<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Focused Systems</title><link>https://focused-systems.pages.dev/</link><description>Exploring modern cloud workflows. DevOps, APIs, Git, serverless architectures, pipelines, and software integrations, alongside personal tech solutions.</description><language>en</language><generator>Hugo</generator><image><url>https://focused-systems.pages.dev/images/social.png</url><title>Focused Systems</title><link>https://focused-systems.pages.dev/</link></image><lastBuildDate>Thu, 12 Jun 2025 17:31:28 +0000</lastBuildDate><atom:link href="https://focused-systems.pages.dev/tags/ci/cd/index.xml" rel="self" type="application/rss+xml"/><item><title>Modern Munki DevOps</title><link>https://focused-systems.pages.dev/munki-devops/</link><guid isPermaLink="true">https://focused-systems.pages.dev/munki-devops/</guid><pubDate>Thu, 12 Jun 2025 17:31:28 +0000</pubDate><dc:creator>Rod Christiansen</dc:creator><category>devops</category><category>git</category><category>ci/cd</category><category>munki</category><category>azure</category><category>macadmin</category><description>How we transformed our Munki workflow into a DevOps-native system using Git, CI/CD pipelines, and Azure. Companion post to my MacDevOps YVR 2025 talk.</description><content:encoded><![CDATA[<blockquote><strong>MacDevOps YVR 2025 Companion Post</strong></blockquote><p>A year ago, we were managing Macs the way most orgs still do: one shared Mac, VNC&#x2019;d into, running a local copy of Munki with no real version control or workflow isolation. Git was an afterthought. Deployments were manual. It worked&#x2014;until it didn&#x2019;t scale.</p><p>We&#x2019;ve since inverted the model. Git is the gate. CI is the deployer. Each admin works from their own machine. And the Munki repo is fully DevOps-native.</p><p>Here&#x2019;s how we rebuilt everything using Git, Azure DevOps, Service Bus, pipelines, local caching servers, and inventory automation&#x2014;all open source and cloud-integrated.</p><div class="kg-card kg-file-card"><a class="kg-file-card-container" href="https://blog.focused.systems/content/files/2025/06/MunkiDevOps-1.pdf" title="Download" download><div class="kg-file-card-contents"><div class="kg-file-card-title">MunkiDevOps Presentation Slides</div><div class="kg-file-card-caption"></div><div class="kg-file-card-metadata"><div class="kg-file-card-filename">MunkiDevOps.pdf</div><div class="kg-file-card-filesize">89 MB</div></div></div><div class="kg-file-card-icon"><svg viewbox="0 0 24 24"><defs><style>.a{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}</style></defs><title>download-circle</title><polyline class="a" points="8.25 14.25 12 18 15.75 14.25"/><line class="a" x1="12" y1="6.75" x2="12" y2="18"/><circle class="a" cx="12" cy="12" r="11.25"/></svg></div></a></div><h2 id="from-manual-to-devops">From Manual to DevOps</h2><p>The legacy flow was:</p><ul><li>GitLab running on-prem</li><li>One shared Mac as the deploy point</li><li>One central repo, updated by many hands</li><li>No pipeline. No hooks. No approval gates.</li><li>Everyone stepped on everyone&#x2019;s toes</li></ul><p>Now we have:</p><ul><li>Azure DevOps Git repos and pipelines</li><li>Git hooks that upload/download packages automatically</li><li>Separate working copies per admin</li><li>Local caching servers that sync intelligently</li><li>A full CI/CD system that integrates with inventory and deploys via pull requests</li></ul><h2 id="architecture-overview">Architecture Overview</h2><p>We&#x2019;ve split this into two core flows:</p><h3 id="munki-devops-infrastructure">Munki DevOps Infrastructure</h3><ul><li>Admins commit to a shared Azure DevOps repo with <code>manifests/</code> and <code>pkgsinfo/</code></li><li>Git hooks (post-commit/merge) run <code>azcopy sync</code> to upload or download packages</li><li>A pipeline (<code>munki-push-production.yml</code>) builds catalogs and updates Azure Storage</li><li>Local caching servers (like PLUTO and PROTEUS) are notified via Azure Service Bus</li><li>A daemon listens for commits and runs <code>git pull</code> and syncs assets</li><li>CDN serves files globally or from on-prem caches</li><li>It&#x2019;s fast, redundant, and observable</li></ul><h3 id="inventory-orchestrated-enrollment">Inventory-Orchestrated Enrollment</h3><ul><li>A polling script checks Snipe-IT for inventory changes and builds new CSVs</li><li>CSVs are committed to Git &#x2192; triggers DevOps pipelines &#x2192; runs <code>enrollment-munki</code>, <code>enrollment-intune</code>, <code>enrollment-sharepoint</code>, and more</li><li>Each system (Munki, Intune, Fleet, TDX, Papercut) gets updated data</li><li>Pull requests are the approval gate</li><li>Everything is traceable, auditable, and CI-driven</li></ul><h2 id="resources">Resources</h2><ul><li><strong>Presentation Repo</strong>: <a href="https://github.com/rodchristiansen/munki-devops">github.com/rodchristiansen/munki-devops</a></li></ul><p>Want to talk shop or ask questions? Connect with me on <a href="https://bsky.app/profile/rodchristiansen.net">BlueSky</a> or on the <a href="https://github.com/rodchristiansen">GitHub</a>.</p>
]]></content:encoded></item><item><title>Welcome to Focused Systems</title><link>https://focused-systems.pages.dev/welcome/</link><guid isPermaLink="true">https://focused-systems.pages.dev/welcome/</guid><pubDate>Sun, 11 May 2025 06:36:35 +0000</pubDate><dc:creator>Rod Christiansen</dc:creator><category>devops</category><category>Endpoint Management</category><category>ci/cd</category><category>macos</category><category>Windows</category><description>Exploring modern cloud workflows</description><content:encoded><![CDATA[<p>I&#x2019;ve been managing Macs since before MDM mattered&#x2014;when deployment meant NetBoot imaging, and local software deployment repos with a couple of on-prem Mac minis, login hooks, and ad-hoc ARD commands fired off through a GUI.</p><p>It worked&#x2014;until it didn&apos;t.</p><p>We moved from running local scripts on a shared Mac to each admin working from their own local repo, committing changes through Git, syncing packages with <code>az</code> git hooks. We used to push changes first, then capture them in Git after the fact. Now, Git is the gate. Commits and PRs drive the entire process. Pipelines run automatically, and the cloud becomes the source of truth. Our local caching servers listen for updates&#x2014;pulling down only when there are changes&#x2014;fully inverting the workflow into something distributed, reliable, and scalable. All of it version-controlled. All of it traceable. All of it running on infrastructure provisioned with Terraform.</p><p>Every config, every profile, every software assignment that matters tracked in Git. It&#x2019;s CI/CD deployed, reproducible by design, and logged automatically for traceability.</p><h2 id="what-this-blog-is-about">What This Blog Is About</h2><p>This blog is about the journey&#x2014;the migrations, the patterns that emerged, the decisions that held up, and the ones that didn&#x2019;t. And about the new tools and ideas I&apos;ll be building and using along the way.</p><p>If you work in endpoint management with DevOps, you&#x2019;ll find deep dives into:</p><ul><li>CI/CD pipelines that manage device tools, states, and configuration</li><li>Every cloud resource under Infrastructure as Code with Terraform</li><li>Inventory systems that drive deployment logic</li><li>And Git at the center of it all</li></ul><p>As I now manage both macOS and Windows endpoints, I&#x2019;ll be writing about how I&apos;m creating a cohesive, mirrored management system&#x2014;where both platforms are driven by open source tools, DevOps, and Git, and where admins speak the same language on both sides.</p><p><strong>Focused Systems. Grounded in what actually works and scales. Very opinionated.</strong></p><p>Let&#x2019;s get to it.</p>
]]></content:encoded></item></channel></rss>