Infrastructure as Code Matures

Kubernetes 1.18 & GitOps - Infrastructure as Code Matures

As the world shifted to remote work in 2020, the importance of declarative, version-controlled infrastructure became more apparent than ever. Kubernetes 1.18 brought stability improvements and features that made GitOps not just possible, but the preferred way to manage cloud-native applications.

The idea that infrastructure and application deployments should be driven entirely by Git commits wasn't new, but 2020 made it essential. When teams couldn't walk over to the operations desk to troubleshoot a deployment, having every change tracked and reversible became critical.

yaml

# GitOps repository structure

infrastructure/

── environments/

   ── development/

      ── namespace.yaml

      ── applications/

      └── monitoring/

   ── staging/

   └── production/

── applications/

   ── user-service/

      ── base/

         ── kustomization.yaml

         ── deployment.yaml

         └── service.yaml

      └── overlays/

          ── development/

          ── staging/

          └── production/

└── platform/

    ── monitoring/

    ── logging/

    └── networking/

The maturation of GitOps operators like ArgoCD and Flux transformed how teams managed deployments. Instead of manual kubectl commands or complex CI/CD scripts, applications were deployed and updated automatically based on Git repository state.

yaml

# ArgoCD Application definition

apiVersion: argoproj.io/v1alpha1

kind: Application

metadata:

  name: user-service

  namespace: argocd

spec:

  project: default

  source:

    repoURL: https://github.com/company/k8s-manifests

    targetRevision: HEAD

    path: applications/user-service/overlays/production

  destination:

    server: https://kubernetes.default.svc

    namespace: production

  syncPolicy:

    automated:

      prune: true

      selfHeal: true

    syncOptions:

    - CreateNamespace=true

    retry:

      limit: 2

      backoff:

        duration: 5s

        factor: 2

        maxDuration: 3m0s

The built-in Kustomize support in kubectl eliminated the need for complex templating solutions while providing powerful configuration management capabilities.

yaml

# Base kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization

 

resources:

- deployment.yaml

- service.yaml

- configmap.yaml

 

images:

- name: user-service

  newTag: v1.2.3

 

# Production overlay

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization

 

resources:

- ../../base

 

replicas:

- name: user-service

  count: 5

 

patchesStrategicMerge:

- production-config.yaml

 

configMapGenerator:

- name: app-config

  files:

  - application-production.properties

  behavior: replace

The integration with external secret management systems became mature enough for production use, enabling secure GitOps workflows where sensitive data wasn't stored in Git repositories.

yaml

# External Secrets Operator

apiVersion: external-secrets.io/v1beta1

kind: ExternalSecret

metadata:

  name: database-credentials

spec:

  refreshInterval: 15s

  secretStoreRef:

    name: vault-backend

    kind: SecretStore

  target:

    name: db-secret

    creationPolicy: Owner

  data:

  - secretKey: username

    remoteRef:

      key: database/production

      property: username

  - secretKey: password

    remoteRef:

      key: database/production

      property: password

As organizations adopted multiple Kubernetes clusters for different environments or regions, the tooling for managing these clusters in a GitOps manner became sophisticated.

GitOps became essential for remote teams because it provided complete auditability and self-service capabilities. Developers could deploy applications by creating pull requests, operations teams could review changes asynchronously, and everyone could see the complete deployment history.

The declarative nature of GitOps meant that infrastructure drift became impossible—the cluster state always matched what was declared in Git. This was particularly valuable when team members were working across different time zones and couldn't easily coordinate manual changes.

GitOps forced organizations to treat infrastructure changes with the same rigor as application code changes. Code reviews, testing, and approval workflows became standard for infrastructure changes, leading to more reliable and secure deployments.

I worked with a team that was struggling with deployment coordination across US and European team members. Before GitOps, deployments required real-time coordination and often failed due to miscommunication. After implementing ArgoCD with a GitOps workflow, deployments became self-service and automatic. The European team could make changes during their day, the US team could review them during their day, and deployments happened automatically without anyone needing to be online simultaneously.

The relief on everyone's faces when they realized they could deploy reliably without complex coordination was unforgettable. GitOps didn't just solve a technical problem—it solved a human collaboration problem.

Comments