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