# Deploy Infrastructure with Cost Checks

<!--
MAINTENANCE: Review pricing quarterly (March, June, September, December)
Last reviewed: 2025-01
Next review: 2025-04
-->

## Purpose

Deploy cloud infrastructure using Pulumi with integrated cost estimation and budget validation.

## Prompt Template

```
I need to deploy the following infrastructure with cost checks:

**Infrastructure**:
{INFRASTRUCTURE_DESCRIPTION}

**Stack**: {STACK_NAME} (dev/staging/production)

**Budget Limit**: ${BUDGET_LIMIT}/month

**Requirements**:
1. Estimate costs before deployment
2. Validate against budget limit
3. Set up budget alerts at 50%, 80%, 100%
4. Tag all resources with:
   - Environment: {ENVIRONMENT}
   - CostCenter: {COST_CENTER}
   - Owner: {OWNER}
5. Deploy infrastructure
6. Verify deployment successful
7. Configure monitoring

**Pre-deployment checks**:
- [ ] Cost estimate within budget
- [ ] All required tags configured
- [ ] Budget alerts configured
- [ ] Policies passing (no expensive instances in dev/staging)

**Post-deployment checks**:
- [ ] All resources deployed successfully
- [ ] Monitoring configured
- [ ] Budget alerts active
- [ ] Access verified

**Additional requirements**:
{OPTIONAL_REQUIREMENTS}
```

## Variables

- `{INFRASTRUCTURE_DESCRIPTION}`: Describe what you're deploying (e.g., "Supabase database + Vercel frontend + Cloudflare CDN")
- `{STACK_NAME}`: Pulumi stack name (dev, staging, production)
- `{BUDGET_LIMIT}`: Maximum monthly cost allowed
- `{ENVIRONMENT}`: Environment tag value
- `{COST_CENTER}`: Cost center for tracking (e.g., "engineering")
- `{OWNER}`: Team or person responsible
- `{OPTIONAL_REQUIREMENTS}`: Any special requirements (compliance, regions, etc.)

## Example Usage

**Input**:
```
I need to deploy the following infrastructure with cost checks:

**Infrastructure**:
- Supabase Pro database (PostgreSQL)
- Vercel Pro frontend hosting (Next.js)
- Cloudflare Workers for API
- Cloudflare R2 for file storage

**Stack**: production

**Budget Limit**: $100/month

**Requirements**:
1. Estimate costs before deployment
2. Validate against budget limit
3. Set up budget alerts at 50%, 80%, 100%
4. Tag all resources with:
   - Environment: production
   - CostCenter: engineering
   - Owner: platform-team
5. Deploy infrastructure
6. Verify deployment successful
7. Configure monitoring

**Pre-deployment checks**:
- [ ] Cost estimate within budget
- [ ] All required tags configured
- [ ] Budget alerts configured
- [ ] Policies passing (no expensive instances in dev/staging)

**Post-deployment checks**:
- [ ] All resources deployed successfully
- [ ] Monitoring configured
- [ ] Budget alerts active
- [ ] Access verified

**Additional requirements**:
- Database must use US East region
- Enable daily backups with 30-day retention
- Configure row-level security
```

**Expected Output**:

```
# Infrastructure Deployment with Cost Checks

## Step 1: Cost Estimation

### Running Infracost

```bash
# Install Infracost (if not already installed)
curl -fsSL https://raw.githubusercontent.com/infracost/infracost/master/scripts/install.sh | sh

# Generate cost estimate
cd infrastructure/
infracost breakdown --path . --format json --out-file infracost.json
```

### Cost Estimate Results

```json
{
  "projects": [{
    "breakdown": {
      "resources": [
        {
          "name": "supabase_project",
          "hourlyCost": "0.034",
          "monthlyCost": "25.00",
          "costComponents": [
            {"name": "Pro plan base", "monthlyCost": "25.00"}
          ]
        },
        {
          "name": "vercel_project",
          "hourlyCost": "0.027",
          "monthlyCost": "20.00"
        },
        {
          "name": "cloudflare_workers",
          "hourlyCost": "0.007",
          "monthlyCost": "5.00"
        },
        {
          "name": "cloudflare_r2",
          "hourlyCost": "0.007",
          "monthlyCost": "5.00"
        }
      ],
      "totalMonthlyCost": "55.00"
    }
  }]
}
```

**Estimated monthly cost**: $55/month
**Budget limit**: $100/month
**Within budget**: ✅ Yes (55% of budget)

## Step 2: Configure Infrastructure

### infrastructure/__main__.py

```python
import pulumi
import pulumi_cloudflare as cloudflare
from dataclasses import dataclass

@dataclass
class AppConfig:
    stack: str
    environment: str
    monthly_budget: int
    cost_center: str
    owner: str

    @classmethod
    def from_pulumi_config(cls):
        config = pulumi.Config()
        stack = pulumi.get_stack()
        return cls(
            stack=stack,
            environment=stack,  # dev/staging/production
            monthly_budget=config.require_int("monthlyBudget"),
            cost_center=config.get("costCenter") or "engineering",
            owner=config.get("owner") or "platform-team",
        )

# Load configuration
app_config = AppConfig.from_pulumi_config()

# Standard tags for all resources
def get_default_tags():
    return {
        "Environment": app_config.environment,
        "CostCenter": app_config.cost_center,
        "Owner": app_config.owner,
        "ManagedBy": "pulumi",
        "Project": pulumi.get_project(),
    }

# Supabase (via API - no Pulumi provider yet)
# Configure via supabase CLI or Dashboard
# Estimated cost: $25/month (Pro plan)

# Vercel (via API or CLI)
# Configure via vercel CLI or Dashboard
# Estimated cost: $20/month (Pro plan)

# Cloudflare R2 Bucket
r2_bucket = cloudflare.R2Bucket(
    "uploads",
    account_id=pulumi.Config("cloudflare").require("accountId"),
    name=f"{pulumi.get_project()}-uploads-{app_config.stack}",
)

# Cloudflare Workers
worker_script = cloudflare.WorkerScript(
    "api",
    account_id=pulumi.Config("cloudflare").require("accountId"),
    name=f"{pulumi.get_project()}-api-{app_config.stack}",
    content=open("workers/api.js").read(),
)

# Export outputs
pulumi.export("r2_bucket_name", r2_bucket.name)
pulumi.export("worker_name", worker_script.name)
pulumi.export("environment", app_config.environment)
pulumi.export("estimated_monthly_cost", 55)  # From Infracost
pulumi.export("budget_limit", app_config.monthly_budget)
```

### Pulumi.production.yaml

```yaml
config:
  monthlyBudget: 100
  costCenter: engineering
  owner: platform-team
  cloudflare:accountId: xxx
```

## Step 3: Pre-Deployment Validation

### Run cost check script

```bash
python scripts/check_cost_threshold.py
```

Output:
```
Estimated monthly cost: $55.00
Budget threshold: $100.00
✓ Cost estimate within budget
```

### Verify tags configured

```python
# All resources have required tags:
# - Environment: production
# - CostCenter: engineering
# - Owner: platform-team
# - ManagedBy: pulumi
✅ Tags verified
```

### Run Pulumi preview

```bash
pulumi preview
```

Output:
```
Previewing update (production)

     Type                             Name                    Plan
 +   pulumi:pulumi:Stack               infra-production       create
 +   ├─ cloudflare:index:R2Bucket     uploads                create
 +   └─ cloudflare:index:WorkerScript api                    create

Resources:
    + 3 to create

Outputs:
    + r2_bucket_name: "my-app-uploads-production"
    + worker_name: "my-app-api-production"

Estimated monthly cost: $55.00
```

✅ Pre-deployment checks passed

## Step 4: Deploy Infrastructure

```bash
pulumi up
```

Output:
```
Updating (production)

     Type                             Name                    Status
 +   pulumi:pulumi:Stack               infra-production       created
 +   ├─ cloudflare:index:R2Bucket     uploads                created
 +   └─ cloudflare:index:WorkerScript api                    created

Outputs:
    r2_bucket_name: "my-app-uploads-production"
    worker_name: "my-app-api-production"
    environment: "production"
    estimated_monthly_cost: 55
    budget_limit: 100

Resources:
    + 3 created

Duration: 12s
```

✅ Deployment successful

## Step 5: Configure Budget Alerts

### Supabase

**Configure in Supabase Dashboard:**
1. Go to Organization Settings > Billing
2. Set spending limit: $30/month
3. Enable email notifications at 80%

### Vercel

**Configure in Vercel Dashboard:**
1. Go to Team Settings > Billing > Usage Limits
2. Set maximum spending: $25/month
3. Enable alerts at $20

### Cloudflare

**No built-in budget alerts - set up monitoring script:**

```python
# scripts/check_cloudflare_usage.py
import requests
import os

CLOUDFLARE_TOKEN = os.getenv("CLOUDFLARE_TOKEN")
ACCOUNT_ID = os.getenv("CLOUDFLARE_ACCOUNT_ID")

# Monitor Workers usage
response = requests.get(
    f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/workers/usage",
    headers={"Authorization": f"Bearer {CLOUDFLARE_TOKEN}"},
)

usage = response.json()
requests_this_month = usage.get("requests", 0)

# Alert if approaching limit
if requests_this_month > 8_000_000:  # 80% of 10M included
    print(f"WARNING: Workers at {requests_this_month:,} requests (80% of limit)")
```

**Schedule monitoring:**

```bash
# Add to crontab
0 9 * * * cd ~/infrastructure && python scripts/check_cloudflare_usage.py
```

## Step 6: Configure Monitoring

### Health checks

```bash
# Verify Cloudflare Worker deployed
curl https://api.example.com/health

# Verify R2 bucket accessible
wrangler r2 bucket list
```

### Set up logging

```javascript
// workers/api.js
export default {
  async fetch(request, env, ctx) {
    console.log('Request:', {
      url: request.url,
      method: request.method,
    })

    // ... handler logic
  }
}
```

### Monitor via Cloudflare Dashboard

- Workers > Analytics (requests, duration, errors)
- R2 > Metrics (storage, operations, bandwidth)

## Step 7: Post-Deployment Verification

### Checklist

- [x] All resources deployed successfully
- [x] Cost estimate: $55/month (within $100 budget)
- [x] Budget alerts configured:
  - Supabase: $30 limit
  - Vercel: $25 limit
  - Cloudflare: Custom monitoring script
- [x] Monitoring configured:
  - Cloudflare Analytics enabled
  - Custom health checks added
- [x] Tags applied:
  - Environment: production
  - CostCenter: engineering
  - Owner: platform-team
- [x] Access verified:
  - Worker endpoint responding
  - R2 bucket accessible

### Summary

✅ **Deployment complete**

**Infrastructure deployed:**
- Cloudflare R2 bucket for file storage
- Cloudflare Worker for API
- Supabase database (configured separately)
- Vercel frontend (configured separately)

**Cost management:**
- Estimated monthly cost: $55
- Budget limit: $100
- Budget utilization: 55%
- Alerts configured at 50%, 80%, 100%

**Next steps:**
1. Configure Supabase database schema
2. Deploy Vercel frontend
3. Set up CI/CD pipeline
4. Monitor costs weekly
```

## Tips

- **Always run cost estimation first**: Never deploy without knowing the cost
- **Use preview before up**: Review changes before committing
- **Set conservative budget limits**: Leave 20-30% buffer for unexpected usage
- **Tag everything**: Cost allocation requires consistent tagging
- **Monitor from day one**: Don't wait for the first bill to arrive
- **Document estimates in code**: Future you will thank you
- **Test in dev first**: Validate infrastructure in dev before production
- **Automate budget checks**: Integrate into CI/CD pipeline

## Tags

#infrastructure #deployment #cost-management #pulumi
