devops-flow
Description: Infrastructure as Code, CI/CD pipeline automation, and deployment management
Category: DevOps & Deployment
Complexity: High (multi-cloud + orchestration + automation)
Purpose
Automate infrastructure provisioning, CI/CD pipelines, and deployment processes based on SPEC documents and ADR decisions. Ensures consistent, repeatable, and secure deployments across environments.
Capabilities
- Infrastructure as Code (IaC)
-
Terraform: Cloud-agnostic infrastructure provisioning
-
CloudFormation: AWS-native infrastructure
-
Ansible: Configuration management and provisioning
-
Pulumi: Modern IaC with standard programming languages
-
Kubernetes manifests: Container orchestration
- CI/CD Pipeline Generation
-
GitHub Actions: Workflow automation
-
GitLab CI: Pipeline configuration
-
Jenkins: Pipeline as code
-
CircleCI: Cloud-native CI/CD
-
Azure DevOps: Microsoft ecosystem integration
- Container Configuration
-
Dockerfile: Container image definition
-
Docker Compose: Multi-container applications
-
Kubernetes: Production orchestration
-
Helm charts: Kubernetes package management
-
Container registry: Image storage and versioning
- Deployment Strategies
-
Blue-Green: Zero-downtime deployments
-
Canary: Gradual rollout with monitoring
-
Rolling: Sequential instance updates
-
Feature flags: Progressive feature enablement
-
Rollback procedures: Automated failure recovery
- Environment Management
-
Environment separation: dev, staging, production
-
Configuration management: Environment-specific configs
-
Secret management: Vault, AWS Secrets Manager, etc.
-
Infrastructure versioning: State management
-
Cost optimization: Resource tagging and monitoring
- Monitoring & Observability
-
Logging: Centralized log aggregation
-
Metrics: Performance and health monitoring
-
Alerting: Incident response automation
-
Tracing: Distributed request tracking
-
Dashboards: Real-time visualization
- Security & Compliance
-
Security scanning: Container and infrastructure
-
Compliance checks: Policy enforcement
-
Access control: IAM and RBAC
-
Network security: Firewall rules, VPC configuration
-
Audit logging: Change tracking
- Disaster Recovery
-
Backup automation: Data and configuration backups
-
Recovery procedures: Automated restoration
-
Failover: Multi-region redundancy
-
Data replication: Cross-region sync
-
RTO/RPO: Recovery objectives implementation
DevOps Workflow
graph TD A[SPEC Document] --> B[Extract Requirements] B --> C{Infrastructure Needed?} C -->|Yes| D[Generate IaC Templates] C -->|No| E[Generate CI/CD Pipeline]
D --> F[Terraform/CloudFormation]
F --> G[Validate Infrastructure Code]
G --> H{Validation Pass?}
H -->|No| I[Report Issues]
H -->|Yes| J[Generate Deployment Pipeline]
E --> J
J --> K[CI/CD Configuration]
K --> L[Add Build Stage]
L --> M[Add Test Stage]
M --> N[Add Security Scan]
N --> O[Add Deploy Stage]
O --> P[Environment Strategy]
P --> Q{Deployment Type}
Q -->|Blue-Green| R[Generate Blue-Green Config]
Q -->|Canary| S[Generate Canary Config]
Q -->|Rolling| T[Generate Rolling Config]
R --> U[Add Monitoring]
S --> U
T --> U
U --> V[Add Rollback Procedure]
V --> W[Generate Documentation]
W --> X[Review & Deploy]
I --> X
Usage Instructions
Generate Infrastructure from SPEC
devops-flow generate-infra
--spec specs/SPEC-API-V1.md
--cloud aws
--output infrastructure/
Generated Terraform structure:
infrastructure/ ├── main.tf # Main configuration ├── variables.tf # Input variables ├── outputs.tf # Output values ├── providers.tf # Cloud provider config ├── modules/ │ ├── vpc/ # Network infrastructure │ ├── compute/ # EC2, Lambda, etc. │ ├── database/ # RDS, DynamoDB │ └── storage/ # S3, EBS └── environments/ ├── dev.tfvars # Development config ├── staging.tfvars # Staging config └── prod.tfvars # Production config
Generate CI/CD Pipeline
devops-flow generate-pipeline
--type github-actions
--language python
--deploy-strategy blue-green
--output .github/workflows/
Generated GitHub Actions workflow:
name: CI/CD Pipeline
on: push: branches: [main, develop] pull_request: branches: [main]
env: PYTHON_VERSION: '3.11' AWS_REGION: us-east-1
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install dependencies run: | pip install ruff mypy - name: Run linters run: | ruff check . mypy .
test: needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run tests run: | pytest --cov=. --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v3
security: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Security scan run: | bandit -r . -f json -o security-report.json - name: Upload security report uses: actions/upload-artifact@v3 with: name: security-report path: security-report.json
build: needs: [lint, test, security] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Build Docker image run: | docker build -t app:${{ github.sha }} . - name: Push to registry run: | docker push registry.example.com/app:${{ github.sha }}
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to staging
run: |
aws ecs update-service
--cluster staging-cluster
--service app-service
--force-new-deployment
deploy-production: needs: build if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest environment: production steps: - name: Deploy blue-green run: | # Deploy to green environment ./scripts/deploy-green.sh # Run smoke tests ./scripts/smoke-tests.sh # Switch traffic to green ./scripts/switch-traffic.sh # Keep blue for rollback
Generate Kubernetes Configuration
devops-flow generate-k8s
--spec specs/SPEC-API-V1.md
--replicas 3
--output k8s/
Generated Kubernetes manifests:
k8s/deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: api-service labels: app: api version: v1 spec: replicas: 3 selector: matchLabels: app: api template: metadata: labels: app: api version: v1 spec: containers: - name: api image: registry.example.com/api:latest ports: - containerPort: 8000 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: api-secrets key: database-url resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8000 initialDelaySeconds: 5 periodSeconds: 5
k8s/service.yaml
apiVersion: v1 kind: Service metadata: name: api-service spec: selector: app: api ports:
- protocol: TCP port: 80 targetPort: 8000 type: LoadBalancer
k8s/hpa.yaml
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: api-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: api-service minReplicas: 3 maxReplicas: 10 metrics:
- type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
Generate Deployment Scripts from REQ
devops-flow generate-deployment-scripts
--req docs/07_REQ/REQ-NN.md
--spec docs/09_SPEC/SPEC-NN.yaml
--output scripts/
Generated shell scripts structure:
scripts/ ├── setup.sh # Initial environment setup ├── install.sh # Application installation ├── deploy.sh # Main deployment orchestration ├── rollback.sh # Rollback to previous version ├── health-check.sh # Health verification └── cleanup.sh # Cleanup old versions
Script Generation Logic:
-
Parse REQ Section 9.5.3 for script requirements
-
Parse SPEC deployment section for technical details
-
Apply script standards (Bash 4.0+, error handling, logging)
-
Reference cloud provider from REQ @adr tags
-
Use environment-specific configurations from REQ 9.5.2
Example generated script (setup.sh):
#!/bin/bash set -euo pipefail
Setup environment for deployment
LOG_FILE="logs/deployment_$(date +%Y%m%d_%H%M%S).log" mkdir -p logs
log() { echo "[$(date +%Y-%m-%d %H:%M:%S)] $*" | tee -a "$LOG_FILE" }
log "Starting environment setup..."
Install dependencies
if [ ! -f .tool-versions ]; then log "Installing Python dependencies..." pip install -r requirements.txt fi
Configure environment variables
if [ -f .env.deployment ]; then log "Loading deployment environment variables..." export $(cat .env.deployment | grep -v '^#' | xargs) fi
log "Environment setup complete" exit 0
Example generated script (deploy.sh):
#!/bin/bash set -euo pipefail
Main deployment orchestration script
LOG_FILE="logs/deployment_$(date +%Y%m%d_%H%M%S).log" ENVIRONMENT="${1:-staging}"
log() { echo "[$(date +%Y-%m-%d %H:%M:%S)] $*" | tee -a "$LOG_FILE" }
Step 1: Setup
log "Running setup..." ./scripts/setup.sh
Step 2: Install
log "Installing application..." ./scripts/install.sh --env "$ENVIRONMENT"
Step 3: Deploy
log "Deploying application..." if [ "$ENVIRONMENT" = "production" ]; then ./scripts/deploy-prod.sh else ./scripts/deploy-staging.sh fi
Step 4: Health check
log "Running health check..." ./scripts/health-check.sh --env "$ENVIRONMENT"
if [ $? -eq 0 ]; then log "Deployment successful" else log "Deployment failed, initiating rollback..." ./scripts/rollback.sh --env "$ENVIRONMENT" exit 1 fi
Example generated script (health-check.sh):
#!/bin/bash set -euo pipefail
Health verification script
HEALTH_URL="${1:-http://localhost:8000/health/live}" TIMEOUT=60 RETRIES=3
log() { echo "[$(date +%Y-%m-%d %H:%M:%S)] $*" }
log "Starting health check..."
for i in $(seq 1 $RETRIES); do log "Attempt $i of $RETRIES..." RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --max-time $TIMEOUT "$HEALTH_URL")
if [ "$RESPONSE" = "200" ]; then log "Health check passed" exit 0 fi
log "Health check failed, sleeping before retry..." sleep 5 done
log "Health check failed after $RETRIES attempts" exit 1
Generate Ansible Playbooks from REQ
devops-flow generate-ansible-playbooks
--req docs/07_REQ/REQ-NN.md
--spec docs/09_SPEC/SPEC-NN.yaml
--output ansible/
Generated Ansible playbooks structure:
ansible/ ├── provision_infra.yml # Infrastructure provisioning ├── configure_instances.yml # Instance configuration ├── deploy_app.yml # Application deployment ├── configure_monitoring.yml # Monitoring setup ├── configure_security.yml # Security hardening └── backup_restore.yml # Backup/restore procedures
Playbook Generation Logic:
-
Parse REQ Section 9.5.4 for playbook requirements
-
Parse Section 9.5.1 for infrastructure configuration
-
Apply Ansible standards (2.9+, modular roles, idempotency)
-
Reference cloud provider from REQ @adr tags
-
Use environment-specific variables from REQ 9.5.2
Example generated playbook (provision_infra.yml):
-
name: Provision Infrastructure hosts: localhost gather_facts: no vars_files:
- "environments/{{ target_env }}.yml"
tasks:
-
name: Create VPC ec2_vpc_net: name: "{{ vpc_name }}" cidr_block: "{{ vpc_cidr }}" region: "{{ aws_region }}" tags: Project: "{{ project_name }}" Environment: "{{ target_env }}" ManagedBy: "Ansible"
-
name: Create security groups ec2_security_group: name: "{{ security_group_name }}" description: "Security group for {{ application_name }}" vpc_id: "{{ vpc.vpc_id }}" rules: - proto: tcp from_port: 80 to_port: 80 cidr_ip: 0.0.0.0/0 - proto: tcp from_port: 443 to_port: 443 cidr_ip: 0.0.0.0/0 region: "{{ aws_region }}" tags: Project: "{{ project_name }}" Environment: "{{ target_env }}"
-
name: Create RDS instance rds: db_name: "{{ db_name }}" engine: postgres engine_version: "{{ db_version }}" instance_type: "{{ db_instance_class }}" allocated_storage: "{{ db_storage_gb }}" username: "{{ db_username }}" password: "{{ db_password }}" vpc_security_group_ids: - "{{ security_group.group_id }}" subnet_group_name: "{{ db_subnet_group }}" backup_retention_period: "{{ backup_retention_days }}" multi_az: true region: "{{ aws_region }}" tags: Project: "{{ project_name }}" Environment: "{{ target_env }}" ManagedBy: "Ansible"
Example generated playbook (deploy_app.yml):
-
name: Deploy Application hosts: app_servers gather_facts: yes become: yes vars_files:
- "environments/{{ target_env }}.yml"
tasks:
-
name: Ensure application directory exists file: path: "{{ app_directory }}" state: directory mode: '0755' owner: "{{ app_user }}" group: "{{ app_group }}"
-
name: Copy application code synchronize: src: "{{ app_source_directory }}/" dest: "{{ app_directory }}/" delete: yes recursive: yes
-
name: Install Python dependencies pip: requirements: "{{ app_directory }}/requirements.txt" virtualenv: "{{ app_venv }}" state: present
-
name: Configure application template: src: "templates/{{ target_env }}_config.yml" dest: "{{ app_directory }}/config.yml" owner: "{{ app_user }}" group: "{{ app_group }}" mode: '0640'
-
name: Restart application service systemd: name: "{{ app_service_name }}" state: restarted daemon_reload: yes notify: Run Health Check
-
name: Wait for application to be ready wait_for: port: 8000 host: "{{ inventory_hostname }}" timeout: 300
handlers:
- name: Run Health Check uri: url: "http://localhost:8000/health/ready" method: GET status_code: 200 register: health_check
Infrastructure Templates
AWS Infrastructure (Terraform)
main.tf
terraform { required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } backend "s3" { bucket = "terraform-state-bucket" key = "infrastructure/terraform.tfstate" region = "us-east-1" } }
provider "aws" { region = var.aws_region default_tags { tags = { Project = var.project_name Environment = var.environment ManagedBy = "Terraform" } } }
VPC Module
module "vpc" { source = "./modules/vpc"
vpc_cidr = var.vpc_cidr availability_zones = var.availability_zones public_subnet_cidrs = var.public_subnet_cidrs private_subnet_cidrs = var.private_subnet_cidrs }
ECS Cluster
resource "aws_ecs_cluster" "main" { name = "${var.project_name}-${var.environment}-cluster"
setting { name = "containerInsights" value = "enabled" } }
Application Load Balancer
resource "aws_lb" "main" { name = "${var.project_name}-${var.environment}-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb.id] subnets = module.vpc.public_subnet_ids
enable_deletion_protection = var.environment == "production" }
RDS Database
resource "aws_db_instance" "main" { identifier = "${var.project_name}-${var.environment}-db" engine = "postgres" engine_version = "15.3" instance_class = var.db_instance_class
allocated_storage = var.db_allocated_storage max_allocated_storage = var.db_max_allocated_storage storage_encrypted = true
db_name = var.db_name username = var.db_username password = random_password.db_password.result
vpc_security_group_ids = [aws_security_group.db.id] db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = var.environment == "production" ? 30 : 7 skip_final_snapshot = var.environment != "production"
tags = { Name = "${var.project_name}-${var.environment}-db" } }
Docker Configuration
Dockerfile
FROM python:3.11-slim as base
WORKDIR /app
Install system dependencies
RUN apt-get update && apt-get install -y
gcc
libpq-dev
&& rm -rf /var/lib/apt/lists/*
Copy requirements
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
Copy application code
COPY . .
Create non-root user
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app USER appuser
Expose port
EXPOSE 8000
Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
Run application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Multi-stage build for smaller image
FROM base as production ENV ENVIRONMENT=production RUN pip install --no-cache-dir gunicorn CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
Docker Compose (Local Development)
docker-compose.yml
version: '3.8'
services: api: build: context: . dockerfile: Dockerfile target: base ports: - "8000:8000" environment: - DATABASE_URL=postgresql://user:password@db:5432/appdb - REDIS_URL=redis://redis:6379/0 - ENVIRONMENT=development volumes: - .:/app depends_on: db: condition: service_healthy redis: condition: service_started command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
db: image: postgres:15 environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: appdb ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U user"] interval: 10s timeout: 5s retries: 5
redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data
nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - api
volumes: postgres_data: redis_data:
Deployment Strategies
Blue-Green Deployment
#!/bin/bash
deploy-blue-green.sh
set -e
BLUE_ENV="production-blue" GREEN_ENV="production-green" CURRENT_ENV=$(get_active_environment)
if [ "$CURRENT_ENV" == "$BLUE_ENV" ]; then TARGET_ENV="$GREEN_ENV" OLD_ENV="$BLUE_ENV" else TARGET_ENV="$BLUE_ENV" OLD_ENV="$GREEN_ENV" fi
echo "Deploying to $TARGET_ENV (current: $OLD_ENV)"
Deploy to target environment
deploy_to_environment "$TARGET_ENV"
Run smoke tests
if ! run_smoke_tests "$TARGET_ENV"; then echo "Smoke tests failed, rolling back" exit 1 fi
Switch traffic
switch_load_balancer "$TARGET_ENV"
Monitor for 5 minutes
monitor_environment "$TARGET_ENV" 300
If all good, keep old environment for quick rollback
echo "Deployment successful. Old environment $OLD_ENV kept for rollback."
Canary Deployment
k8s/canary-deployment.yaml
apiVersion: v1 kind: Service metadata: name: api-service spec: selector: app: api ports:
- port: 80 targetPort: 8000
Stable version (90% traffic)
apiVersion: apps/v1 kind: Deployment metadata: name: api-stable spec: replicas: 9 selector: matchLabels: app: api version: stable template: metadata: labels: app: api version: stable spec: containers: - name: api image: registry.example.com/api:v1.0.0
Canary version (10% traffic)
apiVersion: apps/v1 kind: Deployment metadata: name: api-canary spec: replicas: 1 selector: matchLabels: app: api version: canary template: metadata: labels: app: api version: canary spec: containers: - name: api image: registry.example.com/api:v1.1.0
Monitoring & Observability
Prometheus Configuration
prometheus.yml
global: scrape_interval: 15s evaluation_interval: 15s
scrape_configs:
-
job_name: 'api-service' kubernetes_sd_configs:
- role: pod relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app] action: keep regex: api
-
job_name: 'node-exporter' static_configs:
- targets: ['node-exporter:9100']
alerting: alertmanagers: - static_configs: - targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/alerts/*.yml
Alert Rules
alerts/api-alerts.yml
groups:
- name: api-alerts
interval: 30s
rules:
-
alert: HighErrorRate expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05 for: 5m labels: severity: critical annotations: summary: "High error rate detected" description: "{{ $labels.instance }} has error rate {{ $value }}"
-
alert: HighLatency expr: histogram_quantile(0.95, http_request_duration_seconds_bucket) > 1 for: 10m labels: severity: warning annotations: summary: "High latency detected" description: "95th percentile latency is {{ $value }}s"
-
alert: PodDown expr: up{job="api-service"} == 0 for: 2m labels: severity: critical annotations: summary: "Pod is down" description: "{{ $labels.instance }} has been down for 2 minutes"
-
Security Configuration
Network Security
security-groups.tf
ALB Security Group
resource "aws_security_group" "alb" { name_prefix = "${var.project_name}-alb-" vpc_id = module.vpc.vpc_id
ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTPS from internet" }
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }
Application Security Group
resource "aws_security_group" "app" { name_prefix = "${var.project_name}-app-" vpc_id = module.vpc.vpc_id
ingress { from_port = 8000 to_port = 8000 protocol = "tcp" security_groups = [aws_security_group.alb.id] description = "From ALB" }
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }
Database Security Group
resource "aws_security_group" "db" { name_prefix = "${var.project_name}-db-" vpc_id = module.vpc.vpc_id
ingress { from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = [aws_security_group.app.id] description = "From application" } }
Tool Access
Required tools:
-
Read : Read SPEC documents and ADRs
-
Write : Generate infrastructure and pipeline files
-
Bash : Execute Terraform, Docker, kubectl commands
-
Grep : Search for configuration patterns
Required software:
-
Terraform / OpenTofu
-
Docker / Podman
-
kubectl / helm
-
aws-cli / gcloud / az-cli
-
Ansible (optional)
Integration Points
With doc-flow
-
Extract infrastructure requirements from SPEC documents
-
Validate ADR compliance in infrastructure code
-
Generate deployment documentation
With security-audit
-
Security scanning of infrastructure code
-
Vulnerability assessment of containers
-
Compliance validation
With test-automation
-
Integration with CI/CD for automated testing
-
Deployment smoke tests
-
Infrastructure validation tests
With analytics-flow
-
Deployment metrics and trends
-
Infrastructure cost tracking
-
Performance monitoring integration
Best Practices
-
Infrastructure as Code: All infrastructure versioned in Git
-
Immutable infrastructure: Replace, don't modify
-
Environment parity: Dev/staging/prod consistency
-
Secret management: Never commit secrets
-
Monitoring from day one: Observability built-in
-
Automated rollbacks: Fast failure recovery
-
Cost optimization: Tag resources, monitor spending
-
Security by default: Least privilege, encryption
-
Documentation: Runbooks for common operations
-
Disaster recovery: Regular backup testing
Success Criteria
-
Zero manual infrastructure provisioning
-
Deployment time < 15 minutes
-
Rollback time < 5 minutes
-
Zero-downtime deployments
-
Infrastructure drift detection automated
-
Security compliance 100%
-
Cost variance < 10% from budget
Notes
-
Generated configurations require review before production use
-
Cloud provider credentials must be configured separately
-
State management (Terraform) requires backend configuration
-
Multi-region deployments require additional configuration
-
Cost estimation available with terraform plan