<p>So I have a kubernetes cronjob object set to run periodically.</p>
<pre class="lang-py prettyprint-override"><code>NAME                            SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
ticketing-job-lifetime-manager  45 */4 * * *   False     0        174m            25d
</code></pre>
<p>and I know how to call it manually:</p>
<pre class="lang-yaml prettyprint-override"><code># ticketing-job-manual-call will be the name of the job that runs
kubectl create job --from=cronjobs/ticketing-job-lifetime-manager ticketing-job-manual-call
</code></pre>
<p><strong>BUT</strong> - what I want to do is call the job, but modify portions of it (shown below) before it is called.  Specifically <code>items.metadata.annotations</code> and <code>items.spec.jobTemplate.spec.containers.args</code>.</p>
<p>If this is possible on-the-fly, I'd be over the moon.  If it requires creating a temporary object, then I'd appreciate an approach to doing this that is robust, performant - and safe.  Thanks!</p>
<pre class="lang-yaml prettyprint-override"><code>    apiVersion: v1
    items:
      - apiVersion: batch/v1
        kind: CronJob
        metadata:
          annotations:
            &lt;annotation-1&gt;              &lt;- want to modify these
            &lt;annotation-2&gt;
            ..
            &lt;annotation-n&gt;
          creationTimestamp: &quot;2022-05-03T13:24:49Z&quot;
          labels:
            AccountID: foo
            FooServiceAction: &quot;true&quot;
            FooServiceManaged: &quot;true&quot;
            CronName: foo
          name: foo
          namespace: my-namespace
          resourceVersion: &quot;298013999&quot;
          uid: 57b2-4612-88ef-a0d5e26c8
        spec:
          concurrencyPolicy: Replace
          jobTemplate:
            metadata:
              annotations:
                &lt;annotation-1&gt;          &lt;- want to modify these
                &lt;annotation-2&gt;
                ..
                &lt;annotation-n&gt;
              creationTimestamp: null
              labels:
                AccountID: 7761777c38d93b
                TicketServiceAction: &quot;true&quot;
                TicketServiceManaged: &quot;true&quot;
                CronName: ticketing-actions-7761777c38d93b-0
              name: ticketing-actions-7761777c38d93b-0
              namespace: rias
            spec:
              containers:
                - args:
                    - --accountid=something     &lt;- want to modify these
                    - --faultzone=something
                    - --type=something
                    - --cronjobname=something
                    - --plans=something
                  command:
                    - ./ticketing-job
                  env:
                    - name: FOO_BAR             &lt;- may want to modify these
                      value: &quot;false&quot;
                    - name: FOO_BAZ
                      value: &quot;true&quot;
</code></pre>

Oliver Williams
<p>The way to think about this is that Kubernetes resources are defined (definitively) by YAML|JSON config files. A useful advantage to having config files is that these can be checked into source control; you automatically audit your work if you create unique files for each resource (for every change).</p>
<p>Kubernetes (<code>kubectl</code>) isn't optimized|designed to tweak Resources although you can use <a href="https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/" rel="nofollow noreferrer"><code>kubectl patch</code></a> to update deployed Resources.</p>
<p>I encourage you to consider a better approach that is applicable to any Kubernetes resource (not just <code>Job</code>'s) and this focuses on use YAML|JSON files as the way to represent state:</p>
<ol>
<li><code>kubectl get</code> the resource and output it as YAML|JSON (<code>--output=json|yaml</code>) persisting the result to a file (that could be source-controlled)</li>
<li>Mutate the file using any of many tools but preferably YAML|JSON processing tools (e.g. <a href="https://github.com/mikefarah/yq" rel="nofollow noreferrer"><code>yq</code></a> or <a href="https://stedolan.github.io/jq/" rel="nofollow noreferrer"><code>jq</code></a>)</li>
<li><code>kubectl create</code> or <code>kubectl apply</code> the file that results that reflects the intended configuration of the new resource.</li>
</ol>
<p>By way of example, assuming you use <code>jq</code>:</p>
<pre class="lang-sh prettyprint-override"><code># Output 'ticketing-job-lifetime-manage' as a JSON file
kubectl get job/ticketing-job-lifetime-manage \
--namespace=${NAMESPACE} \
--output=json &gt; ${PWD}/ticketing-job-lifetime-manage.json

# E.g. replace '.metadata.annotations' entirely
jq '.metadata.annotations=[{&quot;foo&quot;:&quot;x&quot;},{&quot;bar&quot;:&quot;y&quot;}]' \
${PWD}/${PWD}/ticketing-job-lifetime-manage.json \
&gt; ${PWD}/${PWD}/new-job.json

# E.g. replace a specific container 'foo' specific 'args' key with value
jq '.spec.jobTemplate.spec.containers[]|select(.name==&quot;foo&quot;).args[&quot;--key&quot;]=&quot;value&quot; \
${PWD}/${PWD}/new-job.json \
&gt; ${PWD}/${PWD}/new-job.json

# Etc.

# Apply
kubectl create \
--filename=${PWD}/new-job.json \
--namespace=${NAMESPACE}
</code></pre>
<blockquote>
<p><strong>NOTE</strong> You can pipe the output from the <code>kubectl get</code> through <code>jq</code> and into <code>kubectl create</code> if you wish but it's useful to keep a file-based record of the resource.</p>
</blockquote>
<p>Having to deal with YAML|JSON config file is a common issue with Kubernetes (and every other technology that uses them). There are other tools e.g. <a href="https://jsonnet.org/" rel="nofollow noreferrer">jsonnet</a> and <a href="https://cuelang.org/docs/integrations/k8s/" rel="nofollow noreferrer">CUE</a> that try to provide a more programmatic way to manage YAML|JSON.</p>
