# {{STACK_NAME}} CDK Infrastructure

This directory contains the AWS CDK infrastructure code for deploying {{STACK_NAME}} to AWS.

## Overview

The CDK app uses the `RuntimeInfraStack` construct from `@worktif/runtime/infra` to provision all required AWS resources:

- **S3 Bucket**: Stores static assets and cached SSR responses
- **Lambda Function**: Handles server-side rendering of React components
- **CloudFront Distribution**: CDN for global content delivery
- **DynamoDB Table**: (Optional) Stores SEO metadata when `enableSeo` is true
- **IAM Roles**: Least-privilege permissions for Lambda execution

## Prerequisites

1. **AWS CLI**: Install and configure AWS CLI with your credentials
   ```bash
   aws configure
   ```

2. **Node.js**: Version 18 or higher

3. **AWS CDK**: Install globally (optional, can use npx)
   ```bash
   npm install -g aws-cdk
   ```

## Getting Started

**Good news!** If you initialized this CDK app using `runtime init`, all dependencies have already been installed automatically. You can skip directly to deployment!

### 1. Verify Installation (Already Done!)

During initialization, Runtime Web automatically:
- ✓ Installed all project dependencies (React, Runtime Web, etc.)
- ✓ Installed all CDK dependencies (aws-cdk-lib, constructs, etc.)
- ✓ Validated that all packages are correctly installed

If you need to reinstall dependencies manually:

```bash
# Install project dependencies (from project root)
cd ..
npm install

# Install CDK dependencies
cd cdk
npm install
```

### 2. Bootstrap CDK (First Time Only)

Bootstrap provisions the CDK toolkit resources in your AWS account:

```bash
cdk bootstrap
```

This only needs to be done once per AWS account/region combination.

**Note**: If you chose to run bootstrap during initialization, this step is already complete!

### 3. Deploy Infrastructure

Deploy to the default stage (dev):

```bash
cdk deploy --all
```

Deploy to a specific stage:

```bash
npm run deploy:dev      # Deploy to dev
npm run deploy:staging  # Deploy to staging
npm run deploy:prod     # Deploy to prod
```

### 4. View Deployment Outputs

After deployment, CDK will display important outputs:

- **CloudFront URL**: Your application's public URL
- **S3 Bucket Name**: Where static assets are stored
- **Lambda Function ARN**: The SSR handler function

## Configuration

### Main Configuration (bin/app.ts)

The CDK app is configured in `bin/app.ts`. Key properties:

- **stage**: Environment name (`dev`, `staging`, `prod`)
  - Affects resource naming and removal policies
  - Production stages have stricter retention policies

- **serviceName**: Identifier for your service
  - Used as prefix for all AWS resources
  - Example: `my-app` → `my-app-static-dev`, `my-app-ssr-handler-dev`

- **enableSeo**: Enable SEO features
  - Creates DynamoDB table for SEO metadata
  - Enables server-side rendering of meta tags

- **env.account**: AWS account ID
  - Defaults to `CDK_DEFAULT_ACCOUNT` environment variable
  - Can be hardcoded for specific environments

- **env.region**: AWS region
  - Resolved from AWS SDK default provider chain (AWS_REGION env var, ~/.aws/config)
  - Set to `{{REGION}}` during initialization based on your AWS configuration
  - Common values: `us-east-1`, `us-west-2`, `eu-west-1`, `eu-central-1`

### Optional Configuration

Uncomment these in `bin/app.ts` to customize:

```typescript
// Increase Lambda memory (default: 512 MB)
lambdaMemorySize: 1024,

// Increase Lambda timeout (default: 29 seconds)
lambdaTimeout: 60,

// Add custom environment variables
customEnvironmentVariables: {
  MY_API_KEY: 'value',
},

// Configure custom domain
domainName: 'example.com',
certificateArn: 'arn:aws:acm:...',
```

## Multiple Stages

To deploy multiple stages (dev, staging, prod), duplicate the stack instantiation in `bin/app.ts`:

```typescript
// Dev stage
new RuntimeInfraStack(app, `${serviceName}-dev`, {
  stage: 'dev',
  serviceName,
  enableSeo: true,
  env: { account: '...', region: '{{REGION}}' },
});

// Staging stage
new RuntimeInfraStack(app, `${serviceName}-staging`, {
  stage: 'staging',
  serviceName,
  enableSeo: true,
  env: { account: '...', region: '{{REGION}}' },
});

// Production stage
new RuntimeInfraStack(app, `${serviceName}-prod`, {
  stage: 'prod',
  serviceName,
  enableSeo: true,
  env: { account: '...', region: '{{REGION}}' },
});
```

## Useful Commands

- `npm run build`: Compile TypeScript to JavaScript
- `npm run watch`: Watch for changes and compile
- `cdk synth`: Synthesize CloudFormation template
- `cdk diff --all`: Compare deployed stack with current state
- `cdk deploy --all`: Deploy stack to AWS
- `cdk destroy`: Remove all resources (use with caution!)

## Troubleshooting

### "Unable to resolve AWS account"

**Problem**: CDK can't determine your AWS account ID.

**Solution**: Set environment variables or configure AWS CLI:
```bash
# Option 1: Set environment variables
export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
export AWS_REGION={{REGION}}

# Option 2: Configure AWS CLI (recommended)
aws configure set region {{REGION}}
```

### "Stack already exists"

**Problem**: A stack with the same name already exists.

**Solution**: CDK will update the existing stack. Use `cdk diff` to preview changes.

### "Insufficient permissions"

**Problem**: Your AWS credentials don't have required permissions.

**Solution**: Ensure your IAM user/role has permissions for:
- CloudFormation
- S3
- Lambda
- CloudFront
- DynamoDB (if enableSeo is true)
- IAM (for creating roles)

### "Lambda bundle not found"

**Problem**: The Lambda bundle hasn't been built.

**Solution**: Build your Runtime Web application first:
```bash
cd ..
npm run build
cd cdk
cdk deploy --all
```

### "Dependencies not installed"

**Problem**: CDK dependencies are missing or corrupted.

**Solution**:

If you initialized with `runtime init`, dependencies should already be installed. If you're experiencing issues:

```bash
# Reinstall project dependencies
cd ..
rm -rf node_modules package-lock.json
npm install

# Reinstall CDK dependencies
cd cdk
rm -rf node_modules package-lock.json
npm install
```

### "Package manager mismatch"

**Problem**: Different package managers used in project vs CDK directory.

**Solution**:

Runtime Web automatically detects your package manager (npm, yarn, or pnpm) and uses it consistently. If you need to switch:

```bash
# For npm
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
npm install

# For yarn
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
yarn install

# For pnpm
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
pnpm install
```

## Learn More

- [AWS CDK Documentation](https://docs.aws.amazon.com/cdk/)
- [Runtime Web Documentation](https://runtimeweb.com/docs)
- [RuntimeInfraStack API Reference](https://runtimeweb.com/docs/cdk)
