Feedback

Chat Icon

GitOps the Hard Way, with Argo CD

Build Real GitOps Pipelines From Empty Clusters to Automated Deploys

Sync Policy: Every Field, Every Sync Option, Every Annotation
60%

A Recap Exercise

This exercise puts the chapter's fields, sync options, and annotations together in a single manifest, plus one option from the section on deleting an Application. Write the YAML yourself first, then check it against the solution.

The Exercise

Write one Application manifest named my_app in the argocd namespace that satisfies every condition below. Then write the two resource manifests asked for in conditions 22, 23, and 24. Those live in the Git repository the Application points at, not in the Application itself.

  1. The application belongs to the default project.
  2. Its manifests come from the repository https://gitlab.com/learningargo/my-app.git, the manifests directory, tag v0.2.
  3. It deploys to the local cluster, referenced by its registered name rather than its API server URL.
  4. It deploys into the team-a namespace.
  5. Synchronization is automated.
  6. A resource deleted from Git is deleted from the cluster.
  7. A change made directly in the cluster is reverted to the Git state.
  8. A sync that would leave the application with zero resources is refused.
  9. Before any resource is pruned, the deletion has to be approved by a human.
  10. Pruning runs only after every other resource has been applied and reports healthy.
  11. When a pruned resource is deleted, its dependents are removed before the resource itself.
  12. A failed sync is retried up to 7 times. The first retry waits 15 seconds, each following wait is three times the previous one, and no wait exceeds 5 minutes.
  13. If the team-a namespace does not exist, Argo CD creates it.
  14. The created namespace carries the label team: team-a and the annotation imageregistry: quay.io.
  15. Each sync applies only the resources that changed, not every resource in the application.
  16. The merge is computed by the Kubernetes API server, not by the Argo CD client.
  17. Client-side schema validation is skipped before apply.
  18. The sync fails if any of the application's resources is already managed by another Application.
  19. The diff ignores two things: the replicas field of every Deployment, so a Horizontal Pod Autoscaler changing it does not register as drift, and the value of the environment variable named LOG_LEVEL in the Deployment named api.
  20. The fields ignored in condition 19 are also left at their live values during a sync, instead of being overwritten from Git.
  21. The application keeps only its last 5 sync records.
  22. In the manifests directory, the PersistentVolumeClaim named data is never pruned, even though condition 6 enables pruning for the application.
  23. The same data PersistentVolumeClaim also survives when the whole Application is deleted, not only when it is removed from Git.
  24. In the manifests directory, the Service named legacy is updated with kubectl replace instead of kubectl apply, because it changes an immutable field.

Try it before reading on.

Solution

The Application manifest. Each comment marks the condition the line satisfies.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my_app
  namespace: argocd
spec:
  project: default                          # (1)
  source:                                   # (2)
    repoURL: https://gitlab.com/learningargo/my-app.git
    path: manifests
    targetRevision: v0.2
  destination:
    name: in-cluster                        # (3)
    namespace: team-a                       # (4)
  revisionHistoryLimit: 5                   # (21)
  syncPolicy:
    automated:                              # (5)
      prune: true                           # (6)
      selfHeal: true                        # (7)
      allowEmpty: false                     # (8)
    retry:                                  # (12)
      limit: 7
      backoff:
        duration: 15s
        factor: 3
        maxDuration: 5m
    syncOptions:
      - CreateNamespace=true                # (13)
      - Prune=confirm                       # (9)
      - PruneLast=true                      # (10)
      - PrunePropagationPolicy=foreground   # (11)
      - ApplyOutOfSyncOnly=true             # (15)
      - ServerSideApply=true                # (16)
      - Validate=false                      # (17)
      - FailOnSharedResource=true           # (18)
      - RespectIgnoreDifferences=true       # (20)
    managedNamespaceMetadata:               # (14)
      labels:
        team: team-a
      annotations:
        imageregistry: quay.io
  ignoreDifferences:                        # (19)
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas
    - group: apps
      kind: Deployment
      name: api
      jqPathExpressions:
        # env[]? skips any container with no env block, so the
        # expression does not error on a sidecar that defines none
        - '.spec.template.spec.containers[].env[]? | select(.name 

GitOps the Hard Way, with Argo CD

Build Real GitOps Pipelines From Empty Clusters to Automated Deploys

Enroll now to unlock all content and receive all future updates for free.