Cloud Infrastructure & DevOps
Cloud Infrastructure & DevOps
Cloud computing and DevOps transformed how software is built and deployed. Instead of managing physical hardware, engineers provision infrastructure programmatically, deploy in containers, and automate every step from code to production. This shift enables teams of five to operate services at global scale.
Cloud Computing Models
IaaS (Infrastructure as a Service): raw compute (VMs), storage, and networking. You manage everything from OS up. AWS EC2, Azure VMs, GCP Compute Engine. Maximum control, maximum responsibility.
PaaS (Platform as a Service): managed runtime environments. You deploy your application; the platform manages OS, runtime, scaling, and availability. Heroku, Google App Engine, Railway, Vercel. Faster to start, less control.
FaaS (Functions as a Service / Serverless): deploy individual functions that execute on-demand. Auto-scales to zero; you pay only for execution time. AWS Lambda, Cloudflare Workers, Vercel Edge Functions. Ideal for event-driven workloads; cold start latency is a limitation.
The shared responsibility model: the cloud provider secures the infrastructure (hardware, hypervisor, facilities); you secure what runs on it (OS updates, application security, IAM policies, encryption of your data).
Infrastructure as Code
IaC treats infrastructure configuration like application code: version-controlled, reviewed, testable, and automated.
Terraform (HashiCorp): declarative HCL syntax for provisioning cloud resources across any provider. State file tracks what's deployed; plan shows what will change before applying.
resource "aws_instance" "app" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
tags = { Name = "app-server" }
}CDK / Pulumi: define infrastructure in general-purpose languages (TypeScript, Python) rather than config syntax. Type safety, loops, and abstractions that HCL doesn't support.
Ansible / Chef / Puppet: configuration management — install packages, configure services, manage files on existing servers. Useful for server configuration; less appropriate for provisioning new infrastructure (that's Terraform's role).
GitOps: IaC stored in Git is the single source of truth; changes happen through PRs; automated pipelines apply changes on merge. Audit trail, rollback via git revert, team review of infrastructure changes.
Containers and Docker
Docker packages applications with their dependencies into portable images:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # install dependencies
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Image layers: each Dockerfile instruction creates a layer. Layers are cached; only changed layers rebuild. Put rarely-changed instructions (FROM, RUN npm install) before frequently-changed ones (COPY source code) to maximize cache hits.
Container isolation: containers share the host kernel but have separate:
- Filesystem (image layers + container-specific writable layer)
- Process namespace (processes inside can't see host processes)
- Network namespace (each container has a virtual network interface)
- cgroups (CPU and memory limits)
Docker Compose: define multi-container applications. A web app with a database and a cache:
services:
app: { image: myapp, ports: ['3000:3000'], environment: {DATABASE_URL: postgres://db:5432/mydb} }
db: { image: postgres:15, environment: {POSTGRES_DB: mydb} }
cache: { image: redis:7-alpine }Kubernetes
Kubernetes (K8s) is a container orchestration platform that manages containerized workloads across a cluster of machines.
Core concepts:
- Pod: the smallest deployable unit; 1+ containers sharing a network namespace and storage
- Deployment: manages a set of Pod replicas with rolling updates
- Service: a stable DNS name and IP that load-balances across matching Pods
- Ingress: routes external HTTP traffic to Services
- ConfigMap / Secret: externalizes configuration from container images
Deployment example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
spec:
containers:
- name: app
image: myapp:v1.2.3
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "512Mi" }Why Kubernetes: it handles scheduling (which node runs each Pod), restarts failed Pods, scales up and down, performs rolling updates with zero downtime, and manages service discovery. The trade-off: significant operational complexity.
CI/CD Pipelines
CI/CD automates the path from code to production:
Continuous Integration:
- Every commit triggers a pipeline
- Build the application
- Run unit and integration tests
- Static analysis (linting, type checking, SAST)
- Build and push container image
- Fail fast: if tests fail, the pipeline stops and notifies the developer
Continuous Deployment:
- Deploy to staging automatically on every main branch merge
- Run smoke tests against staging
- Deploy to production automatically (CD) or after manual approval (Continuous Delivery)
Pipeline as Code (GitHub Actions, CircleCI, GitLab CI):
name: Deploy
on: [push]
jobs:
test:
steps:
- run: npm test
deploy:
needs: test
steps:
- run: vercel deploy --prodFeature flags: deploy code before it's "on." Flag controls whether the feature is visible to users. Enables dark launches, progressive rollouts, and instant kill switches without a deployment.
Observability: Metrics, Logs, Traces
The Three Pillars:
- Metrics: numerical time-series measurements (request rate, error rate, latency percentiles, CPU usage). Alerting is based on metrics. Prometheus collects metrics; Grafana visualizes.
- Logs: timestamped records of events. Use structured logging (JSON) to enable querying. Aggregate with ELK stack, Loki, or Datadog.
- Traces: records of requests as they propagate through distributed services. Shows where time is spent and where errors occur. OpenTelemetry is the standard; Jaeger and Zipkin store and visualize traces.
SLO / SLA / SLI:
- SLI (Service Level Indicator): a measured metric (99th percentile latency, error rate)
- SLO (Service Level Objective): the target (99.9% requests under 200ms)
- SLA (Service Level Agreement): contract with customers; SLA ≤ SLO (you alert internally before breaching the customer commitment)
Error budget: if your SLO is 99.9% uptime, you have 43.8 minutes/month of allowed downtime. Spend it on deployments and experiments. If you've used it, freeze deployments until the budget resets.