<p>I have the following setup:</p>
<ul>
<li>A GitLab repository containing a simple Flask-based web service</li>
<li>A locally deployed private K8s cluster with a configured GitLab agent and a group runner that the previously mentioned repository is using</li>
<li>A GitLab CICD pipeline that creates a custom image with the service inside (port exposed using the <code>Dockerfile</code>), pushes it to the private registry and deploys it to the K8s cluster using Helm</li>
</ul>
<p>The Helm configuration includes two things - a <code>deployment.yaml</code> (for the actual deployment) and a <code>service.yaml</code> for defining a service that relays requests to the deployed pod(s).</p>
<p>My cluster is running in a VM (Ubuntu Server 22.04, using <code>microk8s</code> for K8s) thus if I want to access the web service using my host's web browser I cannot simply use the cluster's internal network but expose the service to the VM's network that connects it to the host.</p>
<p>I always have to do</p>
<pre><code>kubectl -n geo patch svc flask-test --patch=&quot;{\&quot;spec\&quot;:{\&quot;externalIPs\&quot;:[\&quot;192.168.122.163\&quot;]}}&quot;
</code></pre>
<p>where the IP address is the one of the VM. After the patch is applied I have</p>
<p><a href="https://i.stack.imgur.com/v0LuE.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/v0LuE.png" alt="Kubernetes Dashboard view of the example service" /></a></p>
<p>Only after that my web browser can actually interact with the service.</p>
<p>Is there a way to automatically apply a patch (either via <code>--patch</code> or <code>--patch-file</code>) to a service in Kubernetes once that service has been created? I though of adding the IP address to <code>.gitlab-ci.yaml</code> file where the deployment takes place since I can, after all, call <code>kubectl</code> to configure stuff just as I am calling <code>helm</code> to actually deploy and setup the service for my app. However this has many flaws including the fact that the IP address will probably change at some point, thus requiring touching every repository that is configured in a way that uses that IP address. That is why I would like to keep the cluster-related configuration to the cluster itself.</p>

rbaleksandar
<p>I would use Helm to do this setup directly, without a separate <code>kubectl patch</code> step.  You can include the IP address in your manifest, with a value that is provided at deploy time.  For example:</p>
<pre class="lang-yaml prettyprint-override"><code># templates/service.yaml
spec:
  externalIPs:
{{- with .Values.externalIP }}
    - {{ . }}
{{- else }}
    []
{{- end }}
</code></pre>
<p>Importantly, you do not need to include a specific setting in the <code>values.yaml</code> file for this.  If a <code>externalIP</code> value is set then it will be injected into the Service, but if not, an empty list will be used instead.</p>
<p>This means that you can provide a value at the command line, like</p>
<pre class="lang-yaml prettyprint-override"><code>helm install -n geo flask-test . \
  --set externalIP=192.168.122.163
</code></pre>
<p>But if that address ever changes, you can change the value here too</p>
<pre class="lang-yaml prettyprint-override"><code>helm upgrade -n geo flask-test . --reuse-values \
  --set externalIP=192.168.123.321
</code></pre>
<p>In this last example I've used <code>--reuse-values</code>, so Helm starts from the configuration that was used for the last installation and only updates the <code>externalIP</code> value.</p>
<p>Your CD system could do this too.  If it had some way of finding out what the IP address was, you could script running this <code>helm upgrade</code> command across every repository, without actually having to commit anything.  You could also combine this with some of the techniques you describe in the question and comments; if you can run a shell command then you can <code>--set externalIP=$(ip addr show ...)</code> for example.</p>
