Files
spicy-automation/docs/VPC.md
Ryan Wilson 68684df471 Initial commit: Spicy CDK automation framework
Jenkins shared library and CDK constructs for AWS infrastructure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-18 22:21:00 -08:00

10 KiB

VPC Deployment Guide

Deploy production-ready VPCs with spicyVPC.

Minimal Setup

@Library(["spicy-automation@main"]) _

spicyVPC(
    jenkinsAwsCredentialsId: "aws-credentials",
    region: "ca-central-1",
    stackName: "my-vpc",
    ownerTag: "MyTeam",
    productTag: "myproduct",
    componentTag: "vpc",
)

This creates a VPC with all defaults - see What Gets Created.

Full Configuration

@Library(["spicy-automation@main"]) _

spicyVPC(
    // Required
    jenkinsAwsCredentialsId: "aws-credentials",
    region: "ca-central-1",
    stackName: "production-vpc",
    ownerTag: "Platform",
    productTag: "myapp",
    componentTag: "network",

    // Optional - VPC Configuration
    vpcCidr: "10.0.0.0/16",                    // Default: 172.1.0.0/16
    vpcTenancy: "default",                      // default | dedicated
    numberOfAzs: 4,                             // 2, 3, or 4
    availabilityZones: "ca-central-1a,ca-central-1b,ca-central-1c,ca-central-1d",

    // Optional - Subnet Creation
    createPrivateSubnets: true,                 // Default: true
    createAdditionalPrivateSubnets: true,       // Default: true (creates NACL-protected subnets)

    // Optional - Subnet Tags
    publicSubnetTag: "Network=Public",
    privateSubnetATag: "Network=Private",
    privateSubnetBTag: "Network=Private",

    // Optional - Custom CIDRs (see Custom CIDR Configuration below)

    // Optional - Pipeline Behavior
    showDiff: true,                             // Show diff before deploy (default: true)
    showDiffOnPR: true,                         // Show diff on non-main branches (default: true)

    // Optional - Hooks
    onPreDeploy: { args, ctx -> },              // Called before deployment
    onPostDeploy: { args, ctx -> },             // Called after deployment
)

Parameters Reference

Required Parameters

Parameter Type Description
jenkinsAwsCredentialsId string Jenkins credential ID for AWS access
region string AWS region (e.g., ca-central-1)
stackName string CloudFormation stack name (must be unique per account/region)
ownerTag string Owner tag applied to all resources
productTag string Product tag applied to all resources
componentTag string Component tag applied to all resources

VPC Configuration

Parameter Type Default Description
vpcCidr string 172.1.0.0/16 VPC CIDR block
vpcTenancy string default Instance tenancy (default or dedicated)
numberOfAzs number 4 Number of availability zones (2, 3, or 4)
availabilityZones string auto Comma-separated AZ list

Subnet Configuration

Parameter Type Default Description
createPrivateSubnets boolean true Create private subnets with NAT Gateways
createAdditionalPrivateSubnets boolean true Create secondary private subnets with NACLs

Subnet Tags

Parameter Type Default Description
publicSubnetTag string Network=Public Tag for public subnets
privateSubnetATag string Network=Private Tag for primary private subnets
privateSubnetBTag string Network=Private Tag for secondary private subnets

What Gets Created

With default settings, spicyVPC creates:

Network Resources

  • 1 VPC with DNS hostnames and DNS support enabled
  • 1 Internet Gateway attached to the VPC
  • DHCP Options configured for the region

Public Subnets (4 AZs)

  • 4 public subnets (one per AZ)
  • 1 shared public route table with route to Internet Gateway
  • Auto-assign public IP enabled

Private Subnets Type 1 (4 AZs)

  • 4 private subnets (one per AZ)
  • 4 NAT Gateways (one per AZ) with Elastic IPs
  • 4 route tables with routes to NAT Gateways

Private Subnets Type 2 (4 AZs)

  • 4 additional private subnets (one per AZ)
  • 4 Network ACLs (allow all by default, customizable)
  • 4 route tables with routes to NAT Gateways

VPC Endpoints

  • S3 Gateway Endpoint (free, attached to all private route tables)

Default CIDR Blocks

Subnet AZ A AZ B AZ C AZ D
Public 172.1.128.0/20 172.1.144.0/20 172.1.160.0/20 172.1.176.0/20
Private 1 172.1.0.0/19 172.1.32.0/19 172.1.64.0/19 172.1.96.0/19
Private 2 172.1.192.0/21 172.1.200.0/21 172.1.208.0/21 172.1.216.0/21

Custom CIDR Configuration

Override individual subnet CIDRs:

spicyVPC(
    // ... required params ...

    // Public subnets
    publicSubnetACidr: "10.0.0.0/20",
    publicSubnetBCidr: "10.0.16.0/20",
    publicSubnetCCidr: "10.0.32.0/20",
    publicSubnetDCidr: "10.0.48.0/20",

    // Private subnets (type 1)
    privateSubnetA1Cidr: "10.0.64.0/19",
    privateSubnetB1Cidr: "10.0.96.0/19",
    privateSubnetC1Cidr: "10.0.128.0/19",
    privateSubnetD1Cidr: "10.0.160.0/19",

    // Private subnets (type 2, with NACLs)
    privateSubnetA2Cidr: "10.0.192.0/21",
    privateSubnetB2Cidr: "10.0.200.0/21",
    privateSubnetC2Cidr: "10.0.208.0/21",
    privateSubnetD2Cidr: "10.0.216.0/21",
)

CloudFormation Outputs

The stack exports these values for cross-stack references:

Export Name Description
{stackName}-VPCID VPC ID
{stackName}-VPCCIDR VPC CIDR block
{stackName}-PublicSubnetAID Public Subnet A ID
{stackName}-PublicSubnetBID Public Subnet B ID
{stackName}-PublicSubnetCID Public Subnet C ID
{stackName}-PublicSubnetDID Public Subnet D ID
{stackName}-PrivateSubnetA1ID Private Subnet A1 ID
{stackName}-PrivateSubnetB1ID Private Subnet B1 ID
{stackName}-PrivateSubnetC1ID Private Subnet C1 ID
{stackName}-PrivateSubnetD1ID Private Subnet D1 ID
{stackName}-PrivateSubnetA2ID Private Subnet A2 ID
{stackName}-PrivateSubnetB2ID Private Subnet B2 ID
{stackName}-PrivateSubnetC2ID Private Subnet C2 ID
{stackName}-PrivateSubnetD2ID Private Subnet D2 ID
{stackName}-NATZoneAEIP NAT Gateway A Elastic IP
{stackName}-NATZoneBEIP NAT Gateway B Elastic IP
{stackName}-NATZoneCEIP NAT Gateway C Elastic IP
{stackName}-NATZoneDEIP NAT Gateway D Elastic IP
{stackName}-PublicSubnetRouteTable Public Route Table ID
{stackName}-PrivateSubnetA1RouteTable Private A1 Route Table ID
{stackName}-PrivateSubnetB1RouteTable Private B1 Route Table ID
{stackName}-PrivateSubnetC1RouteTable Private C1 Route Table ID
{stackName}-PrivateSubnetD1RouteTable Private D1 Route Table ID

Using Account Configurations

For multi-environment deployments:

@Library(["spicy-automation@main"]) _

def account = accounts.get().SPICY_CA_CENRAL_1_PROD

spicyVPC(
    jenkinsAwsCredentialsId: account.jenkinsAwsCredentialsId,
    region: account.region,
    accountId: account.accountId,
    stackName: "production-vpc",
    ownerTag: "Platform",
    productTag: "spicy",
    componentTag: "vpc",
)

Pipeline Hooks

Pre-Deploy Hook

spicyVPC(
    // ... params ...
    onPreDeploy: { args, ctx ->
        echo "About to deploy ${args.stackName}"
        // Run custom validation, notifications, etc.
    }
)

Post-Deploy Hook

spicyVPC(
    // ... params ...
    onPostDeploy: { args, ctx ->
        echo "Deployed stack: ${ctx.stackName}"
        // Update DNS, notify Slack, etc.
    }
)

Examples

Development VPC (2 AZs, No NACL Subnets)

spicyVPC(
    jenkinsAwsCredentialsId: "aws-dev",
    region: "ca-central-1",
    stackName: "dev-vpc",
    ownerTag: "Dev",
    productTag: "myapp",
    componentTag: "vpc",
    numberOfAzs: 2,
    createAdditionalPrivateSubnets: false,
)

Production VPC (Full HA)

spicyVPC(
    jenkinsAwsCredentialsId: "aws-prod",
    region: "ca-central-1",
    stackName: "prod-vpc",
    ownerTag: "Platform",
    productTag: "myapp",
    componentTag: "vpc",
    vpcCidr: "10.0.0.0/16",
    numberOfAzs: 4,
    createPrivateSubnets: true,
    createAdditionalPrivateSubnets: true,
)

Public-Only VPC (No NAT Gateways)

spicyVPC(
    jenkinsAwsCredentialsId: "aws-credentials",
    region: "ca-central-1",
    stackName: "public-vpc",
    ownerTag: "Dev",
    productTag: "myapp",
    componentTag: "vpc",
    createPrivateSubnets: false,
)

Local Testing

Test VPC synthesis locally:

cd spicy-automation

# Synthesize with minimal config
npx cdk synth \
  -c stackType=vpc \
  -c stackName=test-vpc \
  -c ownerTag=Test \
  -c productTag=test \
  -c componentTag=vpc

# With custom options
npx cdk synth \
  -c stackType=vpc \
  -c stackName=test-vpc \
  -c ownerTag=Test \
  -c productTag=test \
  -c componentTag=vpc \
  -c vpcCidr=10.0.0.0/16 \
  -c numberOfAzs=2 \
  -c createAdditionalPrivateSubnets=false