# Infrastructure as Code: Complete Overview

## What is Infrastructure as Code?

Infrastructure as Code (IaC) is the practice of managing and provisioning infrastructure through machine-readable definition files rather than manual processes or interactive tools.

**In the age of AI**, IaC becomes even more critical: AI assistants can only help manage infrastructure they can read and understand. Text-based IaC definitions are the interface through which AI collaborates on infrastructure.

## Why IaC Matters

### Traditional Infrastructure Problems

| Problem | Impact |
|---------|--------|
| Manual configuration drift | "Works on staging, broken on prod" |
| Tribal knowledge | "Only Alice knows how to set that up" |
| Slow provisioning | Hours/days to spin up new environments |
| No audit trail | "Who changed the firewall rules?" |
| Inconsistent environments | Dev doesn't match production |

### IaC Solutions

| Solution | Benefit |
|----------|---------|
| Version-controlled definitions | Full audit trail, rollback capability |
| Declarative specifications | Consistent, reproducible environments |
| Automated provisioning | Minutes instead of hours |
| Code review for infrastructure | Catch issues before deployment |
| AI-readable configurations | AI assistants can help manage infrastructure |

## IaC Tooling Landscape

### Recommended: Pulumi with Python

**Why Pulumi for this organization:**

1. **Python ecosystem** - Use existing skills, no new language (unlike Terraform's HCL)
2. **Type safety** - IDE autocomplete, mypy checking
3. **Testable** - Use pytest for infrastructure tests
4. **Full programming language** - Loops, conditions, abstractions
5. **AI-friendly** - Claude Code understands Python better than HCL

```python
# Example: Type-safe infrastructure with Python
import pulumi
import pulumi_aws as aws
from dataclasses import dataclass


@dataclass
class WebAppConfig:
    """Configuration for web application infrastructure."""
    environment: str
    instance_type: str
    min_instances: int
    max_instances: int


def create_web_app(config: WebAppConfig) -> aws.ecs.Service:
    """Create web application infrastructure.

    Args:
        config: Web app configuration

    Returns:
        ECS service resource
    """
    # Full type hints, testable, AI-readable
    cluster = aws.ecs.Cluster(f"web-{config.environment}")
    # ...
```

### Alternative Tools

| Tool | Best For | Trade-offs |
|------|----------|------------|
| **Terraform** | Multi-cloud, large teams | HCL learning curve, less testable |
| **CloudFormation** | AWS-only shops | AWS lock-in, verbose JSON/YAML |
| **CDK** | AWS + TypeScript teams | AWS-focused, complex abstractions |
| **Ansible** | Configuration management | Not declarative, state management |

## Core Components of IaC

### 1. Compute Infrastructure

Resources that run your code:

- **Containers**: Docker, ECS Fargate, Kubernetes
- **Functions**: AWS Lambda, Cloudflare Workers, Vercel Functions
- **VMs**: EC2, GCE (avoid when possible - prefer containers/functions)

See: [container-compute.md](./container-compute.md)

### 2. Storage Infrastructure

Resources that persist your data:

- **Object Storage**: S3, Cloudflare R2, GCS
- **Databases**: RDS, Supabase, PlanetScale
- **File Systems**: EFS, persistent volumes

See: [storage-infrastructure.md](./storage-infrastructure.md)

### 3. Networking Infrastructure

Resources that connect components:

- **DNS**: Cloudflare DNS, Route53
- **CDN**: Cloudflare, CloudFront
- **Load Balancers**: ALB, Cloudflare Load Balancing
- **VPCs**: Network isolation and security

See: [cloudflare.md](./cloudflare.md)

### 4. Configuration Infrastructure

Resources that configure your applications:

- **Environment Variables**: Per-environment configuration
- **Secrets**: API keys, database passwords
- **Feature Flags**: Runtime behavior toggles

See: [environment-variables.md](./environment-variables.md), [secrets-management.md](./secrets-management.md)

## IaC Workflow

### Standard Workflow

```
┌─────────────────┐
│  Write/Update   │
│   IaC Code      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   Code Review   │
│   (PR Process)  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Preview/Plan   │
│  (pulumi preview)│
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Cost Estimation │
│   (Infracost)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│     Deploy      │
│  (pulumi up)    │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│    Validate     │
│  (Tests/Checks) │
└─────────────────┘
```

### Commands

```bash
# Preview changes (always do this first)
pulumi preview

# Estimate costs
infracost breakdown --path .

# Deploy (after review)
pulumi up

# Check state
pulumi stack

# Destroy (careful!)
pulumi destroy
```

## Environment Strategy

### Recommended Environment Structure

```
                    ┌──────────────────┐
                    │    Production    │
                    │  (main branch)   │
                    └────────▲─────────┘
                             │
                    ┌────────┴─────────┐
                    │     Staging      │
                    │ (staging branch) │
                    └────────▲─────────┘
                             │
         ┌───────────────────┼───────────────────┐
         │                   │                   │
┌────────┴────────┐ ┌────────┴────────┐ ┌────────┴────────┐
│   Development   │ │    Sandbox      │ │    Preview      │
│  (local/shared) │ │ (experiments)   │ │  (per-PR)       │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```

See: [environment-isolation.md](./environment-isolation.md)

### Environment-Specific Configuration

```python
import pulumi

stack = pulumi.get_stack()

# Environment-specific sizing
ENVIRONMENT_CONFIG = {
    "dev": {
        "instance_type": "t3.micro",
        "min_instances": 1,
        "max_instances": 2,
        "database_size": "db.t3.micro",
        "enable_multi_az": False,
    },
    "staging": {
        "instance_type": "t3.small",
        "min_instances": 1,
        "max_instances": 3,
        "database_size": "db.t3.small",
        "enable_multi_az": False,
    },
    "production": {
        "instance_type": "t3.medium",
        "min_instances": 2,
        "max_instances": 10,
        "database_size": "db.t3.medium",
        "enable_multi_az": True,
    },
}

config = ENVIRONMENT_CONFIG[stack]
```

## Cost Management

### Pre-Deployment Cost Checks

**Required before any infrastructure deployment:**

```bash
# 1. Run cost estimation
infracost breakdown --path .

# 2. Compare with budget
pulumi config get monthlyBudget

# 3. Review significant changes
infracost diff --path . --compare-to infracost-base.json
```

### Resource Tagging

**All resources must be tagged:**

```python
def get_standard_tags() -> dict[str, str]:
    """Get standard resource tags."""
    return {
        "Environment": pulumi.get_stack(),
        "Project": pulumi.get_project(),
        "ManagedBy": "pulumi",
        "CostCenter": pulumi.Config().get("costCenter") or "engineering",
        "Owner": pulumi.Config().get("owner") or "platform-team",
    }
```

See: [financial-governance.md](./financial-governance.md), [cost-estimation.md](./cost-estimation.md)

## Hybrid Approaches

Real-world IaC often combines multiple tools:

### The Practical Stack

```
┌─────────────────────────────────────────────────────────┐
│                    justfile / Makefile                   │
│              (Orchestration layer - human interface)     │
└─────────────────────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
        ▼                     ▼                     ▼
┌───────────────┐   ┌─────────────────┐   ┌───────────────┐
│    Pulumi     │   │   Platform CLIs  │   │ Python Scripts│
│  (Core IaC)   │   │(vercel/supabase) │   │  (Automation) │
└───────────────┘   └─────────────────┘   └───────────────┘
```

See: [hybrid-iac-approaches.md](./hybrid-iac-approaches.md)

## AI-Assisted IaC

### What AI Can Help With

1. **Writing infrastructure code**
   ```
   "Add a new S3 bucket for user uploads with versioning and lifecycle rules"
   ```

2. **Reviewing changes**
   ```
   "Review this Pulumi PR for security issues and cost implications"
   ```

3. **Debugging issues**
   ```
   "Why is my ECS service failing to start?"
   ```

4. **Cost optimization**
   ```
   "Analyze our infrastructure and suggest cost savings"
   ```

5. **Migration planning**
   ```
   "Help me migrate from Heroku to AWS ECS"
   ```

### Making IaC AI-Friendly

**Best Practices:**

- Use descriptive resource names
- Add docstrings to component classes
- Comment non-obvious configurations
- Keep related resources together
- Use type hints everywhere
- Include cost estimates in comments

## Quick Reference

### Essential Commands

```bash
# Pulumi
pulumi preview          # Show planned changes
pulumi up               # Apply changes
pulumi stack            # Show current state
pulumi config set KEY VALUE  # Set config
pulumi config set --secret KEY  # Set secret

# Cost
infracost breakdown --path .

# Platform CLIs
vercel                  # Deploy to Vercel
supabase db push        # Push migrations
wrangler deploy         # Deploy Workers
```

### File Structure

```
infrastructure/
├── Pulumi.yaml              # Project config
├── Pulumi.dev.yaml          # Dev stack
├── Pulumi.staging.yaml      # Staging stack
├── Pulumi.production.yaml   # Production stack
├── __main__.py              # Entry point
├── components/              # Reusable components
│   ├── __init__.py
│   ├── web_service.py
│   └── database.py
├── policies/                # CrossGuard policies
└── tests/                   # Infrastructure tests
```

## Related Documentation

### Core Concepts
- [Configuration as Code](./configuration-as-code.md) - CaC philosophy
- [Environment Variables](./environment-variables.md) - Env var management
- [Environment Isolation](./environment-isolation.md) - Dev/staging/prod patterns
- [Secrets Management](./secrets-management.md) - Secure secret handling

### Platform Guides
- [Pulumi Guide](./pulumi-guide.md) - Python IaC implementation
- [Vercel](./vercel.md) - Next.js deployments
- [Supabase](./supabase.md) - PostgreSQL + Auth
- [Cloudflare](./cloudflare.md) - DNS, CDN, Workers
- [Netlify](./netlify.md) - JAMstack hosting

### Advanced Topics
- [Container Compute](./container-compute.md) - Docker, Fargate, FaaS
- [Storage Infrastructure](./storage-infrastructure.md) - S3, R2, databases
- [Database Migrations](./database-migrations.md) - Schema management
- [Hybrid IaC Approaches](./hybrid-iac-approaches.md) - Multi-tool workflows
- [Multi-Region Overview](./multi-region-overview.md) - HA patterns

### Cost Management
- [Financial Governance](./financial-governance.md) - Cost principles
- [Cost Estimation](./cost-estimation.md) - Pre-deployment checks
- [Budget Alerts](./budget-alerts.md) - Monitoring and alerts

---

**Key Takeaway**: Infrastructure as Code transforms infrastructure management from manual, error-prone processes into version-controlled, testable, AI-assistable code. Start with Pulumi for Python-native IaC, use platform CLIs for specialized services, and orchestrate everything through justfiles or similar tools.
