DRY Kubernetes: Deploying Job and CronJob with YAML Anchors and List
Managing both a one-time Job and a recurring CronJob in Kubernetes often leads to duplicated specs. In most cases, they share the same container image, environment variables, volumes, and execution logic — so why repeat yourself?
This article shows how to eliminate duplication by using:
- YAML anchors (
&and<<:) for reusable specs - Kubernetes 
Listkind to group related resources into a single manifest 
Why This Pattern?
You may want both:
- A 
Jobyou can trigger manually (e.g., ad hoc sync or debug run) - A 
CronJobthat runs on a schedule (e.g., nightly mirror) 
But you don’t want to maintain the full spec.template twice.
The YAML Pattern
📄 base/job-cron.yaml
apiVersion: v1
kind: List
items:
  - apiVersion: batch/v1
    kind: Job
    metadata:
      name: custom-job
    spec: &jobSpec
      backoffLimit: 1
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: runner
              image: alpine
              command: ["sh", "-c", "echo Running job"]
  - apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: custom-cron
    spec:
      schedule: "0 0 * * *"
      jobTemplate:
        spec:
          <<: *jobSpec
How It Works
&jobSpecdefines an anchor at theJob.speclevel.<<: *jobSpecuses the anchor to inject that structure into theCronJob’sjobTemplate.spec.kind: Listbundles the two resources into a single file you cankubectl apply -f.
Using Kustomize to control Cronjob and Job
📄 base/kustomization.yaml
resources:
  - job-cron.yaml
Example of deletion of Job to keep CronJob 📄 overlays/prod/kustomization.yaml
resources:
  - ../../base
patches:
  - target:
      kind: Job
      name: custom-job
    patch: |-
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: custom-job
      $patch: delete      
You folder structure will look like this.
📁 custom-job-kustomize/
├── 📁 base/
│   ├── job-cron.yaml
│   └── kustomization.yaml
├── 📁 overlays/
│   └── 📁 prod/
│       └── kustomization.yaml
Why Use This?
- Avoids drift between 
JobandCronJobdefinitions - Improves maintainability and readability
 - Works well in GitOps and Kustomize bases
 
Gotchas
- YAML anchors don’t work across separate files (unless you use a YAML preprocessor).
 - The syntax is pure YAML — not a Kubernetes-specific feature — so it’s resolved before reaching the API server.
 - Editors and linters may complain unless configured properly.