DevOps and Infrastructure as Code:
Enterprise Automation Framework
Comprehensive Table of Contents
1. DevOps Fundamentals and Culture
2. Infrastructure as Code (IaC) Principles
3. Configuration Management and Automation
4. Containerization and Orchestration
5. CI/CD Pipeline Architecture
6. Monitoring, Logging, and Observability
7. Infrastructure Scaling and Load Balancing
8. Disaster Recovery and High Availability
9. Security in DevOps (DevSecOps)
10. Cost Optimization and Resource Management
11. GitOps and Infrastructure Management
12. DevOps Tools and Best Practices
Chapter 1: DevOps Fundamentals and Culture
1.1 What is DevOps?
DevOps is a set of practices, cultural philosophies, and tools that integrate software
development and IT operations. It emphasizes collaboration, automation, and measurement
to deliver software faster and more reliably.
Traditional Approach : - Developers and operations teams work separately - Deployments
are rare and risky - Long time-to-market - Blame culture when things fail
DevOps Approach : - Development and operations collaborate continuously - Frequent,
small deployments - Fast feedback loops - Shared responsibility for reliability
1.2 The Three Ways of DevOps
First Way: Flow - Accelerate left-to-right flow of work from development to operations -
Visualize work, limit work-in-progress - Reduce batch sizes - Reduce handoffs - Identify
and eliminate constraints
Second Way: Feedback - Amplify feedback from right to left - Implement comprehensive
monitoring and logging - Share metrics with developers - Enable developers to see
production behavior - Short feedback loops enable rapid learning
Third Way: Continuous Learning - Create culture of experimentation and risk-taking -
Establish rituals that reinforce learning - Allocate time for improvement - Share knowledge
across organization - Blameless post-mortems after incidents
1.3 DevOps vs SRE (Site Reliability Engineering)
DevOps focuses on bridging the gap between development and operations through culture
and tooling.
SRE applies software engineering practices to operations work, focusing on reliability.
Both complement each other: - DevOps provides automation and tooling - SRE provides
reliability engineering practices - Together they enable rapid, reliable deployments
1.4 Key DevOps Principles
Automation: Automate everything—deployments, testing, infrastructure provisioning,
monitoring.
Continuous Integration: Developers integrate code frequently into main branch, with
automated tests.
Continuous Delivery: Software is always in deployable state, ready for production
release.
Infrastructure as Code: Manage infrastructure through code, enabling version control
and repeatability.
Monitoring and Observability: Comprehensive visibility into system behavior enables
quick problem detection and resolution.
Blameless Culture: Focus on systems and processes rather than blaming individuals for
failures.
Chapter 2: Infrastructure as Code (IaC) Principles
2.1 IaC Fundamentals
Infrastructure as Code means managing infrastructure through code, treating infrastructure
with same rigor as application code.
Benefits: - Reproducibility: Same infrastructure can be deployed repeatedly - Version
Control: Track infrastructure changes over time - Rapid Provisioning: Automated
infrastructure deployment - Disaster Recovery: Quickly recreate infrastructure after
failures - Documentation: Code serves as executable documentation - Consistency:
Eliminates manual configuration drift
2.2 Declarative vs Imperative IaC
Declarative Approach (Terraform, CloudFormation):
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "[Link]"
tags = {
Name = "web-server"
}
}
User specifies desired state; tool handles how to achieve it.
Imperative Approach (Ansible, Chef):
---
- name: Deploy web server
hosts: webservers
tasks:
- name: Install Apache
apt:
name: apache2
state: present
- name: Start Apache
service:
name: apache2
state: started
User specifies steps to achieve desired state.
2.3 Popular IaC Tools
Terraform: - Declarative language (HCL) - Multi-cloud support - Stateful infrastructure
management - Large community
AWS CloudFormation: - AWS-native IaC - JSON or YAML format - Tight AWS
integration - Free service
Ansible: - Imperative, agent-less automation - Python-based - Simple YAML syntax -
Broad infrastructure support
Chef: - Imperative configuration management - Ruby-based - Agent-based - Mature
platform
2.4 IaC Best Practices
# Use variables for flexibility
variable "environment" {
type = string
default = "production"
}
variable "instance_count" {
type = number
default = 3
}
# Use modules for reusability
module "vpc" {
source = "./modules/vpc"
cidr = "[Link]/16"
}
# Use outputs to expose values
output "load_balancer_dns" {
value = aws_lb.main.dns_name
description = "DNS name of load balancer"
}
# Use locals for derived values
locals {
environment_suffix = "${[Link]}-${[Link]}"
common_tags = {
Environment = [Link]
ManagedBy = "Terraform"
CreatedAt = timestamp()
}
}
Chapter 3: Configuration Management and
Automation
3.1 Configuration Drift
Configuration drift occurs when server configurations diverge from defined state due to
manual changes.
Initial State (via IaC)
↓
Manual Changes (operator updates)
↓
Configuration Drift
↓
Inconsistency, bugs, security issues
↓
Disaster
Prevention: - Immutable infrastructure - Continuous compliance checking - Version
control for all changes - Automation over manual processes
3.2 Ansible Configuration Management
---
- hosts: webservers
vars:
app_version: 2.0
app_port: 8080
roles:
- common
- webserver
- monitoring
tasks:
- name: Deploy application
git:
repo: [Link]
dest: /opt/app
version: "{{ app_version }}"
notify: restart app
- name: Configure application
template:
src: [Link].j2
dest: /etc/app/[Link]
notify: restart app
- name: Start application
systemd:
name: app
state: started
enabled: yes
handlers:
- name: restart app
systemd:
name: app
state: restarted
3.3 Compliance and Auditing
# Automated compliance checking
import boto3
ec2 = [Link]('ec2')
def check_security_group_compliance():
"""Verify security groups follow compliance rules"""
security_groups = ec2.describe_security_groups()['SecurityGroups']
violations = []
for sg in security_groups:
# Check for overly permissive rules
for rule in sg['IpPermissions']:
if [Link]('IpRanges'):
for ip_range in rule['IpRanges']:
if ip_range.get('CidrIp') == '[Link]/0':
[Link](f"SG {sg['GroupId']} allows public access on port
return violations
Chapter 4: Containerization and Orchestration
4.1 Docker and Container Best Practices
# Multi-stage build to reduce image size
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production image
FROM node:18-alpine
WORKDIR /app
ENV NODE_ENV production
# Create non-root user for security
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
USER nodejs
EXPOSE 3000
# Use exec form to ensure proper signal handling
CMD ["node", "dist/[Link]"]
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD node [Link]
4.2 Kubernetes Deployment Strategy
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Chapter 5: CI/CD Pipeline Architecture
5.1 CI/CD Pipeline Stages
Source Code (Git)
↓
[1] Trigger on commit
├─ Checkout code
└─ Run tests
↓
[2] Build
├─ Compile/bundle application
├─ Run unit tests
├─ Run integration tests
└─ Generate artifacts
↓
[3] Security Scanning
├─ SAST (Static Application Security Testing)
├─ Dependency scanning
└─ Container image scanning
↓
[4] Deploy to Staging
├─ Deploy application
├─ Run smoke tests
└─ Run E2E tests
↓
[5] Approval Gate (Manual)
↓
[6] Deploy to Production
├─ Blue-green or canary deployment
├─ Monitor metrics
└─ Automatic rollback if needed
↓
[7] Post-Deployment Monitoring
├─ Performance metrics
├─ Error rates
└─ User experience
5.2 GitLab CI/CD Configuration
stages:
- test
- build
- scan
- deploy
variables:
DOCKER_DRIVER: overlay2
CI_REGISTRY: [Link]
test_job:
stage: test
image: python:3.11
script:
- pip install -r [Link]
- pytest tests/
- coverage report
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: [Link]
build_image:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
security_scan:
stage: scan
image: aquasec/trivy:latest
script:
- trivy image --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
allow_failure: true
deploy_staging:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n staging
- kubectl rollout status deployment/app -n staging
environment:
name: staging
only:
- main
deploy_production:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n production
- kubectl rollout status deployment/app -n production
environment:
name: production
when: manual
only:
- main
Chapter 6: Monitoring, Logging, and Observability
6.1 The Three Pillars of Observability
Metrics: Quantitative measurements of system behavior. - CPU usage - Memory
consumption - Request latency - Error rates - Business metrics
Logs: Detailed records of events. - Application logs - System logs - Access logs - Audit
logs
Traces: Track requests through distributed systems. - Request path - Component
interactions - Performance breakdown - Error attribution
6.2 Prometheus Monitoring
# [Link]
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'app'
static_configs:
- targets: ['localhost:8080']
metrics_path: '/metrics'
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
PromQL Query Examples:
# Request rate
rate(http_requests_total[5m])
# Error rate
rate(http_requests_total{status=~"5.."}[5m])
# P95 latency
histogram_quantile(0.95, request_duration_seconds)
# Memory usage
process_resident_memory_bytes / 1024 / 1024
6.3 ELK Stack for Logging
version: '3'
services:
elasticsearch:
image: [Link]/elasticsearch/elasticsearch:7.13.0
environment:
- [Link]=single-node
- [Link]=false
ports:
- "9200:9200"
logstash:
image: [Link]/logstash/logstash:7.13.0
volumes:
- ./[Link]:/usr/share/logstash/pipeline/[Link]
ports:
- "5000:5000"
kibana:
image: [Link]/kibana/kibana:7.13.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=[Link]
Chapter 7: Infrastructure Scaling and Load Balancing
7.1 Horizontal Scaling
# Terraform: Auto Scaling Group
resource "aws_autoscaling_group" "app" {
name = "app-asg"
vpc_zone_identifier = var.subnet_ids
min_size = 2
max_size = 10
desired_capacity = 3
launch_template {
id = aws_launch_template.[Link]
version = "$Latest"
}
tag {
key = "Name"
value = "app-instance"
propagate_at_launch = true
}
}
# Scaling policies
resource "aws_autoscaling_policy" "scale_up" {
name = "scale-up"
scaling_adjustment = 1
adjustment_type = "ChangeInCapacity"
autoscaling_group_name = aws_autoscaling_group.[Link]
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "high-cpu"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = 120
statistic = "Average"
threshold = 70
alarm_actions = [aws_autoscaling_policy.scale_up.arn]
}
7.2 Load Balancing Strategies
Round Robin: Distribute requests equally across instances.
Least Connections: Route to instance with fewest active connections.
IP Hash: Route based on client IP, ensures session persistence.
Weighted: Route based on assigned weights.
# Nginx load balancing configuration
upstream app_backend {
least_conn;
server [Link] weight=3;
server [Link] weight=2;
server [Link] backup;
keepalive 32;
}
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Health check
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
}
Chapter 8: Disaster Recovery and High Availability
8.1 RTO and RPO
RTO (Recovery Time Objective): Maximum time allowed for system recovery.
RPO (Recovery Point Objective): Maximum acceptable data loss.
Time
│
├─ Disaster occurs
├─ Detection time
├─ Recovery time (RTO)
│ └─ System back online
├─ Data loss (RPO)
│ └─ Latest backup restored
└─ Full recovery
Lower RTO/RPO = Higher cost and complexity
8.2 Backup Strategy
#!/bin/bash
# Automated backup script
BACKUP_DIR="/backups"
DATABASE="production_db"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_$[Link]"
# Perform backup
mysqldump -u root -p"$DB_PASSWORD" "$DATABASE" > "$BACKUP_FILE"
# Compress
gzip "$BACKUP_FILE"
# Upload to S3
aws s3 cp "$BACKUP_FILE.gz" "s3://backup-bucket/$DATABASE/$TIMESTAMP/"
# Verify backup
if ! gunzip -t "$BACKUP_FILE.gz"; then
echo "Backup verification failed!"
exit 1
fi
# Retention policy (keep 30 days)
find "$BACKUP_DIR" -name "backup_*.[Link]" -mtime +30 -delete
echo "Backup completed successfully"
8.3 High Availability Architecture
Availability Zone 1 Availability Zone 2
┌─────────────────────┐ ┌─────────────────────┐
│ Load Balancer │ │ Load Balancer │
│ (Primary) │ │ (Standby) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
Route 53 Health Check Route 53 Health Check
│ │
┌──────────┴──────────┐ ┌──────────┴──────────┐
│ Web Server 1 │ │ Web Server 2 │
│ Web Server 2 │ │ Web Server 3 │
│ App Server 1 │ │ App Server 2 │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
┌──────────┴──────────┐ ┌──────────┴──────────┐
│ Primary Database │ │ Secondary Database │
│ (Multi-AZ) │◄────►│ (Read Replica) │
└─────────────────────┘ └─────────────────────┘
│ │
└───────────────┬───────────┘
│
┌──────┴──────┐
│ S3 Backup │
│ (Cross-AZ) │
└─────────────┘
Chapter 9: Security in DevOps (DevSecOps)
9.1 Security as Code
# Terraform security policies
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.[Link]
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_security_group" "app" {
name = "app-sg"
# Explicitly deny all inbound
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = []
}
# Allow only specific ports
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["[Link]/0"]
}
# Allow outbound only to known services
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["[Link]/0"]
}
}
9.2 Secrets Management
# Using AWS Secrets Manager
import boto3
import json
def get_database_credentials():
client = [Link]('secretsmanager')
try:
response = client.get_secret_value(SecretId='prod/db/password')
secret = [Link](response['SecretString'])
return secret
except Exception as e:
print(f"Error retrieving secret: {e}")
raise
credentials = get_database_credentials()
# Never log or print credentials!
9.3 Supply Chain Security
# SBOM (Software Bill of Materials) generation
name: Build with Security
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build application
run: |
npm install
npm run build
- name: Generate SBOM
uses: CycloneDX/cyclonedx-npm@master
with:
output-file: [Link]
- name: Scan dependencies
uses: anchore/scan-action@v3
with:
path: [Link]
fail-build: true
severity-cutoff: high
Chapter 10: Cost Optimization and Resource
Management
10.1 Cost Monitoring
# AWS Cost Analysis
import boto3
ce = [Link]('ce')
response = ce.get_cost_and_usage(
TimePeriod={
'Start': '2024-01-01',
'End': '2024-01-31'
},
Granularity='DAILY',
Metrics=['UnblendedCost'],
GroupBy=[
{
'Type': 'DIMENSION',
'Key': 'SERVICE'
}
]
)
for result in response['ResultsByTime']:
print(f"Date: {result['TimePeriod']['Start']}")
for group in result['Groups']:
service = group['Keys'][0]
cost = group['Metrics']['UnblendedCost']['Amount']
print(f" {service}: ${cost}")
10.2 Resource Optimization
# Use spot instances for cost savings
resource "aws_instance" "worker" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "[Link]"
spot_price = "0.05"
availability_zone = "us-east-1a"
tags = {
Name = "spot-worker"
}
}
# Right-size resources based on actual usage
resource "aws_rds_cluster_instance" "example" {
instance_class = "[Link]" # Start small
performance_insights_enabled = true
monitoring_interval = 60
tags = {
CostCenter = "engineering"
}
}
Chapter 11: GitOps and Infrastructure Management
11.1 GitOps Principles
Single Source of Truth: Git repository contains complete infrastructure and application
definition.
Declarative Configuration: Git contains desired state, not procedures.
Automated Synchronization: System automatically syncs with Git state.
Version Control: All changes tracked with git history.
Observable: System state visible and auditable.
11.2 ArgoCD Configuration
apiVersion: [Link]/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: [Link]
targetRevision: main
path: k8s/production
destination:
server: [Link]
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
# Notifications
notifications:
- name: slack
webhook: [Link]
Chapter 12: DevOps Tools and Best Practices
12.1 Essential DevOps Tools
Version Control: Git, GitHub, GitLab, Bitbucket
CI/CD: Jenkins, GitLab CI, GitHub Actions, CircleCI
IaC: Terraform, Ansible, CloudFormation, Pulumi
Containers: Docker, Podman
Orchestration: Kubernetes, Docker Swarm
Monitoring: Prometheus, Grafana, DataDog
Logging: ELK Stack, Splunk, CloudWatch
Secrets: Vault, AWS Secrets Manager, sealed-secrets
12.2 DevOps Best Practices
Automate Everything: Manual processes introduce errors and waste time.
Version Everything: Infrastructure, configuration, and application code.
Test Early and Often: Catch issues as early as possible in pipeline.
Monitor Continuously: Visibility into system behavior enables quick response.
Document Decisions: Explain why decisions were made, not just what.
Collaborate Openly: Share knowledge and information across teams.
Embrace Failure: Learn from failures through blameless post-mortems.
Measure Impact: Track metrics showing DevOps improvements.
Conclusion
DevOps represents a fundamental shift in how organizations build, deploy, and operate
software. Success requires combination of cultural change, process improvement, and tool
implementation. Organizations that embrace DevOps principles gain competitive advantages
through faster delivery, higher reliability, and better cost efficiency.
Key takeaways: - Culture comes before tools - Automate everything possible - Treat
infrastructure as code - Implement comprehensive monitoring - Establish clear feedback
loops - Focus on continuous improvement - Prioritize security throughout pipeline - Build
collaborative teams - Measure and optimize continuously
As technology continues evolving, DevOps practices will remain essential for organizations
seeking to deliver software faster, more reliably, and more efficiently.