<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Flux – ecosystem</title><link>https://deploy-preview-2413--fluxcd.netlify.app/tags/ecosystem/</link><description>Recent content in ecosystem on Flux</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 07 Jul 2025 12:00:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-2413--fluxcd.netlify.app/tags/ecosystem/index.xml" rel="self" type="application/rss+xml"/><item><title>Blog: Time-based deployments with Flux Operator</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/07/time-based-deployments/</link><pubDate>Mon, 07 Jul 2025 12:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/07/time-based-deployments/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/07/time-based-deployments/featured-image_hu4d2f40587f850d3f31bb1c5a3038f0ad_154744_640x0_resize_box_3.png" width="640" height="360"/>
&lt;p>We are thrilled to announce time-based deployments, a feature long-awaited by Flux users, in
&lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator/releases/tag/v0.23.0" target="_blank">Flux Operator v0.23.0&lt;/a>!&lt;/p>
&lt;p>&lt;img src="featured-image.png" alt="">&lt;/p>
&lt;p>Organizations using Flux for GitOps deployments frequently require sophisticated control over when
changes are applied to production systems, particularly in regulated industries or critical business
environments. Key requirements include adhering to Change Advisory Board (CAB) approval windows,
enforcing &amp;ldquo;No Deploy Fridays&amp;rdquo; policies, and restricting deployments during peak business hours to
ensure service stability.&lt;/p>
&lt;p>Maintenance windows become critical when managing helm upgrades, where teams need to skip reconciliation
unless the current time falls within a specified interval. In regulated environments like medical device
companies, automated deployments must be controlled to prevent unexpected disruptions during critical
operational periods. Large telecommunications providers and ISVs managing multiple client clusters need
gating mechanisms to control application rollouts, allowing tenants to consume platform updates when ready.&lt;/p>
&lt;p>In this post, we show how to use time-based deployment with Flux Operator
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesets/introduction/" target="_blank">&lt;code>ResourceSets&lt;/code>&lt;/a>.&lt;/p>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;p>The Flux Operator ResourceSet API allows defining bundles of Flux objects by
templating a set of resources with inputs provided by the ResourceSetInputProvider API.&lt;/p>
&lt;p>The ResourceSetInputProvider API allows pulling inputs from external sources, such as
GitHub pull requests, branches and tags. For example, on the reconciliation of a
ResourceSetInputProvider of type &lt;code>GitHubTag&lt;/code>, the operator will list the tags of
a GitHub repository, filter them according to a semver range, and export a set of
inputs for each matching tag in the ResourceSetInputProvider &lt;code>.status.exportedInputs&lt;/code>
field. For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">status&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">exportedInputs&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">id&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;48955639&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">tag&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;6.0.4&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sha&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>11cf36d83818e64aaa60d523ab6438258ebb6009&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Starting with Flux Operator v0.23.0, the ResourceSetInputProvider API now has the field
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesetinputprovider/#schedule" target="_blank">&lt;code>.spec.schedule&lt;/code>&lt;/a>,
which allows defining a cron-based schedule for the reconciliation of the ResourceSetInputProvider.
For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">schedule&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># Every day-of-week from Monday through Thursday&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># between 10:00 to 16:00&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">cron&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;0 10 * * 1-4&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">timeZone&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;Europe/London&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">window&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;6h&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># Every Friday from 10:00 to 13:00&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">cron&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;0 10 * * 5&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">timeZone&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;Europe/London&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">window&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;3h&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With this configuration, reconciliations of the ResourceSetInputProvider object
would only be allowed to run within the specified time windows. When the window
is active, the reconciliation happens normally, according to the interval defined
in the &lt;code>fluxcd.controlplane.io/reconcileEvery&lt;/code> annotation.&lt;/p>
&lt;h2 id="a-complete-example">A complete example&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Define a ResourceSetInputProvider&lt;/strong>: This provider will scan a Git branch or tag
for changes and export the commit SHA as an input.&lt;/li>
&lt;li>&lt;strong>Configure schedule&lt;/strong>: The provider will have a reconciliation schedule
that defines when it should check for changes in the Git repository.&lt;/li>
&lt;li>&lt;strong>Define a ResourceSet&lt;/strong>: The ResourceSet will use the inputs from the provider
to create a &lt;code>GitRepository&lt;/code> and &lt;code>Kustomization&lt;/code> that deploys the application
at the specified commit SHA.&lt;/li>
&lt;/ul>
&lt;h3 id="resourcesetinputprovider-definition">ResourceSetInputProvider Definition&lt;/h3>
&lt;p>Assuming the Kubernetes deployment manifests for an application are stored in a Git repository,
you can define a input provider that scans a branch for changes
and exports the commit SHA:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>fluxcd.controlplane.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ResourceSetInputProvider&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app-main&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>apps&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">labels&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">app.kubernetes.io/name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">annotations&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">fluxcd.controlplane.io/reconcileEvery&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;10m&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">fluxcd.controlplane.io/reconcileTimeout&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;1m&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">schedule&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">cron&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;0 8 * * 1-5&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">timeZone&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;Europe/London&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">window&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>8h&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitHubBranch&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># or GitLabBranch&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://github.com/my-org/my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">secretRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>gh-app-auth&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">filter&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">includeBranch&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;^main$&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">defaultValues&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">env&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;production&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For when Git tags are used to version the application, you can define an input provider
that scans the Git tags and exports the latest tag according to a semantic versioning:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>fluxcd.controlplane.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ResourceSetInputProvider&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app-release&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>apps&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">labels&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">app.kubernetes.io/name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">annotations&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">fluxcd.controlplane.io/reconcileEvery&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;10m&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">fluxcd.controlplane.io/reconcileTimeout&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;1m&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">schedule&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">cron&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;0 8 * * 1-5&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">timeZone&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;Europe/London&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">window&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>8h&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitHubTag&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># or GitLabTag&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://github.com/my-org/my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">secretRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>gh-auth&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">filter&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">semver&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;&amp;gt;=1.0.0&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">limit&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#40a070">1&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="resourceset-definition">ResourceSet Definition&lt;/h3>
&lt;p>The exported inputs can then be used in a &lt;code>ResourceSet&lt;/code> to deploy the application
using the commit SHA from the input provider:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>fluxcd.controlplane.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ResourceSet&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>apps&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">inputsFrom&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ResourceSetInputProvider&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">selector&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">matchLabels&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">app.kubernetes.io/name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">resources&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>source.toolkit.fluxcd.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&amp;lt;&amp;lt; inputs.provider.namespace &amp;gt;&amp;gt;&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>12h&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://github.com/my-org/my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ref&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">commit&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&amp;lt;&amp;lt; inputs.sha &amp;gt;&amp;gt;&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">secretRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>gh-auth&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sparseCheckout&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- deploy&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kustomize.toolkit.fluxcd.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Kustomization&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&amp;lt;&amp;lt; inputs.provider.namespace &amp;gt;&amp;gt;&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>30m&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">retryInterval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">prune&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">wait&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">timeout&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sourceRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>my-app&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">path&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>deploy/&amp;lt;&amp;lt; inputs.env &amp;gt;&amp;gt;&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When the &lt;code>ResourceSetInputProvider&lt;/code> runs according to its schedule, if it finds a new commit,
the &lt;code>ResourceSet&lt;/code> will be automatically updated with the new commit SHA which will trigger
an application deployment for the new version.&lt;/p>
&lt;h2 id="further-reading">Further reading&lt;/h2>
&lt;ul>
&lt;li>
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesets/time-based-delivery/" target="_blank">Complete Guide&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesets/introduction/" target="_blank">ResourceSets Introduction&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://fluxcd.control-plane.io/operator/resourceset/" target="_blank">ResourceSets Documentation&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesetinputprovider/#schedule" target="_blank">Schedule Documentation&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://fluxcd.control-plane.io/operator/resourcesetinputprovider/#schedule-status" target="_blank">Schedule Status Documentation&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Blog: AI-Assisted GitOps with Flux Operator MCP Server</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/05/ai-assisted-gitops/</link><pubDate>Wed, 14 May 2025 12:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/05/ai-assisted-gitops/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/05/ai-assisted-gitops/featured-image_hu758f39f2897d9b09922a59b22a7c36a6_613874_640x0_resize_box_3.png" width="640" height="360"/>
&lt;p>&lt;img src="featured-image.png" alt="">&lt;/p>
&lt;p>In this blog post, we introduce the Flux MCP Server, a new component of the
&lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator" target="_blank">Flux Operator&lt;/a> project
that connects AI assistants directly to your Kubernetes clusters, enabling seamless interaction
through natural language. It serves as a bridge between AI tools and your GitOps pipelines,
allowing you to analyze the cluster state, troubleshoot deployment issues,
and perform operations using conversational prompts.&lt;/p>
&lt;h2 id="bringing-ai-to-gitops">Bringing AI to GitOps&lt;/h2>
&lt;p>The GitOps movement started with the Flux community back in 2016, and since then,
it has gained immense popularity in the Kubernetes ecosystem as a way to manage
infrastructure and application deployments declaratively. But as the GitOps pipelines
grow in complexity, so does the cognitive load required to troubleshoot issues,
understand resource relationships, and perform routine operations.&lt;/p>
&lt;p>That&amp;rsquo;s where the Flux MCP Server comes in. By connecting AI assistants to Kubernetes clusters
and the desired state in Git, it allows operators to:&lt;/p>
&lt;ul>
&lt;li>Debug GitOps pipelines end-to-end from Flux resources to application logs&lt;/li>
&lt;li>Get accurate root cause analysis for failed deployments&lt;/li>
&lt;li>Compare Flux configurations and Kubernetes resources between clusters&lt;/li>
&lt;li>Visualize Flux dependencies with diagrams generated from the cluster state&lt;/li>
&lt;li>Instruct Flux to perform operations using conversational prompts&lt;/li>
&lt;li>Get up-to-date information and recommendations using the latest Flux official docs&lt;/li>
&lt;/ul>
&lt;h2 id="how-it-works">How It Works&lt;/h2>
&lt;p>The Flux MCP Server implements the Model Context Protocol (MCP),
providing purpose-built tools that allow AI assistants to interact with your clusters.
When you ask a question or make a request, the AI model uses these tools to gather information,
analyze configurations, and even perform operations based on your instructions.&lt;/p>
&lt;p>The AI assistants leveraging the Flux MCP Server can trace issues from high-level GitOps resources
like ResourceSets, HelmReleases, and Kustomizations all the way down to Kubernetes deployments
and pod logs.&lt;/p>
&lt;p>&lt;img src="fluxcd-ai-assisted-gitops.png" alt="AI-Assisted GitOps with Flux">&lt;/p>
&lt;p>In addition, the MCP Server enables the AI to search the Flux documentation
and provide accurate, up-to-date guidance based on the latest features and best practices,
rather than relying solely on its training data.&lt;/p>
&lt;h2 id="getting-started">Getting Started&lt;/h2>
&lt;p>Setting up the Flux MCP Server is straightforward. The server is written in Go and
statically compiled as a single binary with no external dependencies.&lt;/p>
&lt;p>You can install it using Homebrew:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>brew install controlplaneio-fluxcd/tap/flux-operator-mcp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternatively, you can download pre-built binaries for Linux, macOS,
and Windows, for more details refer to the
&lt;a href="https://fluxcd.control-plane.io/mcp/install/" target="_blank">installation guide&lt;/a>.&lt;/p>
&lt;p>Once installed, you can configure your AI assistant to use the Flux MCP Server.
For Claude, Cursor, Windsurf, or GitHub Copilot add the following configuration to the MCP settings:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#062873;font-weight:bold">&amp;#34;flux-operator-mcp&amp;#34;&lt;/span>:{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#062873;font-weight:bold">&amp;#34;command&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;flux-operator-mcp&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#062873;font-weight:bold">&amp;#34;args&amp;#34;&lt;/span>:[&lt;span style="color:#4070a0">&amp;#34;serve&amp;#34;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#062873;font-weight:bold">&amp;#34;env&amp;#34;&lt;/span>:{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#062873;font-weight:bold">&amp;#34;KUBECONFIG&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;/path/to/.kube/config&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Make sure to replace &lt;code>/path/to/.kube/config&lt;/code> with the absolute path to your kubeconfig file.&lt;/p>
&lt;h2 id="setting-up-ai-instructions">Setting Up AI Instructions&lt;/h2>
&lt;p>For the best experience with the Flux MCP Server, it&amp;rsquo;s crucial to provide your AI assistant
with proper instructions on how to interact with Kubernetes clusters and the Flux resources.
These instructions help the AI understand the context and make appropriate tool calls.&lt;/p>
&lt;p>The Flux MCP Server comes with a set of predefined instructions that you can copy from the
&lt;a href="https://raw.githubusercontent.com/controlplaneio-fluxcd/distribution/refs/heads/main/docs/mcp/instructions.md" target="_blank">instructions.md&lt;/a>
file.&lt;/p>
&lt;p>It&amp;rsquo;s recommended to enhance these instructions with information specific to your clusters, such as:&lt;/p>
&lt;ul>
&lt;li>Kubernetes distribution details (EKS, GKE, AKS, etc.)&lt;/li>
&lt;li>Cloud-specific services integrated with your clusters&lt;/li>
&lt;li>Types of applications deployed&lt;/li>
&lt;li>Secret management approaches&lt;/li>
&lt;/ul>
&lt;p>For detailed guidance on how to configure these instructions with different AI assistants,
refer to the
&lt;a href="https://fluxcd.control-plane.io/mcp/prompt-engineering/#ai-instructions" target="_blank">AI Instructions&lt;/a>
section of the documentation.&lt;/p>
&lt;h2 id="practical-applications">Practical Applications&lt;/h2>
&lt;p>Let&amp;rsquo;s look at some practical ways the Flux MCP Server can enhance your GitOps experience:&lt;/p>
&lt;h3 id="1-quick-health-assessment">1. Quick Health Assessment&lt;/h3>
&lt;p>Instead of running multiple kubectl and flux commands to check the status of your GitOps pipeline, you can simply ask:&lt;/p>
&lt;blockquote>
&lt;p>Analyze the Flux installation in my current cluster and report the status of all components and ResourceSets.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="flux-mcp-cluster-state.png" alt="">&lt;/p>
&lt;p>The AI assistant will gather information about your Flux Operator installation, controllers,
and managed resources, providing a comprehensive health assessment.&lt;/p>
&lt;h3 id="2-gitops-pipeline-visualization">2. GitOps Pipeline Visualization&lt;/h3>
&lt;p>Understanding the relationships between various GitOps resources can be challenging. The Flux MCP Server makes it easy:&lt;/p>
&lt;blockquote>
&lt;p>List the Flux Kustomizations and draw a Mermaid diagram for the depends on relationship.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="flux-mcp-diagram.png" alt="">&lt;/p>
&lt;p>The AI will generate a visual representation of your GitOps pipeline, showing the dependency
relationships between Flux Kustomizations and helping you understand the deployment order and potential bottlenecks.&lt;/p>
&lt;h3 id="3-cross-cluster-comparisons">3. Cross-Cluster Comparisons&lt;/h3>
&lt;p>When managing multiple environments, comparing configurations can be tedious. With Flux MCP Server:&lt;/p>
&lt;blockquote>
&lt;p>Compare the podinfo HelmRelease between production and staging clusters.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="flux-mcp-diff.png" alt="">&lt;/p>
&lt;p>The AI will switch contexts, gather the relevant information, and highlight the differences between the two environments.&lt;/p>
&lt;h3 id="3-root-cause-analysis">3. Root Cause Analysis&lt;/h3>
&lt;p>When deployments fail, finding the root cause can involve digging through multiple resources and logs:&lt;/p>
&lt;blockquote>
&lt;p>Perform a root cause analysis of the last failed Helm release in the frontend namespace.&lt;/p>
&lt;/blockquote>
&lt;p>The AI assistant will trace through dependencies, check resource statuses, analyze logs,
and provide a detailed explanation of what went wrong and how to fix it.&lt;/p>
&lt;h3 id="4-gitops-operations">4. GitOps Operations&lt;/h3>
&lt;p>You can even perform GitOps operations directly through natural language:&lt;/p>
&lt;blockquote>
&lt;p>Resume all the suspended Flux resources in the current cluster and verify their status.&lt;/p>
&lt;/blockquote>
&lt;p>The AI will identify suspended resources, resume them, and report on the results.&lt;/p>
&lt;h3 id="5-kubernetes-operations">5. Kubernetes Operations&lt;/h3>
&lt;p>The Flux MCP Server enables complex Kubernetes operations with simple instructions:&lt;/p>
&lt;blockquote>
&lt;p>Create a namespace called test, then copy the podinfo Helm release and its source.
Change the Helm values for ingress to test.podinfo.com&lt;/p>
&lt;/blockquote>
&lt;p>The AI will generate and apply the necessary Kubernetes resources,
handling the details of creating namespaces, cloning Helm releases,
and modifying configuration values - all through a single conversational request.&lt;/p>
&lt;h2 id="security-considerations">Security Considerations&lt;/h2>
&lt;p>As with any tool that interacts with your clusters, security should be a top priority.
The Flux MCP Server includes several security features to ensure safe operations:&lt;/p>
&lt;ul>
&lt;li>Operates with your existing kubeconfig permissions&lt;/li>
&lt;li>Supports service account impersonation for limited access&lt;/li>
&lt;li>Masks sensitive information in Kubernetes Secret values&lt;/li>
&lt;li>Provides a read-only mode for observation without affecting the cluster state&lt;/li>
&lt;/ul>
&lt;p>For more details on security settings, please refer to the
&lt;a href="https://fluxcd.control-plane.io/mcp/config/" target="_blank">configuration guide&lt;/a>.&lt;/p>
&lt;h2 id="the-future-of-ai-assisted-gitops">The Future of AI-Assisted GitOps&lt;/h2>
&lt;p>The Flux MCP Server is currently an experimental feature, and it&amp;rsquo;s being actively developed based
on user feedback and real-world use cases.&lt;/p>
&lt;p>We plan to enhance the server with the following features in future releases:&lt;/p>
&lt;ul>
&lt;li>Integration with Kubernetes metrics-server and other observability tools&lt;/li>
&lt;li>Improved the documentation search capabilities&lt;/li>
&lt;li>More advanced troubleshooting capabilities&lt;/li>
&lt;li>Support for staged rollout/rollback of apps across clusters&lt;/li>
&lt;/ul>
&lt;p>All feedback is welcome, please reach out to us on
&lt;a href="https://github.com/fluxcd/flux2/discussions/5352" target="_blank">GitHub Discussions&lt;/a>.&lt;/p></description></item><item><title>Blog: GitHub App bootstrap with Flux Operator</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/04/flux-operator-github-app-bootstrap/</link><pubDate>Mon, 14 Apr 2025 12:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/04/flux-operator-github-app-bootstrap/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2025/04/flux-operator-github-app-bootstrap/featured-image_hu758f39f2897d9b09922a59b22a7c36a6_607567_640x0_resize_box_3.png" width="640" height="360"/>
&lt;p>&lt;img src="featured-image.png" alt="">&lt;/p>
&lt;p>In this blog post, we will showcase how
&lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator" target="_blank">Flux Operator&lt;/a>
can be used to bootstrap Kubernetes clusters using the GitHub App authentication method
introduced in
&lt;a href="https://fluxcd.io/blog/2025/02/flux-v2.5.0/" target="_blank">Flux 2.5.0&lt;/a>.&lt;/p>
&lt;p>Prior to Flux 2.5.0, the GitHub repository authentication methods were based on using a
secret that is tied to a GitHub user, be it a personal access token (PAT) or an SSH deploy key.
When the user leaves the organization, the GitHub deploy keys are revoked
resulting in Flux losing access to all repositories. To restore access, the cluster
administrators have to generate new GitHub deploy keys tied to a different user
and rotate the secret in all clusters.&lt;/p>
&lt;p>To avoid this situation, the recommendation was for organizations to create a dedicated
GitHub user for Flux, but this is also not ideal since an extra user affects billing.
The login credentials and MFA code have to be stored in an external secret management system
like 1Password, increasing the complexity of the cluster bootstrap process.&lt;/p>
&lt;p>Starting with Flux 2.5.0, the GitHub App authentication method allows organizations to create a GitHub App
with access to the repositories from where Flux syncs the desired state of Kubernetes clusters.
Instead of using the credentials of a GitHub user, Flux running on the clusters will use the GitHub App
private key to authenticate with the GitHub API, acquiring a short-lived access token to perform
Git operations.&lt;/p>
&lt;h2 id="flux-operator">Flux Operator&lt;/h2>
&lt;p>The
&lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator" target="_blank">Flux Operator&lt;/a> offers an alternative
to the Flux CLI bootstrap procedure. It removes the operational burden of managing Flux across fleets
of clusters by fully automating the installation, configuration, and upgrade of the Flux controllers
based on a declarative API called &lt;code>FluxInstance&lt;/code>.&lt;/p>
&lt;p>The
&lt;a href="https://fluxcd.control-plane.io/operator/fluxinstance/" target="_blank">FluxInstance&lt;/a> custom resource defines
the desired state of the Flux components and allows the configuration of the
&lt;a href="https://fluxcd.control-plane.io/operator/flux-sync/" target="_blank">cluster state syncing&lt;/a>
from Git repositories, OCI artifacts and S3-compatible storage.&lt;/p>
&lt;p>When using a GitHub repository as the source of truth, the Flux instance can be configured
to use the GitHub App authentication method by referencing a Kubernetes secret that contains
the app ID, the installation ID and the private key of the GitHub App.&lt;/p>
&lt;p>What follows is a step-by-step guide on how to install the Flux Operator and bootstrap
a cluster using the GitHub App authentication.&lt;/p>
&lt;h3 id="bootstrap-using-flux-operator-and-helm">Bootstrap using Flux Operator and Helm&lt;/h3>
&lt;p>First, install the Flux Operator using the Helm chart:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>helm install flux-operator oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --namespace flux-system &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --create-namespace
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Next, create a GitHub App secret using the &lt;code>flux&lt;/code> CLI (see docs on how to create a GitHub App
&lt;a href="#github-app-docs">here&lt;/a>):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>flux create secret githubapp flux-system &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --app-id&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#40a070">1&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --app-installation-id&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#40a070">2&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --app-private-key&lt;span style="color:#666">=&lt;/span>./path/to/private-key-file.pem
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Finally, bootstrap the cluster by creating a &lt;code>FluxInstance&lt;/code> custom resource in the &lt;code>flux-system&lt;/code> namespace:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>fluxcd.controlplane.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>FluxInstance&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">distribution&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">version&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;2.x&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">registry&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">components&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- source-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- kustomize-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- helm-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- notification-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- image-reflector-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- image-automation-controller&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">cluster&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kubernetes&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">multitenant&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">false&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">networkPolicy&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">domain&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;cluster.local&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sync&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">provider&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>github&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;https://github.com/my-org/my-fleet.git&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ref&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;refs/heads/main&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">path&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;clusters/my-cluster&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">pullSecret&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;flux-system&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When the &lt;code>FluxInstance&lt;/code> is applied on the cluster, the operator will automatically deploy the Flux controllers
and configure them to sync the cluster state from the specified repository using GitHub App authentication.
Similarly to the Flux CLI bootstrap, the operator generates a Flux &lt;code>GitRepository&lt;/code> and &lt;code>Kustomization&lt;/code> named
&lt;code>flux-system&lt;/code> that points to the &lt;code>clusters/my-cluster&lt;/code> path inside the Git repository.&lt;/p>
&lt;p>The Flux instance can be customized in various ways including multi-tenancy lockdown,
sharding, horizontal and vertical scaling, persistent storage, and fine-tuning
the Flux controllers with Kustomize patches.
For more information on the available options, please refer
to the
&lt;a href="https://fluxcd.control-plane.io/operator/flux-config/" target="_blank">Flux Operator documentation&lt;/a>.&lt;/p>
&lt;h3 id="bootstrap-using-flux-operator-and-terraform">Bootstrap using Flux Operator and Terraform&lt;/h3>
&lt;p>Alternatively, you can use Terraform or OpenTofu to install the Flux Operator and
the &lt;code>FluxInstance&lt;/code>. A Terraform example is available in the
&lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator/blob/main/config/terraform/README.md" target="_blank">Flux Operator repository&lt;/a>.&lt;/p>
&lt;p>The command for applying this Terraform example with a GitHub App would be the following:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">GITHUB_APP_PEM&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">`&lt;/span>cat path/to/app.private-key.pem&lt;span style="color:#4070a0">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>terraform apply &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">flux_version&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;2.x&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">flux_registry&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">github_app_id&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;1&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">github_app_installation_id&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;2&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">github_app_pem&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;&lt;/span>&lt;span style="color:#bb60d5">$GITHUB_APP_PEM&lt;/span>&lt;span style="color:#4070a0">&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">git_url&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;https://github.com/my-org/my-fleet.git&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">git_ref&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;refs/heads/main&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> -var &lt;span style="color:#bb60d5">git_path&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;clusters/production&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="github-app-docs">GitHub App Docs&lt;/h3>
&lt;ul>
&lt;li>
&lt;a href="https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app" target="_blank">Registering a GitHub App&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps" target="_blank">Managing private keys for GitHub Apps&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://docs.github.com/en/apps/using-github-apps/installing-your-own-github-app" target="_blank">Installing your GitHub App&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>After installing your GitHub App in your organization you can find the &lt;em>installation ID&lt;/em> like this:&lt;/p>
&lt;ol>
&lt;li>Go to the Organization settings&lt;/li>
&lt;li>Click on &amp;lsquo;GitHub Apps&amp;rsquo; under &amp;lsquo;Third-party Access&amp;rsquo;&lt;/li>
&lt;li>If there are multiple GitHub apps, choose your App and click on &amp;lsquo;Configure&amp;rsquo;&lt;/li>
&lt;li>Once your GitHub App is selected check the URL for obtaining &amp;lsquo;GitHub App Installation ID&amp;rsquo;&lt;/li>
&lt;/ol>
&lt;p>The URL looks like this:&lt;/p>
&lt;pre tabindex="0">&lt;code>https://github.com/organizations/&amp;lt;Organization-name&amp;gt;/settings/installations/&amp;lt;ID&amp;gt;
&lt;/code>&lt;/pre>&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>Using the GitHub App authentication method with Flux Operator offers a more secure
way of bootstrapping Flux on Kubernetes clusters, as it eliminates the need for managing
GitHub user credentials and deploy keys. This approach ensures that Flux can
continue to operate seamlessly even when users leave the organization or change their access
permissions.&lt;/p>
&lt;p>Migrating clusters that have been bootstrapped with the Flux CLI to the Flux Operator
is a straightforward process. For more information on how to do this, please refer to the
&lt;a href="https://fluxcd.control-plane.io/operator/flux-bootstrap-migration/" target="_blank">Flux Operator bootstrap migration guide&lt;/a>.&lt;/p></description></item><item><title>Blog: How to use Weave GitOps as your Flux UI</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/</link><pubDate>Tue, 04 Apr 2023 08:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/wego-featured_hu053769197a9647a871b80b35799f23ef_504003_640x0_resize_box_3.png" width="640" height="440"/>
&lt;p>Here comes the newest blog post in our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/tags/ecosystem/">ecosystem category&lt;/a>.
One of the key reasons to rewrite Flux was to break up the former monolith
solution into separate controllers which provide distinct parts of the
functionality. This allows users to pick just the parts they need, and
integrators to very easily build on top of Flux&amp;rsquo;s APIs. Today we have a very
active
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/ecosystem/">Flux Ecosystem&lt;/a> - we very much welcome this to happen and
see it as an indicator of success.&lt;/p>
&lt;h2 id="an-introduction-to-weave-gitops">An introduction to Weave GitOps&lt;/h2>
&lt;p>Today we would like to talk about
&lt;a href="https://github.com/weaveworks/weave-gitops" target="_blank">Weave
GitOps&lt;/a>. It has
been built out in the open for about a year and brings among other
things one of the most requested additions to Flux: a UI.&lt;/p>
&lt;script src="https://deploy-preview-2413--fluxcd.netlify.app/shortcode-gallery/lazy/jquery.lazy.min.js">&lt;/script>
&lt;script src="https://deploy-preview-2413--fluxcd.netlify.app/shortcode-gallery/swipebox/js/jquery.swipebox.min.js">&lt;/script>
&lt;link rel="stylesheet" href="https://deploy-preview-2413--fluxcd.netlify.app/shortcode-gallery/swipebox/css/swipebox.min.css">
&lt;script src="https://deploy-preview-2413--fluxcd.netlify.app/shortcode-gallery/justified_gallery/jquery.justifiedGallery.min.js">&lt;/script>
&lt;link rel="stylesheet" href="https://deploy-preview-2413--fluxcd.netlify.app/shortcode-gallery/justified_gallery/justifiedGallery.min.css"/>
&lt;style>
&lt;/style>
&lt;div id="gallery-3510214d32a2d8dc5bd033478b965178-0-wrapper" class="gallery-wrapper">
&lt;div id="gallery-3510214d32a2d8dc5bd033478b965178-0" class="justified-gallery">
&lt;div>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/wego2.png"
class="galleryImg"
>
&lt;img
width="600" height="413"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGL6/uMnIAAA//8F2gLrBLOjVQAAAABJRU5ErkJggg=="
class="lazy"
data-src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/wego2_hu053769197a9647a871b80b35799f23ef_612680_600x600_fit_q90_lanczos_3.png"
>
&lt;/a>
&lt;/div>
&lt;div>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/wego-featured.png"
class="galleryImg"
>
&lt;img
width="600" height="413"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAEElEQVR4nGL6&amp;#43;fMXIAAA//8F4wLvmvkWLwAAAABJRU5ErkJggg=="
class="lazy"
data-src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/04/how-to-use-weave-gitops-as-your-flux-ui/wego-featured_hu053769197a9647a871b80b35799f23ef_504003_600x600_fit_q90_lanczos_3.png"
>
&lt;/a>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;script>
if (!jQuery) {
alert("jquery is not loaded");
}
$( document ).ready(() => {
const gallery = $("#gallery-3510214d32a2d8dc5bd033478b965178-0");
let swipeboxInstance = null;
gallery.on('jg.complete', () => {
$(() => {
$('.lazy').Lazy({
visibleOnly: true,
afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
});
});
swipeboxInstance = $('.galleryImg').swipebox(
jQuery.extend({},
{ }
)
);
});
gallery.justifiedGallery({
rowHeight : "150",
margins : "5",
border : 0,
randomize : false ,
waitThumbnailsLoad : false,
lastRow : "justify",
captions : false,
});
});
&lt;/script>
&lt;br>
&lt;p>With Weave GitOps you&lt;/p>
&lt;ul>
&lt;li>manage and view applications all in one place&lt;/li>
&lt;li>easily see your continuous deployments and what is being produced
via GitOps&lt;/li>
&lt;li>sync your latest git commits directly from the UI&lt;/li>
&lt;li>leverage Kubernetes RBAC to control permissions in the dashboard&lt;/li>
&lt;li>quickly see the health of your reconciliation deployment runtime&lt;/li>
&lt;/ul>
&lt;p>The Weave GitOps team works very closely together with the Flux
Community - many engineers on both teams are actually colleagues.&lt;/p>
&lt;p>In addition to the UI Weave GitOps provides a frictionless way
to get up to speed with your GitOps experience:
&lt;a href="https://web.archive.org/web/20230922003942/https://docs.gitops.weave.works/docs/gitops-run/overview/" target="_blank">GitOps
Run&lt;/a>.
All you need to get started is a cluster and the Weave GitOps CLI.
Everything else, including Flux and the Weave GitOps Dashboard will be
set up automatically for you.&lt;/p>
&lt;p>GitOps Run actually does more than the setup. You see changes sync
almost in real time instead of the normal loop, where everything goes
through a PR process, enabling you to iterate very quickly without
sacrificing the GitOps pattern. The moment you are happy with the
changes you create a PR just as usual. It&amp;rsquo;s the best of both worlds.&lt;/p>
&lt;p>Watch this short video to see the beauty and ease of use: set up&lt;/p>
&lt;div class="responsive-video">
&lt;iframe src="https://www.youtube.com/embed/2TJz7RhDtAc" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>If you are a Terraform user, you will love that the terraform-controller
is integrated by default and your terraform resources will show up in
the dashboard as well.&lt;/p>
&lt;h2 id="getting-started">Getting Started&lt;/h2>
&lt;p>Using GitOps Run as shown in the video above is the easiest way to get
set up. Period.&lt;/p>
&lt;p>Here is an example of how to get an app deployment set up using GitOps
(powered by Flux), including the dashboard.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;code>brew install fluxcd/tap/flux&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Head to
&lt;a href="https://github.com/stefanprodan/podinfo" target="_blank">podinfo&lt;/a>
and create a fork with the name &lt;code>podinfo-gitops-run&lt;/code>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Clone locally and change into the directory&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-cli" data-lang="cli">export GITHUB_USER=&amp;lt;your github username&amp;gt;
# you can ignore these two commands if you already created and
# cloned your repository
git clone git@github.com:$GITHUB_USER/podinfo-gitops-run.git
cd podinfo-gitops-run
&lt;/code>&lt;/pre>&lt;/li>
&lt;li>
&lt;p>Now run the &lt;code>gitops&lt;/code> command with &lt;code>--no-session&lt;/code> as it&amp;rsquo;s a single user
cluster which we want to use in direct mode. The port-forward
points at the &lt;code>podinfo&lt;/code> pod we will create later on.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-cli" data-lang="cli">gitops beta run ./podinfo --no-session \
--port-forward namespace=dev,resource=svc/backend,port=9898:9898
&lt;/code>&lt;/pre>&lt;p>The other arguments denote a directory where the manifests are
going to be stored and we set up port-forwarding for the
application we are about to install.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>During the installation process, Flux will be installed if it isn&amp;rsquo;t
and you will now be asked if you want to install the GitOps
&lt;a href="https://web.archive.org/web/20230927114646/https://docs.gitops.weave.works/docs/getting-started/intro/" target="_blank">dashboard&lt;/a>.
Answer &lt;code>yes&lt;/code> and &lt;strong>set a password&lt;/strong>.&lt;/p>
&lt;p>Note: If you do not set a password, you won&amp;rsquo;t be able to login to
the GitOps UI 😱.&lt;/p>
&lt;p>Shortly after you should be able to
&lt;a href="http://localhost:9001" target="_blank">open the
dashboard&lt;/a>. The username is &lt;code>admin&lt;/code> and the
password will be the one you set above.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If you check the contents of the podinfo directory, you will notice
a &lt;code>kustomization.yaml&lt;/code> file. Edit the resources element to list
&lt;code>&amp;quot;../deploy/overlays/dev&amp;quot;&lt;/code> as well. It should like below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kustomize.config.k8s.io/v1beta1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Kustomization&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>dev-podinfo&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">resources&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>[&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;../deploy/overlays/dev&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>]&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>If you save the file, podinfo will be deployed and able to access it at
&lt;a href="http://localhost:9898" target="_blank">http://localhost:9898&lt;/a>.&lt;/p>
&lt;p>There&amp;rsquo;s more: if you Ctrl-C the running &amp;ldquo;gitops&amp;rdquo; process in the
terminal, you will be asked if you want to change the deployment to be
in &amp;ldquo;GitOps mode&amp;rdquo;, this means that the manifests for the cluster
definition and dashboard will be added as well and pushed to GitHub for
you.&lt;/p>
&lt;p>As you can see, Weave GitOps takes care of a lot of the repetitive tasks
and heavy lifting. A beautiful way to get set up and know that Flux is
doing everything behind the scenes for you.&lt;/p>
&lt;h2 id="is-there-more">Is there more?&lt;/h2>
&lt;p>There is an
&lt;a href="https://web.archive.org/web/20231206150400/https://docs.gitops.weave.works/docs/intro-ee/" target="_blank">Enterprise version of Weave
GitOps&lt;/a> as
well, so if you need professional support for everything mentioned
above, you will be covered. In addition to that, you get advanced
features, such as templates and GitOpsSets - these are what will enable
you to create a self-service for application teams.&lt;/p>
&lt;p>The Weave GitOps team is very friendly and are always happy to help and
receive feedback. Just join them in the &lt;code>#weave-gitops&lt;/code> channel on the
&lt;a href="https://weave-community.slack.com/join/shared_invite/zt-yqwtav03-QPo7W4Qoi1pL6W8UQYk2yQ" target="_blank">Weave Users Slack&lt;/a>.&lt;/p>
&lt;h2 id="come-and-talk-to-us">Come and talk to us&lt;/h2>
&lt;p>If you have feedback to this story, let us know on Slack or on social
media and if you have a story to tell yourself, come find us as well -
you can also hit us up on the
&lt;a href="https://github.com/fluxcd/website/" target="_blank">fluxcd.io website
repository&lt;/a>. We want to
report more stories from our ecosystem and Flux success stories. Thanks
in advance for reaching out!&lt;/p></description></item><item><title>Blog: How Flux and Pulumi give each other superpowers</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/02/flux-pulumi-superpowers/</link><pubDate>Tue, 14 Feb 2023 08:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/02/flux-pulumi-superpowers/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/02/flux-pulumi-superpowers/flying-sparkles-purple-cape-featured_hufcb8a54e4f3d1acc465b5cb00164b2c0_21207_640x0_resize_box_3.png" width="640" height="349"/>
&lt;p>
&lt;a href="https://pulumi.com/" target="_blank">Pulumi&lt;/a> is an &amp;ldquo;Infrastructure as Code&amp;rdquo; tool that lets you specify your
infrastructure as programs written in JavaScript, Python, Java, Go, .NET languages, or YAML. The
&lt;a href="https://github.com/pulumi/pulumi-kubernetes-operator" target="_blank">Pulumi Kubernetes operator&lt;/a> drives Pulumi
from Kubernetes, so you can maintain your infrastructure by pushing commits to git and letting
automation take it from there.&lt;/p>
&lt;img class="img-fluid float-left m-3" alt="Pulumi mascot with sparkling cape" src="flying-sparkles-purple-cape-featured.png" />
&lt;p>Recently, we added support to the operator for
&lt;a href="https://www.pulumi.com/docs/guides/continuous-delivery/pulumi-kubernetes-operator/#using-a-flux-source" target="_blank">using Flux
sources&lt;/a>. This
is a great addition to the operator, but it&amp;rsquo;s not the only way Flux and Pulumi can work together.&lt;/p>
&lt;p>Below I&amp;rsquo;m going to talk about how Flux and Pulumi can be combined, and the superpowers each grants
to the other.&lt;/p>
&lt;h2 style="clear:left;">Adding OCI support and supply chain security to Pulumi&lt;/h2>
&lt;p>The support for Flux sources in the Pulumi operator gives you more ways to make your Pulumi programs
available to the operator. Notably, you can now package your program as an OCI image and push it to
an image registry, before using it with the operator. This might be appealing if you have deployment
pipelines to generate Kubernetes YAML (e.g., from
&lt;a href="https://cuelang.org/" target="_blank">Cue&lt;/a>) or other data, before
using it in a program. It&amp;rsquo;s also convenient when you&amp;rsquo;re on a platform like AWS, GCP or Azure,
because these have OCI registries with useful operational features like caching, security scanning,
and so on.&lt;/p>
&lt;p>But I think an even better reason for using Flux is that it can verify your sources. If you use a
Flux source in a Pulumi stack, you can better secure your supply chain. When you&amp;rsquo;re using an OCI
repository source for example,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/ocirepositories/#verification">Flux will check Cosign
signatures&lt;/a> on each image
for you, and refuse to update a source that does not have a valid signature.&lt;/p>
&lt;!-- ASCII art here? Or a YAML example. -->
&lt;p>A more subtle security benefit of Flux sources is context-based authorization. For example, in AWS
the Flux controller can take advantage of
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/cheatsheets/oci-artifacts/#contextual-authorization">workload
identity&lt;/a> to gain access
to an ECR container registry containing your sources, so that you don&amp;rsquo;t have to explicitly manage
credentials.&lt;/p>
&lt;h2 id="using-pulumi-to-extend-the-reach-of-flux">Using Pulumi to extend the reach of Flux&lt;/h2>
&lt;p>With Pulumi you are not restricted to Kubernetes resources &amp;ndash; you can create any resource defined in
a provider, e.g., within AWS, GCP, and Azure, among
&lt;a href="https://pulumi.com/registry/" target="_blank">many such platforms and
services&lt;/a>. You can
&lt;a href="https://www.pulumi.com/docs/intro/languages/yaml/" target="_blank">write a Pulumi program in
YAML&lt;/a>, and you can
&lt;a href="https://www.pulumi.com/docs/guides/continuous-delivery/pulumi-kubernetes-operator/#using-a-program-object" target="_blank">declare a YAML program as a
Kubernetes custom
resource&lt;/a>,
making the whole chain amenable to
&lt;a href="https://github.com/kubernetes/design-proposals-archive/blob/main/architecture/resource-management.md" target="_blank">Kubernetes Resource Model
(KRM)&lt;/a>-oriented
tooling, including Flux.&lt;/p>
&lt;p>For example, here&amp;rsquo;s Kubernetes YAMLs for creating an AWS EC2 instance, and a security group, with
Pulumi:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># This is a program for creating the EC2 instance and security group&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>pulumi.com/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Program&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ec2-instance&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">program&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">resources&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">group&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>aws:ec2:SecurityGroup&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">properties&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">description&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Enable HTTP access&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ingress&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">protocol&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>tcp&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">fromPort&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#40a070">80&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">toPort&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#40a070">80&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">cidrBlocks&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>[&lt;span style="color:#4070a0">&amp;#34;0.0.0.0/0&amp;#34;&lt;/span>]&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">server&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>aws:ec2:Instance&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">properties&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ami&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ami-6869aa05&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">instanceType&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>t2.micro&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">vpcSecurityGroupIds&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>${group.name}&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">outputs&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">publicIp&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>${server.publicIp}&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">publicDns&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>${server.publicDns}&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># This stack tells the operator how to run the program&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>pulumi.com/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Stack&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>dev-ec2-instance&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">stack&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>squaremo/ec2-instance/dev&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">programRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ec2-instance&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">destroyOnFinalize&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">config&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">aws:region&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>us-east-1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can commit these in files in git, and have them synced by Flux. Then the Pulumi operator will
take over, create the infrastructure as it&amp;rsquo;s declared, and mark the Stack object as ready. As far as
Flux knows, these are just regular Kubernetes resources &amp;ndash; but now you can bring your whole
infrastructure under control!&lt;/p>
&lt;h2 id="using-flux-to-simplify-kubernetes-for-pulumi">Using Flux to simplify Kubernetes for Pulumi&lt;/h2>
&lt;p>Pulumi makes a huge variety of infrastructure accessible by
&lt;a href="https://www.pulumi.com/what-is/what-is-infrastructure-as-code/" target="_blank">&lt;em>just writing
programs&lt;/em>&lt;/a>. In the specific context
of Kubernetes, many folks will find KRM-oriented tooling and YAML files easier. Flux&amp;rsquo;s Kustomize and
Helm controllers work alongside its source controller, but happily they also work in harmony with
the Pulumi operator, and you can mix and match to suit yourself.&lt;/p>
&lt;p>For example, you might find it useful to write all your Pulumi Program and Stack YAMLs as files in a
directory for Flux to sync, rather than trying to create them in Pulumi code (or &amp;ndash; horror &amp;ndash;
applying them by hand).&lt;/p>
&lt;h2 id="getting-started-with-flux-and-the-pulumi-operator">Getting started with Flux and the Pulumi operator&lt;/h2>
&lt;p>If you are already invested in Pulumi, it would make sense to bootstrap &lt;strong>Flux, using Pulumi&lt;/strong>. You
can use the
&lt;a href="https://www.pulumi.com/registry/packages/flux/" target="_blank">Flux provider for Pulumi&lt;/a> from your
Pulumi program, and gain verified sources and effortless YAML syncing.&lt;/p>
&lt;p>And, vice versa &amp;ndash; if you are starting with Flux and want to expand its reach with Pulumi, you can
bootstrap the &lt;strong>Pulumi operator, using Flux&lt;/strong>, by syncing the deployment manifests in the operator&amp;rsquo;s
GitHub repo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>source.toolkit.fluxcd.io/v1beta2&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>pulumi-operator&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m0s&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ref&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">semver&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;1.11.x&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://github.com/pulumi/pulumi-kubernetes-operator&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kustomize.toolkit.fluxcd.io/v1beta2&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Kustomization&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>deploy-pulumi-operator&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m0s&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">path&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>./deploy/yaml&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">prune&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sourceRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>pulumi-operator&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Visit
&lt;a href="https://www.pulumi.com/docs/get-started/" target="_blank">Pulumi&amp;rsquo;s &amp;ldquo;Get Started&amp;rdquo; portal&lt;/a> to learn more about
what you can accomplish with Pulumi.&lt;/p></description></item><item><title>Blog: GitOps Without Leaving your IDE</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/</link><pubDate>Wed, 28 Sep 2022 11:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/vscode-gitops-commands-featured_hud8bc9c45cad569062b2b353a7572261b_306010_640x0_resize_box_3.png" width="640" height="360"/>
&lt;p>Welcome to the second
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/tags/ecosystem/">blog post in our Flux Ecosystem category&lt;/a>!
This time we are talking about one of the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/ecosystem/#flux-uis--guis">Flux UIs&lt;/a>: it&amp;rsquo;s
the
&lt;a href="https://github.com/weaveworks/vscode-gitops-tools" target="_blank">VS Code GitOps Extension&lt;/a>.&lt;/p>
&lt;p>If you already use VS Code, this extension will be straight up your alley: it
provides an intuitive way to manage, troubleshoot and operate your Kubernetes
environment following the GitOps operating model, accelerating your development
lifecycle and simplifying your continuous delivery pipelines. Of course it uses
Flux under the hood.&lt;/p>
&lt;h2 id="getting-started">Getting Started&lt;/h2>
&lt;p>Installing it: It&amp;rsquo;s
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Weaveworks.vscode-gitops-tools" target="_blank">in the Visual Studio Code
Marketplace&lt;/a>, so if you search for it in VS Code, it&amp;rsquo;s just a click of
the Install button away.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 810px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/vscode-gitops-features_huc42989800101be5ffa42886711045c56_143771_800x0_resize_box_3.png" width="800" height="1065">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>Additionally, you will need to&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://kubectl.docs.kubernetes.io/installation/kubectl/" target="_blank">Install Kubectl&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/installation/#install-the-flux-cli">Install Flux CLI&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://git-scm.com/downloads" target="_blank">Install git&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Optionally, if available, the extension will make use of the &lt;code>az&lt;/code> tool
(for Azure clusters) and &lt;code>docker&lt;/code> as well.&lt;/p>
&lt;p>With that out of the way, let&amp;rsquo;s get going and take the extension for a
spin.&lt;/p>
&lt;h2 id="drive-everything-from-your-ide">Drive everything from your IDE&lt;/h2>
&lt;p>Once you launch VS Code, you should see available clusters listed in the
Clusters section of the GitOps extension. Now you can easily interact
with the resources in each of the clusters. This makes it very
straightforward to make changes in your manifests, commit and observe
changes in the clusters without leaving your IDE.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 810px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/vscode-gitops-commands-featured_hud8bc9c45cad569062b2b353a7572261b_306010_800x0_resize_box_3.png" width="800" height="450">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 810px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/vscode-gitops-tools_hu600760dc3592d5cf40750027ba68a58a_234068_800x0_resize_box_3.png" width="800" height="450">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>The extension was designed so that you always have access to the
immediate tasks and events. Turning a manifest into a &lt;code>Kustomization&lt;/code> or
&lt;code>Source&lt;/code>? Right-click on the YAML file. View repositories, clusters,
sources, kustomizations, etc. - you see them at the first glance. View
GitOps Output panel with CLI command traces for diagnostics, cluster and
components versions, Flux controller logs, everything you might need to
debug. Enable/disable GitOps cluster operations with just a click.
Reconcile Sources and Workloads demand, and much more - links to
most-needed docs included.&lt;/p>
&lt;h2 id="constantly-evolving">Constantly evolving&lt;/h2>
&lt;p>The extension is rapidly growing new features. In 0.21.0, the team added
OCI support which is supported natively in Flux. If you would like to
see a video demo of this, check out this talk done by Annie Talvasto and
Kingdon Barrett in the CNCF Webinar series.&lt;/p>
&lt;div class="responsive-video">
&lt;iframe src="https://www.youtube.com/embed/Hz8IP_eprec" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>In 0.22.0 basic support for Azure AKS/Arc was added. Future releases
will add a new beginner-friendly UI workflow for creating complete Flux
configurations using both generic Flux Source (Git, OCI, Bucket,
&lt;code>HelmRepository&lt;/code>) and Workload (&lt;code>Kustomization&lt;/code>, &lt;code>HelmRelease&lt;/code>) resources
as well as Azure &lt;code>FluxConfig&lt;/code> resources.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 810px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/gitops-without-leaving-your-ide/azure-support_hu406742798f89d858567e5883bc0c4978_117756_800x0_resize_box_3.png" width="800" height="200">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>The team has begun work to transition the extension implementation from
shell out commands to Javascript APIs for Kubernetes and Azure. Once
that is complete, extension responsiveness and performance will improve
dramatically.&lt;/p>
&lt;h2 id="join-the-community">Join the community&lt;/h2>
&lt;p>The team behind the extension loves feedback. If you like what you see,
please star
&lt;a href="https://github.com/weaveworks/vscode-gitops-tools" target="_blank">the extension on
GitHub&lt;/a>
or leave an issue if something is missing, or send a PR if you can.&lt;/p>
&lt;p>All feedback is very welcome!&lt;/p></description></item><item><title>Blog: How to GitOps Your Terraform</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/how-to-gitops-your-terraform/</link><pubDate>Wed, 14 Sep 2022 11:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/how-to-gitops-your-terraform/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/how-to-gitops-your-terraform/tf-controller2-featured_hu4780872c53a7fcf48bdaf1dc3836ae60_2295744_640x0_resize_box_3.png" width="640" height="360"/>
&lt;p>This is the first blog post in a series where we want to shine a light
on projects in the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/ecosystem/">Flux Ecosystem&lt;/a>. This time it&amp;rsquo;s
going to be the
&lt;a href="https://github.com/weaveworks/tf-controller" target="_blank">Terraform
Controller&lt;/a>.&lt;/p>
&lt;p>If you use Terraform, you might think of it as &amp;ldquo;Infrastructure as Code&amp;rdquo;
and to be separate from the concept of GitOps. Quite often we have seen
debates about &amp;ldquo;Infrastructure as Code vs. GitOps&amp;rdquo;. The Terraform
Controller reconciles these two worlds and lets you take advantage of
the benefits of GitOps for existing Terraform resources: one source of
truth, one single pane of glass and drift detection among them.&lt;/p>
&lt;p>You might have resorted to using pipelines or manual deployments up
until now. In this blog post we are going to show how to have your
Terraform resources managed the GitOps way. Without having to convert
your code at all!&lt;/p>
&lt;h2 id="what-is-the-terraform-controller">What is the Terraform Controller?&lt;/h2>
&lt;p>The
&lt;a href="https://weaveworks.github.io/tf-controller/" target="_blank">Terraform Controller&lt;/a>
is a
&lt;a href="https://fluxcd.io" target="_blank">Flux&lt;/a> controller that can manage your
Terraform resources. Although Flux runs on Kubernetes, whatever you are
using Terraform for, the Flux controller can manage it. It has several
features including the ability to do manual approvals or auto-approve
Terraform plans, and the Terraform outputs can be set as a Kubernetes
secret. It is also integrated with Terraform Cloud and Terraform
Enterprise.&lt;/p>
&lt;p>The benefits of using the Terraform Controller is that you are able to
take advantage of GitOps for existing Terraform resources. There is
drift detection of Terraform resources and it can be used as a glue for
Terraform resources and Kubernetes workloads.&lt;/p>
&lt;p>Terraform Controller is very versatile because it offers different modes
of operation and many features which give you the integration points and
control you need. Primarily it supports these use-cases:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>GitOps Automation Model:&lt;/strong> Here you GitOps your Terraform
resources from the provision steps to the enforcement steps, like
for example a whole EKS cluster.&lt;/li>
&lt;li>&lt;strong>Hybrid GitOps Automation Model:&lt;/strong> Here you GitOps parts of your
existing infrastructure resources. For example, you have an
existing EKS cluster. You can choose to GitOps only its nodegroup,
or its security group.&lt;/li>
&lt;/ul>
&lt;p>Building on this, you can make use of these features if you have a
&lt;code>TFSTATE&lt;/code> file:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>State Enforcement:&lt;/strong> Use GitOps to enforce it, without changing
anything else.&lt;/li>
&lt;li>&lt;strong>Drift Detection:&lt;/strong> Use GitOps just for drift detection, so you can
decide to do things later when a drift occurs.&lt;/li>
&lt;/ul>
&lt;p>And
&lt;a href="https://weaveworks.github.io/tf-controller/#features" target="_blank">there&amp;rsquo;s more&lt;/a>:
Multi-Tenancy, Plan and Manual Approve and more features on
&lt;a href="https://github.com/weaveworks/tf-controller#roadmap" target="_blank">the
roadmap&lt;/a>.&lt;/p>
&lt;p>Now let&amp;rsquo;s move on to how to integrate it practically!&lt;/p>
&lt;h2 id="gitopsing-your-terraform">GitOpsing your Terraform&lt;/h2>
&lt;h3 id="prerequisites">Prerequisites&lt;/h3>
&lt;p>Obviously you will need a Kubernetes cluster and Flux installed.
Terraform Controller will require at least Flux 0.32, which in turn
needs at least Kubernetes version 1.20.6. Either use flux install or
flux bootstrap as explained in
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/get-started/">the Flux documentation&lt;/a>.&lt;/p>
&lt;h3 id="installation">Installation&lt;/h3>
&lt;p>Now you need to install Terraform Controller. There are many ways to do it,
check out the
&lt;a href="https://weaveworks.github.io/tf-controller/getting_started/#installation" target="_blank">installation
docs&lt;/a>
for more information.&lt;/p>
&lt;p>One very easy way to do it is to add this
&lt;a href="https://raw.githubusercontent.com/weaveworks/tf-controller/main/docs/release.yaml" target="_blank">&lt;code>HelmRelease&lt;/code>&lt;/a>
to your bootstrap repository.&lt;/p>
&lt;h3 id="tying-in-your-terraform-resources">Tying in your Terraform resources&lt;/h3>
&lt;p>And here is where all the beauty of Terraform Controller comes in - it
does all the hard work for you. All you will need to do to is&lt;/p>
&lt;ol>
&lt;li>Define the source of your Terraform resources&lt;/li>
&lt;li>Enable GitOps Automation&lt;/li>
&lt;/ol>
&lt;h4 id="define-source">Define source&lt;/h4>
&lt;p>So let&amp;rsquo;s go ahead, here we define a Source controller&amp;rsquo;s source (you can
pick any of &lt;code>GitRepository&lt;/code>, &lt;code>Bucket&lt;/code>, &lt;code>OCIRepository&lt;/code>). A &lt;code>GitRepository&lt;/code>
entry could look like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>source.toolkit.fluxcd.io/v1beta1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>helloworld&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>30s&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://github.com/tf-controller/helloworld&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">ref&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">branch&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>main&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="the-gitops-automation-mode">The GitOps Automation mode&lt;/h4>
&lt;p>The GitOps automation mode could be enabled by setting
&lt;code>.spec.approvePlan=auto&lt;/code>. In this mode, Terraform resources will be
planned, and automatically applied for you. Here is a simple example you
can just copy and paste.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>infra.contrib.fluxcd.io/v1alpha1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Terraform&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>helloworld&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>1m&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">approvePlan&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;auto&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">path&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>./&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">sourceRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>helloworld&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>flux-system&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note: If you have a &lt;code>kustomization.yaml&lt;/code> file (which is the case in the
basic flux bootstrap use-case), make sure you add the file(s) the above
manifest portions are in into the resources list.&lt;/p>
&lt;p>Once you commit this to Git, you should see Terraform Controller pick
this up quickly. One way to confirm is:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-cli" data-lang="cli">kubectl -n flux-system get terraforms.infra.contrib.fluxcd.io
NAME READY STATUS AGE
helloworld True No drift:
main/d9c5cc348e555526ea563fb82fc901e37de4d732 1m
&lt;/code>&lt;/pre>&lt;p>Simple, wasn&amp;rsquo;t it?&lt;/p>
&lt;h2 id="what-else-is-there">What else is there?&lt;/h2>
&lt;p>The Terraform Controller team has been hard at work and made sure that
many of the common
&lt;a href="https://weaveworks.github.io/tf-controller/use_cases/" target="_blank">use-cases are
supported&lt;/a>.
Above we covered the automation mode, some teams might want more
control, so there&amp;rsquo;s a &amp;ldquo;plan and manual apply&amp;rdquo; mode as well. You can
configure it as well to just do &amp;ldquo;drift detection only&amp;rdquo;.&lt;/p>
&lt;p>And there&amp;rsquo;s more, you can disable drift detection, use it with AWS EKS
IRSA, interact with Terraform (set variables, manage terraform state),
there&amp;rsquo;s health checks and lots of other flexibility. OCI fans will love
to hear that it supports OCI Artifacts as Source as well.&lt;/p>
&lt;p>It is also
&lt;a href="https://weaveworks.github.io/tf-controller/tfe_integration/" target="_blank">integrated with Terraform Cloud and Terraform
Enterprise&lt;/a>.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 610px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/how-to-gitops-your-terraform/tf-controller1_hu6cdbe679a8ab337f70738f9b44aca5c1_411818_600x0_resize_box_3.png" width="600" height="466">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>In past weeks the performance of the Terraform Controller has been
improved significantly as well. Now the controller is greatly scalable
to reconcile and provision a high volume of Terraform modules
concurrently. The team has recently tested the controller with 1,500
Terraform modules.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 610px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/09/how-to-gitops-your-terraform/tf-controller2-featured_hu4780872c53a7fcf48bdaf1dc3836ae60_2295744_600x0_resize_box_3.png" width="600" height="337">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>In the most recent release (v0.12.0) new features are: custom backend
support, interoperability with Flux&amp;rsquo;s Notification Controller, and
supporting human-readable plan output in &lt;code>ConfigMap&lt;/code>.&lt;/p>
&lt;p>And there&amp;rsquo;s more to come, check out
&lt;a href="https://github.com/weaveworks/tf-controller#roadmap" target="_blank">the team&amp;rsquo;s
roadmap&lt;/a>.
While you are checking it out, please give feedback as well. If you are
missing something, if you like it, if you want to contribute - the team
is eager to hear from you.&lt;/p>
&lt;h2 id="want-to-learn-more">Want to learn more?&lt;/h2>
&lt;p>Priyanka &amp;ldquo;Pinky&amp;rdquo; Ravi, Developer Experience Engineer at Weaveworks gave
a great introduction to the Terraform Controller a couple of weeks ago.
Take a look to dive into some of the finer details of this!&lt;/p>
&lt;div class="responsive-video">
&lt;iframe src="https://www.youtube.com/embed/8xhEPPA6XUs" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>You are lucky, there is more to come! Pinky will give an on-demand
webinar as part of the CNCF series. You can
&lt;a href="https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-on-demand-webinar-how-to-gitops-your-terraform/" target="_blank">sign up for it
here&lt;/a>.
It will become available on Sep 29th, 2022.&lt;/p>
&lt;blockquote>
&lt;p>Title: How to GitOps your Terraform!&lt;/p>
&lt;p>Presenter: Priyanka &amp;ldquo;Pinky&amp;rdquo; Ravi&lt;/p>
&lt;p>Link:
&lt;a href="https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-on-demand-webinar-how-to-gitops-your-terraform/" target="_blank">Registration
here&lt;/a>.&lt;/p>
&lt;/blockquote></description></item></channel></rss>