aws
cdk
vpc
cloud development
aws guide

How to import existing VPC in aws cdk?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

When you use AWS CDK with infrastructure that already exists, you usually do not recreate foundational network resources such as the VPC. Instead, you import the existing VPC into your stack so other constructs can attach to it.

In CDK, the two main approaches are Vpc.fromLookup and Vpc.fromVpcAttributes. fromLookup is the easiest when the VPC already exists in the target account and region, while fromVpcAttributes is better when you already know the IDs you want to supply explicitly.

Use Vpc.fromLookup for Existing Environments

fromLookup queries the AWS environment during synthesis and returns an IVpc that other constructs can use.

typescript
1import * as cdk from "aws-cdk-lib";
2import * as ec2 from "aws-cdk-lib/aws-ec2";
3
4export class NetworkConsumerStack extends cdk.Stack {
5  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
6    super(scope, id, props);
7
8    const vpc = ec2.Vpc.fromLookup(this, "ExistingVpc", {
9      vpcId: "vpc-0123456789abcdef0",
10    });
11
12    new ec2.SecurityGroup(this, "AppSecurityGroup", {
13      vpc,
14      allowAllOutbound: true,
15    });
16  }
17}

You can also look up by tags, name, or default VPC settings depending on what is stable in your environment.

Understand the Lookup Behavior

fromLookup happens at synthesis time, not deployment time. CDK stores the discovered values in context so later synth runs do not have to query AWS every time.

That means:

  • your AWS account and region must be configured correctly when you run cdk synth or cdk deploy
  • the lookup result may be cached in cdk.context.json
  • changing the target VPC may require clearing or refreshing context

If the lookup seems stale, run:

bash
cdk context --clear

Then synthesize again so CDK fetches fresh values.

This behavior surprises many people the first time they switch AWS profiles or regions, because the stack code did not change even though the environment did.

Use fromVpcAttributes When IDs Are Known

If you already know the VPC ID, subnet IDs, and availability zones, you can import them directly without a lookup:

typescript
1const vpc = ec2.Vpc.fromVpcAttributes(this, "ImportedVpc", {
2  vpcId: "vpc-0123456789abcdef0",
3  availabilityZones: ["us-east-1a", "us-east-1b"],
4  privateSubnetIds: ["subnet-aaa", "subnet-bbb"],
5  publicSubnetIds: ["subnet-ccc", "subnet-ddd"],
6});

This is useful in CI systems or multi-account setups where you want deterministic input values rather than live discovery.

What Importing a VPC Really Means

Importing does not put the VPC under CDK ownership. CDK can reference the VPC so other resources can be placed into it, but it will not start managing the VPC lifecycle itself.

For example, this is valid:

typescript
1new ec2.Instance(this, "AppInstance", {
2  vpc,
3  instanceType: new ec2.InstanceType("t3.micro"),
4  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
5  vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
6});

The EC2 instance is managed by CDK. The pre-existing VPC is not recreated or updated as part of that stack.

That separation is exactly what makes imports useful in brownfield AWS environments where networking is shared across many teams and stacks.

Common Pitfalls

  • Assuming import means CDK now owns and manages the existing VPC. It only references it.
  • Forgetting that fromLookup depends on the correct account and region during synthesis.
  • Being confused by stale context after a VPC change. Clear cdk.context.json or refresh context.
  • Using fromVpcAttributes without enough subnet information for downstream constructs.
  • Importing a VPC successfully but then selecting subnet types that do not actually exist in that environment.

Summary

  • Use Vpc.fromLookup when CDK can discover the existing VPC in the target environment.
  • Use Vpc.fromVpcAttributes when you want to provide IDs explicitly.
  • Imported VPCs are referenced by CDK, not owned by CDK.
  • Context caching is normal for lookups and may need to be refreshed.
  • Once imported, the VPC can be used by security groups, instances, load balancers, and other constructs.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.