<p>I have a repository with a Kubernetes deployment YAML. Pipelines run on each commit that builds and pushes an image into our repository, versioned with the commit (eg. <code>my_project:bm4a83</code>). Then I'm updating the deployment image</p>

<p><code>kubectl set image deployment/my_deployment my_deployment=my_project:bm4a83</code>.</p>

<p>This works, but I also want to keep the rest of the deployment YAML specification in version control.</p>

<p>I thought I could just keep it in the same repository, but that means my changes that may only be infrastructure (eg, changing <code>replicas</code>) triggers new builds, without code changes.</p>

<p>What felt like it made the most sense was keeping the deployment YAML in a totally separate repository. I figured I can manage all the values from there, independently from actual code changes. The only problem with that is the <code>image</code> key would need to be kept up to date. The only way around that, is working with some floating <code>:latest</code>-type version, but I don't really think that's ideal.</p>

<p>What's a sensible workflow for managing this? Am I missing something entirely?</p>

Richard Taylor
<blockquote>
  <p>What's a sensible workflow for managing this? Am I missing something entirely?</p>
</blockquote>

<p>Some of the answer depends on the kind of risk you're trying to drive down with any process you have in place. If it's "the cluster was wiped out by a hurricane and I need to recover my descriptors," then <a href="https://github.com/heptio/ark#readme" rel="nofollow noreferrer">Heptio Ark</a> is a good solution for that. If the risks are more "human-centric," then IMHO you will have to walk a very careful line between locking down all the things and crippling the very agile, empowering, tools that kubernetes provides to a team. A concrete example of that model running up against your model is: what happens when a developer edits a Deployment but does not (remember|know) to update the descriptor in the repo? So do you revoke the edit rights? Use some diff-esque logic to detect a changed in-cluster config?</p>

<p>To speak to something you said <em>specifically</em>: it is a highly suboptimal idea to commit a descriptor change just to resize a <code>(Deployment|ReplicationController|StatefulSet)</code>. Separately, a well-built CI pipeline would also understand if no <em>buildable</em> artifact changed and bail out (either early, or not even triggering a build, if the CI tool is that smart).</p>

<p>Finally, if you do want to carry on with the current situation, then the best practice I can think of is textual replacement right before applying a descriptor:</p>

<pre><code>$ grep "image: " the-deployment.yml
    image: example.com/something:#CI_PIPELINE_IID#
$ sed -i'' -e "s/#CI_PIPELINE_IID#/${CI_PIPELINE_IID}/" the-deployment.yml
$ kubectl apply -f the-deployment.yml
</code></pre>

<p>so that the copy in the repo remains textually pristine, and also isn't inadvertently <em>actually applied</em> since it won't actually result in a runnable Deployment.</p>
