Migration GuideΒΆ

Guide for migrating existing VPC infrastructure to be managed by the VPC Provisioner.

Table of ContentsΒΆ

Migrating from Manual VPC SetupΒΆ

Step 1: Inventory Existing InfrastructureΒΆ

Export your current VPC configuration for reference:

# Export VPC details
aws ec2 describe-vpcs --vpc-ids vpc-xxxxx > existing-vpc.json

# Export subnets
aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'Subnets[].{Name:Tags[?Key==`Name`].Value|[0],SubnetId:SubnetId,CIDR:CidrBlock,AZ:AvailabilityZone,Public:MapPublicIpOnLaunch}' \
  --output table

# Export route tables
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-xxxxx" > existing-routes.json

# Export NAT Gateways
aws ec2 describe-nat-gateways \
  --filter "Name=vpc-id,Values=vpc-xxxxx" > existing-nat.json

# Export Internet Gateway
aws ec2 describe-internet-gateways \
  --filters "Name=attachment.vpc-id,Values=vpc-xxxxx" > existing-igw.json

# Export security groups
aws ec2 describe-security-groups \
  --filters "Name=vpc-id,Values=vpc-xxxxx" > existing-sgs.json

Step 2: Create Equivalent ConfigurationΒΆ

Map your existing infrastructure to a VPC Provisioner YAML configuration:

client:
  company_name: Your Company
  company_prefix: yourco
  account_id: "123456789012"
  tenant_id: "a001"

environment:
  env: prod
  region: us-west-2

vpc:
  vpc_name_override: ""
  cidr_block: 10.0.0.0/16          # Match existing VPC CIDR
  availability_zones:
    - us-west-2a                     # Match existing AZs
    - us-west-2b
  subnets:
    public:                          # Map existing public subnets
      - name: public-subnet-1
        cidr: 10.0.1.0/24
        az: us-west-2a
      - name: public-subnet-2
        cidr: 10.0.2.0/24
        az: us-west-2b
    private:                         # Map existing private subnets
      - name: private-app-subnet-1
        cidr: 10.0.11.0/24
        az: us-west-2a
      - name: private-app-subnet-2
        cidr: 10.0.12.0/24
        az: us-west-2b
    database:                        # Map existing database subnets
      - name: database-subnet-1
        cidr: 10.0.21.0/26
        az: us-west-2a
      - name: database-subnet-2
        cidr: 10.0.22.0/26
        az: us-west-2b
  internet_gateway:
    enabled: true                    # Match existing IGW
  nat_gateway:
    enabled: true                    # Match existing NAT
    high_availability: true          # Match existing HA setup

tags:
  Environment: production
  MigratedFrom: manual

Step 3: Validate ConfigurationΒΆ

docker run --rm \
  -v ~/.aws:/home/vpcuser/.aws:ro \
  -v $(pwd)/vpc/configs:/app/configs:ro \
  -v $(pwd)/vpc/reports:/app/reports \
  vpc-provisioner:latest \
  --config yourco-prod-a001-us-west-2-vpc.yaml \
  --action validate-config

Step 4: Deploy New VPC in ParallelΒΆ

Deploy the new VPC with a different CIDR block to avoid conflicts:

vpc:
  cidr_block: 10.1.0.0/16  # Different from existing 10.0.0.0/16
docker run --rm \
  -v ~/.aws:/home/vpcuser/.aws:ro \
  -v $(pwd)/vpc/configs:/app/configs:ro \
  -v $(pwd)/vpc/templates:/app/templates \
  -v $(pwd)/vpc/reports:/app/reports \
  vpc-provisioner:latest \
  --config yourco-prod-a001-us-west-2-vpc.yaml \
  --action create-vpc \
  --force

Step 5: Test New VPCΒΆ

  • Deploy a test workload in the new VPC

  • Verify connectivity (internet, cross-AZ, AWS services)

  • Test NAT Gateway and routing

  • Verify security group rules work as expected

Step 6: Migrate WorkloadsΒΆ

Options for gradual migration:

VPC Peering (simplest):

# Create peering connection between old and new VPC
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-old \
  --peer-vpc-id vpc-new

Transit Gateway (multi-VPC):

  • Attach both VPCs to a Transit Gateway

  • Route traffic between them during migration

  • Remove old VPC attachment after migration

Blue-Green (safest):

  • Deploy identical workloads in new VPC

  • Switch DNS/load balancer to new VPC

  • Monitor for issues

  • Decommission old VPC after validation period

Step 7: Decommission Old VPCΒΆ

After all workloads are migrated and validated:

# Verify no resources remain in old VPC
aws ec2 describe-instances \
  --filters "Name=vpc-id,Values=vpc-old" \
  --query 'Reservations[].Instances[].InstanceId'

# Delete old VPC manually (not managed by CloudFormation)
# Remove resources in dependency order:
# 1. EC2 instances
# 2. NAT Gateways (wait for deletion)
# 3. Elastic IPs
# 4. Route table associations
# 5. Route tables
# 6. Internet Gateway detach + delete
# 7. Subnets
# 8. Security groups
# 9. VPC

Migrating from TerraformΒΆ

Step 1: Export Terraform StateΒΆ

# List resources in Terraform state
terraform state list

# Export VPC details
terraform state show aws_vpc.main
terraform state show aws_subnet.public[0]
terraform state show aws_nat_gateway.main

Step 2: Map to YAML ConfigurationΒΆ

Translate Terraform resource attributes to VPC Provisioner YAML:

Terraform

VPC Provisioner YAML

aws_vpc.cidr_block

vpc.cidr_block

aws_subnet.cidr_block

subnets.public[].cidr

aws_subnet.availability_zone

subnets.public[].az

aws_nat_gateway exists

nat_gateway.enabled: true

aws_internet_gateway exists

internet_gateway.enabled: true

Step 3: Deploy and MigrateΒΆ

Follow Steps 3-7 from the manual migration above.

Step 4: Remove from Terraform StateΒΆ

After migration, remove old resources from Terraform state to prevent accidental deletion:

terraform state rm aws_vpc.main
terraform state rm aws_subnet.public
# ... remove all VPC-related resources

Migrating from AWS CDKΒΆ

Step 1: Review Synthesized TemplateΒΆ

cdk synth > existing-template.yaml

Step 2: Map to YAML ConfigurationΒΆ

Review the CloudFormation template and map resources to VPC Provisioner YAML. Focus on:

  • VPC CIDR block

  • Subnet CIDRs and AZs

  • NAT Gateway configuration

  • Internet Gateway

  • Route tables

Step 3: Deploy and MigrateΒΆ

Follow Steps 3-7 from the manual migration above.

Step 4: Destroy CDK StackΒΆ

After migration, destroy the CDK stack:

cdk destroy

Parallel Deployment StrategyΒΆ

For zero-downtime migration, run old and new VPCs in parallel:

Week 1: Deploy new VPC, test connectivity
Week 2: Migrate non-critical workloads
Week 3: Migrate critical workloads
Week 4: Monitor, validate, decommission old VPC

Important: Use different CIDR blocks to avoid IP conflicts. If you need the same CIDR, you must decommission the old VPC first.

Rollback ProceduresΒΆ

CloudFormation Automatic RollbackΒΆ

If deployment fails, CloudFormation automatically rolls back all resources:

# Check stack events for failure reason
aws cloudformation describe-stack-events \
  --stack-name yourco-prod-a001-us-west-2-vpc-stack \
  --query 'StackEvents[?ResourceStatus==`CREATE_FAILED`].[LogicalResourceId,ResourceStatusReason]' \
  --output table

Manual RollbackΒΆ

If you need to revert after a successful deployment:

# Delete the new VPC stack
docker run --rm \
  -v ~/.aws:/home/vpcuser/.aws:ro \
  -v $(pwd)/vpc/configs:/app/configs:ro \
  -v $(pwd)/vpc/reports:/app/reports \
  vpc-provisioner:latest \
  --config yourco-prod-a001-us-west-2-vpc.yaml \
  --action delete-vpc \
  --force

Your old VPC remains untouched β€” the VPC Provisioner only manages resources it created.

Workload RollbackΒΆ

If workloads were migrated:

  1. Switch DNS/load balancer back to old VPC

  2. Verify old VPC workloads are still running

  3. Delete new VPC when ready