<p>I want to add and remove specific key value pair into kubernetes yamls</p>
<p>For eg:</p>
<pre><code>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: null
    version: latest
  name: null
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: null
      version: latest
  template:
    metadata:
      labels:
        app: null
        version: latest
    spec:
      containers:
      - image: aude-service
        name: aude-api
        ports:
        - containerPort: 3003
          hostPort: 3003
          protocol: TCP
</code></pre>
<p>Contents to be removed in spec after selector:</p>
<pre><code>hostPort: 3003
protocol: TCP

</code></pre>
<p>Contents to be added:</p>
<pre><code>strategy:
  type: RollingUpdate 
  rollingUpdate:
    maxUnavailable: 25% 

</code></pre>
<p>It would be of great help, if anyone suggest solution</p>
<p>So, I tried using bash to remove hostport key but it didn't work</p>
<pre><code>awk '/^[[:alpha:]]+:/ {level1=$0; next} level1 ~ &quot;hostPort&quot; &amp;&amp; /aaa/ {next} 1' aude-convert.yml
</code></pre>

Vansh Kumar Madan
<p>If you wanna try something different, you could work with <code>yq</code> to achieve the same. <code>yq</code> is a lightweight and portable command-line YAML processor. <code>yq</code> uses <code>jq</code> like syntax but works with yaml files as well as json. Read more about it <a href="https://mikefarah.gitbook.io/yq/" rel="nofollow noreferrer">here</a></p>
<p>So, in your case</p>
<p>To <strong>remove the content</strong> from the yaml:</p>
<pre><code>yq -i 'del(.spec.template.spec.containers[0].ports[0].hostPort) | del(.spec.template.spec.containers[0].ports[0].protocol)' deployment.yaml
</code></pre>
<p>Here we are removing the <code>hostPort</code> and <code>protocol</code> entries from the first element of the <code>ports</code> array.</p>
<p>This gives you a lot of flexibility, for eg if you have multiple <code>containerPort</code> &amp; <code>hostPort</code> entries you could easily select the second element of the <code>ports</code> array:</p>
<pre><code>yq -i 'del(.spec.template.spec.containers[0].ports[1].hostPort) | del(.spec.template.spec.containers[0].ports[1].protocol)' deployment.yaml
</code></pre>
<p>or both elements:</p>
<pre><code>yq -i 'del(.spec.template.spec.containers[0].ports[].hostPort) | del(.spec.template.spec.containers[0].ports[].protocol)' deployment.yaml
</code></pre>
<p>and the same can be applied to <code>containers[0]</code> - not providing examples for this but I hope you got the point. Really flexible.</p>
<hr />
<p>To <strong>add the required content</strong> to the yaml:</p>
<pre><code>yq -i '.spec.strategy = {&quot;type&quot;: &quot;RollingUpdate&quot;, &quot;rollingUpdate&quot;: {&quot;maxUnavailable&quot;: &quot;25%&quot;}}' deployment3.yaml
</code></pre>
<p>This adds the required content at the end of the file within <code>spec</code> (as is defined using <code>.spec.strategy</code> in the <code>cmd</code>).</p>
<p>To add it right below <code>replicas</code>:</p>
<pre><code>yq -i '.spec |= {&quot;replicas&quot;: .replicas, &quot;strategy&quot;: {&quot;type&quot;: &quot;RollingUpdate&quot;, &quot;rollingUpdate&quot;: {&quot;maxUnavailable&quot;: &quot;25%&quot;}}, &quot;selector&quot;: .selector, &quot;template&quot;: .template}' deployment.yaml
</code></pre>
<p>adding the new <code>strategy</code> key-value pair to the <code>.spec</code> object along with the existing <code>.replicas</code>, <code>.selector</code> &amp; <code>template</code> key.</p>
<p>This helps with not worrying about spaces or tabs that would come with <code>sed</code>.</p>
<p>Hope it helps.</p>
