Skip to content
v2.273.0

Amazon EC2 Construct Library ​

The aws-cdk-lib/aws-ec2 package contains primitives for setting up networking and instances.

ts
import * as ec2 from 'aws-cdk-lib/aws-ec2';
python
import aws_cdk.aws_ec2 as ec2
java
import software.amazon.awscdk.services.ec2.*;
csharp
using Amazon.CDK.AWS.EC2;
go
import ec2 "github.com/aws/aws-cdk-go/awscdk"

VPC ​

Most projects need a Virtual Private Cloud to provide security by means of network partitioning. This is achieved by creating an instance of Vpc:

ts
const vpc = new ec2.Vpc(this, 'VPC');
python
vpc = ec2.Vpc(self, "VPC")
java
Vpc vpc = new Vpc(this, "VPC");
csharp
var vpc = new Vpc(this, "VPC");
go
vpc := ec2.NewVpc(this, jsii.String("VPC"))

All default constructs require EC2 instances to be launched inside a VPC, so you should generally start by defining a VPC whenever you need to launch instances for your project.

Subnet Types ​

A VPC consists of one or more subnets that instances can be placed into. CDK distinguishes three different subnet types:

  • Public (SubnetType.PUBLIC) - public subnets connect directly to the Internet using an Internet Gateway. If you want your instances to have a public IP address and be directly reachable from the Internet, you must place them in a public subnet.
  • Private with Internet Access (SubnetType.PRIVATE_WITH_EGRESS) - instances in private subnets are not directly routable from the Internet, and you must provide a way to connect out to the Internet. By default, a NAT gateway is created in every public subnet for maximum availability. Be aware that you will be charged for NAT gateways. Alternatively you can set natGateways:0 and provide your own egress configuration (i.e through Transit Gateway)
  • Isolated (SubnetType.PRIVATE_ISOLATED) - isolated subnets do not route from or to the Internet, and as such do not require NAT gateways. They can only connect to or be connected to from other instances in the same VPC. A default VPC configuration will not include isolated subnets,

A default VPC configuration will create public and private subnets. However, if natGateways:0 and subnetConfiguration is undefined, default VPC configuration will create public and isolated subnets. See Advanced Subnet Configuration below for information on how to change the default subnet configuration.

Constructs using the VPC will "launch instances" (or more accurately, create Elastic Network Interfaces) into one or more of the subnets. They all accept a property called subnetSelection (sometimes called vpcSubnets) to allow you to select in what subnet to place the ENIs, usually defaulting to private subnets if the property is omitted.

If you would like to save on the cost of NAT gateways, you can use isolated subnets instead of private subnets (as described in Advanced Subnet Configuration). If you need private instances to have internet connectivity, another option is to reduce the number of NAT gateways created by setting the natGateways property to a lower value (the default is one NAT gateway per availability zone). Be aware that this may have availability implications for your application.

Read more about subnets.

Control over availability zones ​

By default, a VPC will spread over at most 3 Availability Zones available to it. To change the number of Availability Zones that the VPC will spread over, specify the maxAzs property when defining it.

The number of Availability Zones that are available depends on the region and account of the Stack containing the VPC. If the region and account are specified on the Stack, the CLI will look up the existing Availability Zones and get an accurate count. The result of this operation will be written to a file called cdk.context.json. You must commit this file to source control so that the lookup values are available in non-privileged environments such as CI build steps, and to ensure your template builds are repeatable.

If region and account are not specified, the stack could be deployed anywhere and it will have to make a safe choice, limiting itself to 2 Availability Zones.

Therefore, to get the VPC to spread over 3 or more availability zones, you must specify the environment where the stack will be deployed.

You can gain full control over the availability zones selection strategy by overriding the Stack's get availabilityZones() method:

text
// This example is only available in TypeScript

class MyStack extends Stack {

  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // ...
  }

  get availabilityZones(): string[] {
    return ['us-west-2a', 'us-west-2b'];
  }

}

Note that overriding the get availabilityZones() method will override the default behavior for all constructs defined within the Stack.

Choosing subnets for resources ​

When creating resources that create Elastic Network Interfaces (such as databases or instances), there is an option to choose which subnets to place them in. For example, a VPC endpoint by default is placed into a subnet in every availability zone, but you can override which subnets to use. The property is typically called one of subnets, vpcSubnets or subnetSelection.

The example below will place the endpoint into two AZs (us-east-1a and us-east-1c), in Isolated subnets:

ts
declare const vpc: ec2.Vpc;

new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', {
  vpc,
  service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443),
  subnets: {
    subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
    availabilityZones: ['us-east-1a', 'us-east-1c']
  }
});
python
# vpc: ec2.Vpc


ec2.InterfaceVpcEndpoint(self, "VPC Endpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    subnets=ec2.SubnetSelection(
        subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
        availability_zones=["us-east-1a", "us-east-1c"]
    )
)
java
Vpc vpc;


InterfaceVpcEndpoint.Builder.create(this, "VPC Endpoint")
        .vpc(vpc)
        .service(new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443))
        .subnets(SubnetSelection.builder()
                .subnetType(SubnetType.PRIVATE_ISOLATED)
                .availabilityZones(List.of("us-east-1a", "us-east-1c"))
                .build())
        .build();
csharp
Vpc vpc;


new InterfaceVpcEndpoint(this, "VPC Endpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    Subnets = new SubnetSelection {
        SubnetType = SubnetType.PRIVATE_ISOLATED,
        AvailabilityZones = new [] { "us-east-1a", "us-east-1c" }
    }
});
go
var vpc Vpc


ec2.NewInterfaceVpcEndpoint(this, jsii.String("VPC Endpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.NewInterfaceVpcEndpointService(jsii.String("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc"), jsii.Number(443)),
	Subnets: &SubnetSelection{
		SubnetType: ec2.SubnetType_PRIVATE_ISOLATED,
		AvailabilityZones: []*string{
			jsii.String("us-east-1a"),
			jsii.String("us-east-1c"),
		},
	},
})

You can also specify specific subnet objects for granular control:

ts
declare const vpc: ec2.Vpc;
declare const subnet1: ec2.Subnet;
declare const subnet2: ec2.Subnet;

new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', {
  vpc,
  service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443),
  subnets: {
    subnets: [subnet1, subnet2]
  }
});
python
# vpc: ec2.Vpc
# subnet1: ec2.Subnet
# subnet2: ec2.Subnet


ec2.InterfaceVpcEndpoint(self, "VPC Endpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    subnets=ec2.SubnetSelection(
        subnets=[subnet1, subnet2]
    )
)
java
Vpc vpc;
Subnet subnet1;
Subnet subnet2;


InterfaceVpcEndpoint.Builder.create(this, "VPC Endpoint")
        .vpc(vpc)
        .service(new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443))
        .subnets(SubnetSelection.builder()
                .subnets(List.of(subnet1, subnet2))
                .build())
        .build();
csharp
Vpc vpc;
Subnet subnet1;
Subnet subnet2;


new InterfaceVpcEndpoint(this, "VPC Endpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    Subnets = new SubnetSelection {
        Subnets = new [] { subnet1, subnet2 }
    }
});
go
var vpc Vpc
var subnet1 Subnet
var subnet2 Subnet


ec2.NewInterfaceVpcEndpoint(this, jsii.String("VPC Endpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.NewInterfaceVpcEndpointService(jsii.String("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc"), jsii.Number(443)),
	Subnets: &SubnetSelection{
		Subnets: []ISubnet{
			subnet1,
			subnet2,
		},
	},
})

Which subnets are selected is evaluated as follows:

  • subnets: if specific subnet objects are supplied, these are selected, and no other logic is used.
  • subnetType/subnetGroupName: otherwise, a set of subnets is selected by supplying either type or name:
    • subnetType will select all subnets of the given type.
    • subnetGroupName should be used to distinguish between multiple groups of subnets of the same type (for example, you may want to separate your application instances and your RDS instances into two distinct groups of Isolated subnets).
    • If neither are given, the first available subnet group of a given type that exists in the VPC will be used, in this order: Private, then Isolated, then Public. In short: by default ENIs will preferentially be placed in subnets not connected to the Internet.
  • availabilityZones/onePerAz: finally, some availability-zone based filtering may be done. This filtering by availability zones will only be possible if the VPC has been created or looked up in a non-environment agnostic stack (so account and region have been set and availability zones have been looked up).
    • availabilityZones: only the specific subnets from the selected subnet groups that are in the given availability zones will be returned.
    • onePerAz: per availability zone, a maximum of one subnet will be returned (Useful for resource types that do not allow creating two ENIs in the same availability zone).
  • subnetFilters: additional filtering on subnets using any number of user-provided filters which extend SubnetFilter. The following methods on the SubnetFilter class can be used to create a filter:
    • byIds: chooses subnets from a list of ids
    • availabilityZones: chooses subnets in the provided list of availability zones
    • onePerAz: chooses at most one subnet per availability zone
    • containsIpAddresses: chooses a subnet which contains any of the listed ip addresses
    • byCidrMask: chooses subnets that have the provided CIDR netmask
    • byCidrRanges: chooses subnets which are inside any of the specified CIDR ranges

Using Regional NAT Gateways ​

Regional NAT Gateways provide automatic multi-AZ redundancy with a single gateway that scales across availability zones. Unlike zonal NAT gateways, a regional NAT gateway does not require public subnets and is created at the VPC level.

ts
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
new ec2.Vpc(this, 'Vpc', {
  natGatewayProvider: ec2.NatProvider.regionalGateway(),
});
python
# Basic usage
# Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
ec2.Vpc(self, "Vpc",
    nat_gateway_provider=ec2.NatProvider.regional_gateway()
)
java
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
Vpc.Builder.create(this, "Vpc")
        .natGatewayProvider(NatProvider.regionalGateway())
        .build();
csharp
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
new Vpc(this, "Vpc", new VpcProps {
    NatGatewayProvider = NatProvider.RegionalGateway()
});
go
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
// Basic usage
// Creates a single Regional NAT Gateway for the VPC and automatically allocate Elastic IPs
ec2.NewVpc(this, jsii.String("Vpc"), &VpcProps{
	NatGatewayProvider: ec2.NatProvider_RegionalGateway(),
})

You can specify an existing EIP from a CfnEIP resource or an allocation ID:

ts
const eip = new ec2.CfnEIP(this, 'NatEip');

new ec2.Vpc(this, 'Vpc1', {
  natGatewayProvider: ec2.NatProvider.regionalGateway({
    eip,
  }),
});

new ec2.Vpc(this, 'Vpc2', {
  natGatewayProvider: ec2.NatProvider.regionalGateway({
    allocationId: eip.attrAllocationId,
  }),
});
python
eip = ec2.CfnEIP(self, "NatEip")

ec2.Vpc(self, "Vpc1",
    nat_gateway_provider=ec2.NatProvider.regional_gateway(
        eip=eip
    )
)

ec2.Vpc(self, "Vpc2",
    nat_gateway_provider=ec2.NatProvider.regional_gateway(
        allocation_id=eip.attr_allocation_id
    )
)
java
CfnEIP eip = new CfnEIP(this, "NatEip");

Vpc.Builder.create(this, "Vpc1")
        .natGatewayProvider(NatProvider.regionalGateway(RegionalNatGatewayProviderProps.builder()
                .eip(eip)
                .build()))
        .build();

Vpc.Builder.create(this, "Vpc2")
        .natGatewayProvider(NatProvider.regionalGateway(RegionalNatGatewayProviderProps.builder()
                .allocationId(eip.getAttrAllocationId())
                .build()))
        .build();
csharp
var eip = new CfnEIP(this, "NatEip");

new Vpc(this, "Vpc1", new VpcProps {
    NatGatewayProvider = NatProvider.RegionalGateway(new RegionalNatGatewayProviderProps {
        Eip = eip
    })
});

new Vpc(this, "Vpc2", new VpcProps {
    NatGatewayProvider = NatProvider.RegionalGateway(new RegionalNatGatewayProviderProps {
        AllocationId = eip.AttrAllocationId
    })
});
go
eip := ec2.NewCfnEIP(this, jsii.String("NatEip"))

ec2.NewVpc(this, jsii.String("Vpc1"), &VpcProps{
	NatGatewayProvider: ec2.NatProvider_RegionalGateway(&RegionalNatGatewayProviderProps{
		Eip: *Eip,
	}),
})

ec2.NewVpc(this, jsii.String("Vpc2"), &VpcProps{
	NatGatewayProvider: ec2.NatProvider_*RegionalGateway(&RegionalNatGatewayProviderProps{
		AllocationId: eip.attrAllocationId,
	}),
})

For manual control over AZ coverage and EIP allocation, use availabilityZoneAddresses:

ts
const eip1 = new ec2.CfnEIP(this, 'NatEip1');
const eip2 = new ec2.CfnEIP(this, 'NatEip2');

new ec2.Vpc(this, 'Vpc', {
  availabilityZones: ['us-east-1a', 'us-east-1b'],
  natGatewayProvider: ec2.NatProvider.regionalGateway({
    availabilityZoneAddresses: [
      { allocationIds: [eip1.attrAllocationId], availabilityZone: 'us-east-1a' },
      { allocationIds: [eip2.attrAllocationId], availabilityZone: 'us-east-1b' },
    ],
  }),
});
python
eip1 = ec2.CfnEIP(self, "NatEip1")
eip2 = ec2.CfnEIP(self, "NatEip2")

ec2.Vpc(self, "Vpc",
    availability_zones=["us-east-1a", "us-east-1b"],
    nat_gateway_provider=ec2.NatProvider.regional_gateway(
        availability_zone_addresses=[ec2.AvailabilityZoneAddress(allocation_ids=[eip1.attr_allocation_id], availability_zone="us-east-1a"), ec2.AvailabilityZoneAddress(allocation_ids=[eip2.attr_allocation_id], availability_zone="us-east-1b")
        ]
    )
)
java
CfnEIP eip1 = new CfnEIP(this, "NatEip1");
CfnEIP eip2 = new CfnEIP(this, "NatEip2");

Vpc.Builder.create(this, "Vpc")
        .availabilityZones(List.of("us-east-1a", "us-east-1b"))
        .natGatewayProvider(NatProvider.regionalGateway(RegionalNatGatewayProviderProps.builder()
                .availabilityZoneAddresses(List.of(AvailabilityZoneAddress.builder().allocationIds(List.of(eip1.getAttrAllocationId())).availabilityZone("us-east-1a").build(), AvailabilityZoneAddress.builder().allocationIds(List.of(eip2.getAttrAllocationId())).availabilityZone("us-east-1b").build()))
                .build()))
        .build();
csharp
var eip1 = new CfnEIP(this, "NatEip1");
var eip2 = new CfnEIP(this, "NatEip2");

new Vpc(this, "Vpc", new VpcProps {
    AvailabilityZones = new [] { "us-east-1a", "us-east-1b" },
    NatGatewayProvider = NatProvider.RegionalGateway(new RegionalNatGatewayProviderProps {
        AvailabilityZoneAddresses = new [] { new AvailabilityZoneAddress { AllocationIds = new [] { eip1.AttrAllocationId }, AvailabilityZone = "us-east-1a" }, new AvailabilityZoneAddress { AllocationIds = new [] { eip2.AttrAllocationId }, AvailabilityZone = "us-east-1b" } }
    })
});
go
eip1 := ec2.NewCfnEIP(this, jsii.String("NatEip1"))
eip2 := ec2.NewCfnEIP(this, jsii.String("NatEip2"))

ec2.NewVpc(this, jsii.String("Vpc"), &VpcProps{
	AvailabilityZones: []*string{
		jsii.String("us-east-1a"),
		jsii.String("us-east-1b"),
	},
	NatGatewayProvider: ec2.NatProvider_RegionalGateway(&RegionalNatGatewayProviderProps{
		AvailabilityZoneAddresses: []AvailabilityZoneAddress{
			&AvailabilityZoneAddress{
				AllocationIds: []*string{
					eip1.attrAllocationId,
				},
				AvailabilityZone: jsii.String("us-east-1a"),
			},
			&AvailabilityZoneAddress{
				AllocationIds: []*string{
					eip2.attrAllocationId,
				},
				AvailabilityZone: jsii.String("us-east-1b"),
			},
		},
	}),
})

Each Availability Zone may only appear once in availabilityZoneAddresses.

In this manual mode the gateway only serves the listed Availability Zones and does not expand to other zones automatically, so every Availability Zone that contains a private subnet must be listed. When the zone names are known at synthesis time, a private subnet in an unlisted zone is rejected with an error. Entries that use availabilityZoneId or unresolved tokens cannot be checked at synthesis time.

The natGateways property is ignored when using a Regional NAT Gateway, since a single gateway already covers every Availability Zone. Values below 1, as well as unresolved tokens, are rejected because they would silently disable the gateway you explicitly configured; omit natGatewayProvider instead if you do not want a NAT gateway.

You can also configure the maximum drain duration:

ts
new ec2.Vpc(this, 'Vpc', {
  natGatewayProvider: ec2.NatProvider.regionalGateway({
    maxDrainDuration: Duration.minutes(10),
  }),
});
python
ec2.Vpc(self, "Vpc",
    nat_gateway_provider=ec2.NatProvider.regional_gateway(
        max_drain_duration=Duration.minutes(10)
    )
)
java
Vpc.Builder.create(this, "Vpc")
        .natGatewayProvider(NatProvider.regionalGateway(RegionalNatGatewayProviderProps.builder()
                .maxDrainDuration(Duration.minutes(10))
                .build()))
        .build();
csharp
new Vpc(this, "Vpc", new VpcProps {
    NatGatewayProvider = NatProvider.RegionalGateway(new RegionalNatGatewayProviderProps {
        MaxDrainDuration = Duration.Minutes(10)
    })
});
go
ec2.NewVpc(this, jsii.String("Vpc"), &VpcProps{
	NatGatewayProvider: ec2.NatProvider_RegionalGateway(&RegionalNatGatewayProviderProps{
		MaxDrainDuration: awscdk.Duration_Minutes(jsii.Number(10)),
	}),
})

Using NAT instances ​

By default, the Vpc construct will create NAT gateways for you, which are managed by AWS. If you would prefer to use your own managed NAT instances instead, specify a different value for the natGatewayProvider property, as follows:

The construct will automatically selects the latest version of Amazon Linux 2023. If you prefer to use a custom AMI, use machineImage: MachineImage.genericLinux({ ... }) and configure the right AMI ID for the regions you want to deploy to.

Warning The NAT instances created using this method will be unmonitored. They are not part of an Auto Scaling Group, and if they become unavailable or are terminated for any reason, will not be restarted or replaced.

By default, the NAT instances will route all traffic. To control what traffic gets routed, pass a custom value for defaultAllowedTraffic and access the NatInstanceProvider.connections member after having passed the NAT provider to the VPC:

ts
declare const instanceType: ec2.InstanceType;

const provider = ec2.NatProvider.instanceV2({
  instanceType,
  defaultAllowedTraffic: ec2.NatTrafficDirection.OUTBOUND_ONLY,
});
new ec2.Vpc(this, 'TheVPC', {
  natGatewayProvider: provider,
});
provider.connections.allowFrom(ec2.Peer.ipv4('1.2.3.4/8'), ec2.Port.HTTP);
python
# instance_type: ec2.InstanceType


provider = ec2.NatProvider.instance_v2(
    instance_type=instance_type,
    default_allowed_traffic=ec2.NatTrafficDirection.OUTBOUND_ONLY
)
ec2.Vpc(self, "TheVPC",
    nat_gateway_provider=provider
)
provider.connections.allow_from(ec2.Peer.ipv4("1.2.3.4/8"), ec2.Port.HTTP)
java
InstanceType instanceType;


NatInstanceProviderV2 provider = NatProvider.instanceV2(NatInstanceProps.builder()
        .instanceType(instanceType)
        .defaultAllowedTraffic(NatTrafficDirection.OUTBOUND_ONLY)
        .build());
Vpc.Builder.create(this, "TheVPC")
        .natGatewayProvider(provider)
        .build();
provider.connections.allowFrom(Peer.ipv4("1.2.3.4/8"), Port.HTTP);
csharp
InstanceType instanceType;


var provider = NatProvider.InstanceV2(new NatInstanceProps {
    InstanceType = instanceType,
    DefaultAllowedTraffic = NatTrafficDirection.OUTBOUND_ONLY
});
new Vpc(this, "TheVPC", new VpcProps {
    NatGatewayProvider = provider
});
provider.Connections.AllowFrom(Peer.Ipv4("1.2.3.4/8"), Port.HTTP);
go
var instanceType InstanceType


provider := ec2.NatProvider_InstanceV2(&NatInstanceProps{
	InstanceType: InstanceType,
	DefaultAllowedTraffic: ec2.NatTrafficDirection_OUTBOUND_ONLY,
})
ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	NatGatewayProvider: provider,
})
provider.connections.AllowFrom(ec2.Peer_Ipv4(jsii.String("1.2.3.4/8")), ec2.Port_HTTP())

You can also customize the characteristics of your NAT instances, including their security group, as well as their initialization scripts:

ts
declare const bucket: s3.Bucket;

const userData = ec2.UserData.forLinux();
userData.addCommands(
  ...ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS,
  'echo "hello world!" > hello.txt',
  `aws s3 cp hello.txt s3://${bucket.bucketName}`,
);

const provider = ec2.NatProvider.instanceV2({
  instanceType: new ec2.InstanceType('t3.small'),
  creditSpecification: ec2.CpuCredits.UNLIMITED,
  defaultAllowedTraffic: ec2.NatTrafficDirection.NONE,
});

const vpc = new ec2.Vpc(this, 'TheVPC', {
  natGatewayProvider: provider,
  natGateways: 2,
});

const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', { vpc });
    securityGroup.addEgressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443));
for (const gateway of provider.gatewayInstances) {
  bucket.grants.write(gateway);
  gateway.addSecurityGroup(securityGroup);
}
python
# bucket: s3.Bucket


user_data = ec2.UserData.for_linux()
user_data.add_commands(
    (SpreadElement ...ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS
      ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS), "echo \"hello world!\" > hello.txt", f"aws s3 cp hello.txt s3://{bucket.bucketName}")

provider = ec2.NatProvider.instance_v2(
    instance_type=ec2.InstanceType("t3.small"),
    credit_specification=ec2.CpuCredits.UNLIMITED,
    default_allowed_traffic=ec2.NatTrafficDirection.NONE
)

vpc = ec2.Vpc(self, "TheVPC",
    nat_gateway_provider=provider,
    nat_gateways=2
)

security_group = ec2.SecurityGroup(self, "SecurityGroup", vpc=vpc)
security_group.add_egress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(443))
for gateway in provider.gateway_instances:
    bucket.grants.write(gateway)
    gateway.add_security_group(security_group)
java
Bucket bucket;


UserData userData = UserData.forLinux();
userData.addCommands(
(SpreadElement ...ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS
  NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS), "echo \"hello world!\" > hello.txt", String.format("aws s3 cp hello.txt s3://%s", bucket.getBucketName()));

NatInstanceProviderV2 provider = NatProvider.instanceV2(NatInstanceProps.builder()
        .instanceType(new InstanceType("t3.small"))
        .creditSpecification(CpuCredits.UNLIMITED)
        .defaultAllowedTraffic(NatTrafficDirection.NONE)
        .build());

Vpc vpc = Vpc.Builder.create(this, "TheVPC")
        .natGatewayProvider(provider)
        .natGateways(2)
        .build();

SecurityGroup securityGroup = SecurityGroup.Builder.create(this, "SecurityGroup").vpc(vpc).build();
securityGroup.addEgressRule(Peer.anyIpv4(), Port.tcp(443));
for (Object gateway : provider.getGatewayInstances()) {
    bucket.grants.write(gateway);
    gateway.addSecurityGroup(securityGroup);
}
csharp
Bucket bucket;


var userData = UserData.ForLinux();
userData.AddCommands(
(SpreadElement ...ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS
  NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS), "echo \"hello world!\" > hello.txt", $"aws s3 cp hello.txt s3://{bucket.bucketName}");

var provider = NatProvider.InstanceV2(new NatInstanceProps {
    InstanceType = new InstanceType("t3.small"),
    CreditSpecification = CpuCredits.UNLIMITED,
    DefaultAllowedTraffic = NatTrafficDirection.NONE
});

var vpc = new Vpc(this, "TheVPC", new VpcProps {
    NatGatewayProvider = provider,
    NatGateways = 2
});

var securityGroup = new SecurityGroup(this, "SecurityGroup", new SecurityGroupProps { Vpc = vpc });
securityGroup.AddEgressRule(Peer.AnyIpv4(), Port.Tcp(443));
for (var gateway in provider.GatewayInstances)
{
    bucket.Grants.Write(gateway);
    gateway.AddSecurityGroup(securityGroup);
}
go
var bucket Bucket


userData := ec2.UserData_ForLinux()
userData.AddCommands(
(SpreadElement ...ec2.NatInstanceProviderV2.DEFAULT_USER_DATA_COMMANDS
		ec2.NatInstanceProviderV2_DEFAULT_USER_DATA_COMMANDS()), jsii.String("echo \"hello world!\" > hello.txt"),
fmt.Sprintf("aws s3 cp hello.txt s3://%v", bucket.bucketName))

provider := ec2.NatProvider_InstanceV2(&NatInstanceProps{
	InstanceType: ec2.NewInstanceType(jsii.String("t3.small")),
	CreditSpecification: ec2.CpuCredits_UNLIMITED,
	DefaultAllowedTraffic: ec2.NatTrafficDirection_NONE,
})

vpc := ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	NatGatewayProvider: provider,
	NatGateways: jsii.Number(2),
})

securityGroup := ec2.NewSecurityGroup(this, jsii.String("SecurityGroup"), &SecurityGroupProps{
	Vpc: Vpc,
})
securityGroup.AddEgressRule(ec2.Peer_AnyIpv4(), ec2.Port_Tcp(jsii.Number(443)))
for _, gateway := range provider.gatewayInstances {
	bucket.grants.Write(gateway)
	gateway.AddSecurityGroup(securityGroup)
}
ts
    // Configure the `natGatewayProvider` when defining a Vpc
    const natGatewayProvider = ec2.NatProvider.instance({
      instanceType: new ec2.InstanceType('t3.small'),
    });

    const vpc = new ec2.Vpc(this, 'MyVpc', {
      natGatewayProvider,

      // The 'natGateways' parameter now controls the number of NAT instances
      natGateways: 2,
    });
python
# Configure the `natGatewayProvider` when defining a Vpc
nat_gateway_provider = ec2.NatProvider.instance(
    instance_type=ec2.InstanceType("t3.small")
)

vpc = ec2.Vpc(self, "MyVpc",
    nat_gateway_provider=nat_gateway_provider,

    # The 'natGateways' parameter now controls the number of NAT instances
    nat_gateways=2
)
java
// Configure the `natGatewayProvider` when defining a Vpc
NatInstanceProvider natGatewayProvider = NatProvider.instance(NatInstanceProps.builder()
        .instanceType(new InstanceType("t3.small"))
        .build());

Vpc vpc = Vpc.Builder.create(this, "MyVpc")
        .natGatewayProvider(natGatewayProvider)

        // The 'natGateways' parameter now controls the number of NAT instances
        .natGateways(2)
        .build();
csharp
// Configure the `natGatewayProvider` when defining a Vpc
var natGatewayProvider = NatProvider.Instance(new NatInstanceProps {
    InstanceType = new InstanceType("t3.small")
});

var vpc = new Vpc(this, "MyVpc", new VpcProps {
    NatGatewayProvider = natGatewayProvider,

    // The 'natGateways' parameter now controls the number of NAT instances
    NatGateways = 2
});
go
// Configure the `natGatewayProvider` when defining a Vpc
natGatewayProvider := ec2.NatProvider_Instance(&NatInstanceProps{
	InstanceType: ec2.NewInstanceType(jsii.String("t3.small")),
})

vpc := ec2.NewVpc(this, jsii.String("MyVpc"), &VpcProps{
	NatGatewayProvider: NatGatewayProvider,

	// The 'natGateways' parameter now controls the number of NAT instances
	NatGateways: jsii.Number(2),
})

The V1 NatProvider.instance construct will use the AWS official NAT instance AMI, which has already reached EOL on Dec 31, 2023. For more information, see the following blog post: Amazon Linux AMI end of life.

ts
declare const instanceType: ec2.InstanceType;

const provider = ec2.NatProvider.instance({
  instanceType,
  defaultAllowedTraffic: ec2.NatTrafficDirection.OUTBOUND_ONLY,
});
new ec2.Vpc(this, 'TheVPC', {
  natGatewayProvider: provider,
});
provider.connections.allowFrom(ec2.Peer.ipv4('1.2.3.4/8'), ec2.Port.HTTP);
python
# instance_type: ec2.InstanceType


provider = ec2.NatProvider.instance(
    instance_type=instance_type,
    default_allowed_traffic=ec2.NatTrafficDirection.OUTBOUND_ONLY
)
ec2.Vpc(self, "TheVPC",
    nat_gateway_provider=provider
)
provider.connections.allow_from(ec2.Peer.ipv4("1.2.3.4/8"), ec2.Port.HTTP)
java
InstanceType instanceType;


NatInstanceProvider provider = NatProvider.instance(NatInstanceProps.builder()
        .instanceType(instanceType)
        .defaultAllowedTraffic(NatTrafficDirection.OUTBOUND_ONLY)
        .build());
Vpc.Builder.create(this, "TheVPC")
        .natGatewayProvider(provider)
        .build();
provider.connections.allowFrom(Peer.ipv4("1.2.3.4/8"), Port.HTTP);
csharp
InstanceType instanceType;


var provider = NatProvider.Instance(new NatInstanceProps {
    InstanceType = instanceType,
    DefaultAllowedTraffic = NatTrafficDirection.OUTBOUND_ONLY
});
new Vpc(this, "TheVPC", new VpcProps {
    NatGatewayProvider = provider
});
provider.Connections.AllowFrom(Peer.Ipv4("1.2.3.4/8"), Port.HTTP);
go
var instanceType InstanceType


provider := ec2.NatProvider_Instance(&NatInstanceProps{
	InstanceType: InstanceType,
	DefaultAllowedTraffic: ec2.NatTrafficDirection_OUTBOUND_ONLY,
})
ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	NatGatewayProvider: provider,
})
provider.connections.AllowFrom(ec2.Peer_Ipv4(jsii.String("1.2.3.4/8")), ec2.Port_HTTP())

Associate Public IP Address to NAT Instance ​

You can choose to associate public IP address to a NAT instance V2 by specifying associatePublicIpAddress like the following:

ts
const natGatewayProvider = ec2.NatProvider.instanceV2({
  instanceType: new ec2.InstanceType('t3.small'),
  associatePublicIpAddress: true,
});
python
nat_gateway_provider = ec2.NatProvider.instance_v2(
    instance_type=ec2.InstanceType("t3.small"),
    associate_public_ip_address=True
)
java
NatInstanceProviderV2 natGatewayProvider = NatProvider.instanceV2(NatInstanceProps.builder()
        .instanceType(new InstanceType("t3.small"))
        .associatePublicIpAddress(true)
        .build());
csharp
var natGatewayProvider = NatProvider.InstanceV2(new NatInstanceProps {
    InstanceType = new InstanceType("t3.small"),
    AssociatePublicIpAddress = true
});
go
natGatewayProvider := ec2.NatProvider_InstanceV2(&NatInstanceProps{
	InstanceType: ec2.NewInstanceType(jsii.String("t3.small")),
	AssociatePublicIpAddress: jsii.Boolean(true),
})

In certain scenarios where the public subnet has set mapPublicIpOnLaunch to false, NAT instances does not get public IP addresses assigned which would result in non-working NAT instance as NAT instance requires a public IP address to enable outbound internet connectivity. Users can specify associatePublicIpAddress to true to solve this problem.

Ip Address Management ​

The VPC spans a supernet IP range, which contains the non-overlapping IPs of its contained subnets. Possible sources for this IP range are:

  • You specify an IP range directly by specifying a CIDR
  • You allocate an IP range of a given size automatically from AWS IPAM

By default the Vpc will allocate the 10.0.0.0/16 address range which will be exhaustively spread across all subnets in the subnet configuration. This behavior can be changed by passing an object that implements IIpAddresses to the ipAddress property of a Vpc. See the subsequent sections for the options.

Be aware that if you don't explicitly reserve subnet groups in subnetConfiguration, the address space will be fully allocated! If you predict you may need to add more subnet groups later, add them early on and set reserved: true (see the "Advanced Subnet Configuration" section for more information).

Specifying a CIDR directly ​

Use IpAddresses.cidr to define a Cidr range for your Vpc directly in code:

ts
import { IpAddresses } from 'aws-cdk-lib/aws-ec2';

new ec2.Vpc(this, 'TheVPC', {
  ipAddresses: IpAddresses.cidr('10.0.1.0/20')
});
python
from aws_cdk.aws_ec2 import IpAddresses


ec2.Vpc(self, "TheVPC",
    ip_addresses=IpAddresses.cidr("10.0.1.0/20")
)
java
import software.amazon.awscdk.services.ec2.IpAddresses;


Vpc.Builder.create(this, "TheVPC")
        .ipAddresses(IpAddresses.cidr("10.0.1.0/20"))
        .build();
csharp
using Amazon.CDK.AWS.EC2;


new Vpc(this, "TheVPC", new VpcProps {
    IpAddresses = IpAddresses.Cidr("10.0.1.0/20")
});
go
import "github.com/aws/aws-cdk-go/awscdk"


ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	IpAddresses: awscdk.IpAddresses_Cidr(jsii.String("10.0.1.0/20")),
})

Space will be allocated to subnets in the following order:

  • First, spaces is allocated for all subnets groups that explicitly have a cidrMask set as part of their configuration (including reserved subnets).
  • Afterwards, any remaining space is divided evenly between the rest of the subnets (if any).

The argument to IpAddresses.cidr may not be a token, and concrete Cidr values are generated in the synthesized CloudFormation template.

Allocating an IP range from AWS IPAM ​

Amazon VPC IP Address Manager (IPAM) manages a large IP space, from which chunks can be allocated for use in the Vpc. For information on Amazon VPC IP Address Manager please see the official documentation. An example of allocating from AWS IPAM looks like this:

ts
import { IpAddresses } from 'aws-cdk-lib/aws-ec2';

declare const pool: ec2.CfnIPAMPool;

new ec2.Vpc(this, 'TheVPC', {
  ipAddresses: IpAddresses.awsIpamAllocation({
    ipv4IpamPoolId: pool.ref,
    ipv4NetmaskLength: 18,
    defaultSubnetIpv4NetmaskLength: 24
  })
});
python
from aws_cdk.aws_ec2 import IpAddresses

# pool: ec2.CfnIPAMPool


ec2.Vpc(self, "TheVPC",
    ip_addresses=IpAddresses.aws_ipam_allocation(
        ipv4_ipam_pool_id=pool.ref,
        ipv4_netmask_length=18,
        default_subnet_ipv4_netmask_length=24
    )
)
java
import software.amazon.awscdk.services.ec2.IpAddresses;

CfnIPAMPool pool;


Vpc.Builder.create(this, "TheVPC")
        .ipAddresses(IpAddresses.awsIpamAllocation(AwsIpamProps.builder()
                .ipv4IpamPoolId(pool.getRef())
                .ipv4NetmaskLength(18)
                .defaultSubnetIpv4NetmaskLength(24)
                .build()))
        .build();
csharp
using Amazon.CDK.AWS.EC2;

CfnIPAMPool pool;


new Vpc(this, "TheVPC", new VpcProps {
    IpAddresses = IpAddresses.AwsIpamAllocation(new AwsIpamProps {
        Ipv4IpamPoolId = pool.Ref,
        Ipv4NetmaskLength = 18,
        DefaultSubnetIpv4NetmaskLength = 24
    })
});
go
import "github.com/aws/aws-cdk-go/awscdk"

var pool CfnIPAMPool


ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	IpAddresses: awscdk.IpAddresses_AwsIpamAllocation(&AwsIpamProps{
		Ipv4IpamPoolId: pool.ref,
		Ipv4NetmaskLength: jsii.Number(18),
		DefaultSubnetIpv4NetmaskLength: jsii.Number(24),
	}),
})

IpAddresses.awsIpamAllocation requires the following:

  • ipv4IpamPoolId, the id of an IPAM Pool from which the VPC range should be allocated.
  • ipv4NetmaskLength, the size of the IP range that will be requested from the Pool at deploy time.
  • defaultSubnetIpv4NetmaskLength, the size of subnets in groups that don't have cidrMask set.

With this method of IP address management, no attempt is made to guess at subnet group sizes or to exhaustively allocate the IP range. All subnet groups must have an explicit cidrMask set as part of their subnet configuration, or defaultSubnetIpv4NetmaskLength must be set for a default size. If not, synthesis will fail and you must provide one or the other.

Dual Stack configuration ​

To allocate both IPv4 and IPv6 addresses in your VPC, you can configure your VPC to have a dual stack protocol.

ts
new ec2.Vpc(this, 'DualStackVpc', {
  ipProtocol: ec2.IpProtocol.DUAL_STACK,
})
python
ec2.Vpc(self, "DualStackVpc",
    ip_protocol=ec2.IpProtocol.DUAL_STACK
)
java
Vpc.Builder.create(this, "DualStackVpc")
        .ipProtocol(IpProtocol.DUAL_STACK)
        .build();
csharp
new Vpc(this, "DualStackVpc", new VpcProps {
    IpProtocol = IpProtocol.DUAL_STACK
});
go
ec2.NewVpc(this, jsii.String("DualStackVpc"), &VpcProps{
	IpProtocol: ec2.IpProtocol_DUAL_STACK,
})

By default, a dual stack VPC will create an Amazon provided IPv6 /56 CIDR block associated to the VPC. It will then assign /64 portions of the block to each subnet. For each subnet, auto-assigning an IPv6 address will be enabled, and auto-asigning a public IPv4 address will be disabled. An egress only internet gateway will be created for PRIVATE_WITH_EGRESS subnets, and IPv6 routes will be added for IGWs and EIGWs.

Disabling the auto-assigning of a public IPv4 address by default can avoid the cost of public IPv4 addresses starting 2/1/2024. For use cases that need an IPv4 address, the mapPublicIpOnLaunch property in subnetConfiguration can be set to auto-assign the IPv4 address. Note that private IPv4 address allocation will not be changed.

See Advanced Subnet Configuration for all IPv6 specific properties.

Reserving availability zones ​

There are situations where the IP space for availability zones will need to be reserved. This is useful in situations where availability zones would need to be added after the vpc is originally deployed, without causing IP renumbering for availability zones subnets. The IP space for reserving n availability zones can be done by setting the reservedAzs to n in vpc props, as shown below:

ts
const vpc = new ec2.Vpc(this, 'TheVPC', {
  cidr: '10.0.0.0/21',
  maxAzs: 3,
  reservedAzs: 1,
});
python
vpc = ec2.Vpc(self, "TheVPC",
    cidr="10.0.0.0/21",
    max_azs=3,
    reserved_azs=1
)
java
Vpc vpc = Vpc.Builder.create(this, "TheVPC")
        .cidr("10.0.0.0/21")
        .maxAzs(3)
        .reservedAzs(1)
        .build();
csharp
var vpc = new Vpc(this, "TheVPC", new VpcProps {
    Cidr = "10.0.0.0/21",
    MaxAzs = 3,
    ReservedAzs = 1
});
go
vpc := ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	Cidr: jsii.String("10.0.0.0/21"),
	MaxAzs: jsii.Number(3),
	ReservedAzs: jsii.Number(1),
})

In the example above, the subnets for reserved availability zones is not actually provisioned but its IP space is still reserved. If, in the future, new availability zones needs to be provisioned, then we would decrement the value of reservedAzs and increment the maxAzs or availabilityZones accordingly. This action would not cause the IP address of subnets to get renumbered, but rather the IP space that was previously reserved will be used for the new availability zones subnets.

Advanced Subnet Configuration ​

If the default VPC configuration (public and private subnets spanning the size of the VPC) don't suffice for you, you can configure what subnets to create by specifying the subnetConfiguration property. It allows you to configure the number and size of all subnets. Specifying an advanced subnet configuration could look like this:

ts
const vpc = new ec2.Vpc(this, 'TheVPC', {
  // 'IpAddresses' configures the IP range and size of the entire VPC.
  // The IP space will be divided based on configuration for the subnets.
  ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/21'),

  // 'maxAzs' configures the maximum number of availability zones to use.
  // If you want to specify the exact availability zones you want the VPC
  // to use, use `availabilityZones` instead.
  maxAzs: 3,

  // 'subnetConfiguration' specifies the "subnet groups" to create.
  // Every subnet group will have a subnet for each AZ, so this
  // configuration will create `3 groups × 3 AZs = 9` subnets.
  subnetConfiguration: [
    {
      // 'subnetType' controls Internet access, as described above.
      subnetType: ec2.SubnetType.PUBLIC,

      // 'name' is used to name this particular subnet group. You will have to
      // use the name for subnet selection if you have more than one subnet
      // group of the same type.
      name: 'Ingress',

      // 'cidrMask' specifies the IP addresses in the range of individual
      // subnets in the group. Each of the subnets in this group will contain
      // `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
      // usable IP addresses.
      //
      // If 'cidrMask' is left out the available address space is evenly
      // divided across the remaining subnet groups.
      cidrMask: 24,
    },
    {
      cidrMask: 24,
      name: 'Application',
      subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
    },
    {
      cidrMask: 28,
      name: 'Database',
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,

      // 'reserved' can be used to reserve IP address space. No resources will
      // be created for this subnet, but the IP range will be kept available for
      // future creation of this subnet, or even for future subdivision.
      reserved: true
    }
  ],
});
python
vpc = ec2.Vpc(self, "TheVPC",
    # 'IpAddresses' configures the IP range and size of the entire VPC.
    # The IP space will be divided based on configuration for the subnets.
    ip_addresses=ec2.IpAddresses.cidr("10.0.0.0/21"),

    # 'maxAzs' configures the maximum number of availability zones to use.
    # If you want to specify the exact availability zones you want the VPC
    # to use, use `availabilityZones` instead.
    max_azs=3,

    # 'subnetConfiguration' specifies the "subnet groups" to create.
    # Every subnet group will have a subnet for each AZ, so this
    # configuration will create `3 groups × 3 AZs = 9` subnets.
    subnet_configuration=[ec2.SubnetConfiguration(
        # 'subnetType' controls Internet access, as described above.
        subnet_type=ec2.SubnetType.PUBLIC,

        # 'name' is used to name this particular subnet group. You will have to
        # use the name for subnet selection if you have more than one subnet
        # group of the same type.
        name="Ingress",

        # 'cidrMask' specifies the IP addresses in the range of individual
        # subnets in the group. Each of the subnets in this group will contain
        # `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
        # usable IP addresses.
        #
        # If 'cidrMask' is left out the available address space is evenly
        # divided across the remaining subnet groups.
        cidr_mask=24
    ), ec2.SubnetConfiguration(
        cidr_mask=24,
        name="Application",
        subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS
    ), ec2.SubnetConfiguration(
        cidr_mask=28,
        name="Database",
        subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,

        # 'reserved' can be used to reserve IP address space. No resources will
        # be created for this subnet, but the IP range will be kept available for
        # future creation of this subnet, or even for future subdivision.
        reserved=True
    )
    ]
)
java
Vpc vpc = Vpc.Builder.create(this, "TheVPC")
        // 'IpAddresses' configures the IP range and size of the entire VPC.
        // The IP space will be divided based on configuration for the subnets.
        .ipAddresses(IpAddresses.cidr("10.0.0.0/21"))

        // 'maxAzs' configures the maximum number of availability zones to use.
        // If you want to specify the exact availability zones you want the VPC
        // to use, use `availabilityZones` instead.
        .maxAzs(3)

        // 'subnetConfiguration' specifies the "subnet groups" to create.
        // Every subnet group will have a subnet for each AZ, so this
        // configuration will create `3 groups × 3 AZs = 9` subnets.
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                // 'subnetType' controls Internet access, as described above.
                .subnetType(SubnetType.PUBLIC)

                // 'name' is used to name this particular subnet group. You will have to
                // use the name for subnet selection if you have more than one subnet
                // group of the same type.
                .name("Ingress")

                // 'cidrMask' specifies the IP addresses in the range of individual
                // subnets in the group. Each of the subnets in this group will contain
                // `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
                // usable IP addresses.
                //
                // If 'cidrMask' is left out the available address space is evenly
                // divided across the remaining subnet groups.
                .cidrMask(24)
                .build(), SubnetConfiguration.builder()
                .cidrMask(24)
                .name("Application")
                .subnetType(SubnetType.PRIVATE_WITH_EGRESS)
                .build(), SubnetConfiguration.builder()
                .cidrMask(28)
                .name("Database")
                .subnetType(SubnetType.PRIVATE_ISOLATED)

                // 'reserved' can be used to reserve IP address space. No resources will
                // be created for this subnet, but the IP range will be kept available for
                // future creation of this subnet, or even for future subdivision.
                .reserved(true)
                .build()))
        .build();
csharp
var vpc = new Vpc(this, "TheVPC", new VpcProps {
    // 'IpAddresses' configures the IP range and size of the entire VPC.
    // The IP space will be divided based on configuration for the subnets.
    IpAddresses = IpAddresses.Cidr("10.0.0.0/21"),

    // 'maxAzs' configures the maximum number of availability zones to use.
    // If you want to specify the exact availability zones you want the VPC
    // to use, use `availabilityZones` instead.
    MaxAzs = 3,

    // 'subnetConfiguration' specifies the "subnet groups" to create.
    // Every subnet group will have a subnet for each AZ, so this
    // configuration will create `3 groups × 3 AZs = 9` subnets.
    SubnetConfiguration = new [] { new SubnetConfiguration {
        // 'subnetType' controls Internet access, as described above.
        SubnetType = SubnetType.PUBLIC,

        // 'name' is used to name this particular subnet group. You will have to
        // use the name for subnet selection if you have more than one subnet
        // group of the same type.
        Name = "Ingress",

        // 'cidrMask' specifies the IP addresses in the range of individual
        // subnets in the group. Each of the subnets in this group will contain
        // `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
        // usable IP addresses.
        //
        // If 'cidrMask' is left out the available address space is evenly
        // divided across the remaining subnet groups.
        CidrMask = 24
    }, new SubnetConfiguration {
        CidrMask = 24,
        Name = "Application",
        SubnetType = SubnetType.PRIVATE_WITH_EGRESS
    }, new SubnetConfiguration {
        CidrMask = 28,
        Name = "Database",
        SubnetType = SubnetType.PRIVATE_ISOLATED,

        // 'reserved' can be used to reserve IP address space. No resources will
        // be created for this subnet, but the IP range will be kept available for
        // future creation of this subnet, or even for future subdivision.
        Reserved = true
    } }
});
go
vpc := ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	// 'IpAddresses' configures the IP range and size of the entire VPC.
	// The IP space will be divided based on configuration for the subnets.
	IpAddresses: ec2.IpAddresses_Cidr(jsii.String("10.0.0.0/21")),

	// 'maxAzs' configures the maximum number of availability zones to use.
	// If you want to specify the exact availability zones you want the VPC
	// to use, use `availabilityZones` instead.
	MaxAzs: jsii.Number(3),

	// 'subnetConfiguration' specifies the "subnet groups" to create.
	// Every subnet group will have a subnet for each AZ, so this
	// configuration will create `3 groups × 3 AZs = 9` subnets.
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			// 'subnetType' controls Internet access, as described above.
			SubnetType: ec2.SubnetType_PUBLIC,

			// 'name' is used to name this particular subnet group. You will have to
			// use the name for subnet selection if you have more than one subnet
			// group of the same type.
			Name: jsii.String("Ingress"),

			// 'cidrMask' specifies the IP addresses in the range of individual
			// subnets in the group. Each of the subnets in this group will contain
			// `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
			// usable IP addresses.
			//
			// If 'cidrMask' is left out the available address space is evenly
			// divided across the remaining subnet groups.
			CidrMask: jsii.Number(24),
		},
		&SubnetConfiguration{
			CidrMask: jsii.Number(24),
			Name: jsii.String("Application"),
			SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
		},
		&SubnetConfiguration{
			CidrMask: jsii.Number(28),
			Name: jsii.String("Database"),
			SubnetType: ec2.SubnetType_PRIVATE_ISOLATED,

			// 'reserved' can be used to reserve IP address space. No resources will
			// be created for this subnet, but the IP range will be kept available for
			// future creation of this subnet, or even for future subdivision.
			Reserved: jsii.Boolean(true),
		},
	},
})

The example above is one possible configuration, but the user can use the constructs above to implement many other network configurations.

The Vpc from the above configuration in a Region with three availability zones will be the following:

Subnet NameTypeIP BlockAZFeatures
IngressSubnet1PUBLIC10.0.0.0/24#1NAT Gateway
IngressSubnet2PUBLIC10.0.1.0/24#2NAT Gateway
IngressSubnet3PUBLIC10.0.2.0/24#3NAT Gateway
ApplicationSubnet1PRIVATE10.0.3.0/24#1Route to NAT in IngressSubnet1
ApplicationSubnet2PRIVATE10.0.4.0/24#2Route to NAT in IngressSubnet2
ApplicationSubnet3PRIVATE10.0.5.0/24#3Route to NAT in IngressSubnet3
DatabaseSubnet1ISOLATED10.0.6.0/28#1Only routes within the VPC
DatabaseSubnet2ISOLATED10.0.6.16/28#2Only routes within the VPC
DatabaseSubnet3ISOLATED10.0.6.32/28#3Only routes within the VPC

Dual Stack Configurations ​

Here is a break down of IPv4 and IPv6 specific subnetConfiguration properties in a dual stack VPC:

ts
const vpc = new ec2.Vpc(this, 'TheVPC', {
  ipProtocol: ec2.IpProtocol.DUAL_STACK,

  subnetConfiguration: [
    {
      // general properties
      name: 'Public',
      subnetType: ec2.SubnetType.PUBLIC,
      reserved: false,

      // IPv4 specific properties
      mapPublicIpOnLaunch: true,
      cidrMask: 24,

      // new IPv6 specific property
      ipv6AssignAddressOnCreation: true,
    },
  ],
});
python
vpc = ec2.Vpc(self, "TheVPC",
    ip_protocol=ec2.IpProtocol.DUAL_STACK,

    subnet_configuration=[ec2.SubnetConfiguration(
        # general properties
        name="Public",
        subnet_type=ec2.SubnetType.PUBLIC,
        reserved=False,

        # IPv4 specific properties
        map_public_ip_on_launch=True,
        cidr_mask=24,

        # new IPv6 specific property
        ipv6_assign_address_on_creation=True
    )
    ]
)
java
Vpc vpc = Vpc.Builder.create(this, "TheVPC")
        .ipProtocol(IpProtocol.DUAL_STACK)

        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                // general properties
                .name("Public")
                .subnetType(SubnetType.PUBLIC)
                .reserved(false)

                // IPv4 specific properties
                .mapPublicIpOnLaunch(true)
                .cidrMask(24)

                // new IPv6 specific property
                .ipv6AssignAddressOnCreation(true)
                .build()))
        .build();
csharp
var vpc = new Vpc(this, "TheVPC", new VpcProps {
    IpProtocol = IpProtocol.DUAL_STACK,

    SubnetConfiguration = new [] { new SubnetConfiguration {
        // general properties
        Name = "Public",
        SubnetType = SubnetType.PUBLIC,
        Reserved = false,

        // IPv4 specific properties
        MapPublicIpOnLaunch = true,
        CidrMask = 24,

        // new IPv6 specific property
        Ipv6AssignAddressOnCreation = true
    } }
});
go
vpc := ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	IpProtocol: ec2.IpProtocol_DUAL_STACK,

	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			// general properties
			Name: jsii.String("Public"),
			SubnetType: ec2.SubnetType_PUBLIC,
			Reserved: jsii.Boolean(false),

			// IPv4 specific properties
			MapPublicIpOnLaunch: jsii.Boolean(true),
			CidrMask: jsii.Number(24),

			// new IPv6 specific property
			Ipv6AssignAddressOnCreation: jsii.Boolean(true),
		},
	},
})

The property mapPublicIpOnLaunch controls if a public IPv4 address will be assigned. This defaults to false for dual stack VPCs to avoid inadvertant costs of having the public address. However, a public IP must be enabled (or otherwise configured with BYOIP or IPAM) in order for services that rely on the address to function.

The ipv6AssignAddressOnCreation property controls the same behavior for the IPv6 address. It defaults to true.

Using IPv6 specific properties in an IPv4 only VPC will result in errors.

Accessing the Internet Gateway ​

If you need access to the internet gateway, you can get its ID like so:

ts
declare const vpc: ec2.Vpc;

const igwId = vpc.internetGatewayId;
python
# vpc: ec2.Vpc


igw_id = vpc.internet_gateway_id
java
Vpc vpc;


String igwId = vpc.getInternetGatewayId();
csharp
Vpc vpc;


var igwId = vpc.InternetGatewayId;
go
var vpc Vpc


igwId := vpc.InternetGatewayId

For a VPC with only ISOLATED subnets, this value will be undefined.

This is only supported for VPCs created in the stack - currently you're unable to get the ID for imported VPCs. To do that you'd have to specifically look up the Internet Gateway by name, which would require knowing the name beforehand.

This can be useful for configuring routing using a combination of gateways: for more information see Routing below.

Disabling the creation of the default internet gateway ​

If you need to control the creation of the internet gateway explicitly, you can disable the creation of the default one using the createInternetGateway property:

ts
const vpc = new ec2.Vpc(this, "VPC", {
  createInternetGateway: false,
  subnetConfiguration: [{
      subnetType: ec2.SubnetType.PUBLIC,
      name: 'Public',
    }]
});
python
vpc = ec2.Vpc(self, "VPC",
    create_internet_gateway=False,
    subnet_configuration=[ec2.SubnetConfiguration(
        subnet_type=ec2.SubnetType.PUBLIC,
        name="Public"
    )]
)
java
Vpc vpc = Vpc.Builder.create(this, "VPC")
        .createInternetGateway(false)
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                .subnetType(SubnetType.PUBLIC)
                .name("Public")
                .build()))
        .build();
csharp
var vpc = new Vpc(this, "VPC", new VpcProps {
    CreateInternetGateway = false,
    SubnetConfiguration = new [] { new SubnetConfiguration {
        SubnetType = SubnetType.PUBLIC,
        Name = "Public"
    } }
});
go
vpc := ec2.NewVpc(this, jsii.String("VPC"), &VpcProps{
	CreateInternetGateway: jsii.Boolean(false),
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			SubnetType: ec2.SubnetType_PUBLIC,
			Name: jsii.String("Public"),
		},
	},
})

Routing ​

It's possible to add routes to any subnets using the addRoute() method. If for example you want an isolated subnet to have a static route via the default Internet Gateway created for the public subnet - perhaps for routing a VPN connection - you can do so like this:

ts
const vpc = new ec2.Vpc(this, "VPC", {
  subnetConfiguration: [{
      subnetType: ec2.SubnetType.PUBLIC,
      name: 'Public',
    },{
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
      name: 'Isolated',
    }]
});

(vpc.isolatedSubnets[0] as ec2.Subnet).addRoute("StaticRoute", {
    routerId: vpc.internetGatewayId!,
    routerType: ec2.RouterType.GATEWAY,
    destinationCidrBlock: "8.8.8.8/32",
})
python
vpc = ec2.Vpc(self, "VPC",
    subnet_configuration=[ec2.SubnetConfiguration(
        subnet_type=ec2.SubnetType.PUBLIC,
        name="Public"
    ), ec2.SubnetConfiguration(
        subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
        name="Isolated"
    )]
)

(vpc.isolated_subnets[0]).add_route("StaticRoute",
    router_id=vpc.internet_gateway_id,
    router_type=ec2.RouterType.GATEWAY,
    destination_cidr_block="8.8.8.8/32"
)
java
Vpc vpc = Vpc.Builder.create(this, "VPC")
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                .subnetType(SubnetType.PUBLIC)
                .name("Public")
                .build(), SubnetConfiguration.builder()
                .subnetType(SubnetType.PRIVATE_ISOLATED)
                .name("Isolated")
                .build()))
        .build();

((Subnet)vpc.isolatedSubnets[0]).addRoute("StaticRoute", AddRouteOptions.builder()
        .routerId(vpc.getInternetGatewayId())
        .routerType(RouterType.GATEWAY)
        .destinationCidrBlock("8.8.8.8/32")
        .build());
csharp
var vpc = new Vpc(this, "VPC", new VpcProps {
    SubnetConfiguration = new [] { new SubnetConfiguration {
        SubnetType = SubnetType.PUBLIC,
        Name = "Public"
    }, new SubnetConfiguration {
        SubnetType = SubnetType.PRIVATE_ISOLATED,
        Name = "Isolated"
    } }
});

((Subnet)vpc.IsolatedSubnets[0]).AddRoute("StaticRoute", new AddRouteOptions {
    RouterId = vpc.InternetGatewayId,
    RouterType = RouterType.GATEWAY,
    DestinationCidrBlock = "8.8.8.8/32"
});
go
vpc := ec2.NewVpc(this, jsii.String("VPC"), &VpcProps{
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			SubnetType: ec2.SubnetType_PUBLIC,
			Name: jsii.String("Public"),
		},
		&SubnetConfiguration{
			SubnetType: ec2.SubnetType_PRIVATE_ISOLATED,
			Name: jsii.String("Isolated"),
		},
	},
})

(vpc.IsolatedSubnets[0].(Subnet)).AddRoute(jsii.String("StaticRoute"), &AddRouteOptions{
	RouterId: vpc.InternetGatewayId,
	RouterType: ec2.RouterType_GATEWAY,
	DestinationCidrBlock: jsii.String("8.8.8.8/32"),
})

Note that we cast to Subnet here because the list of subnets only returns an ISubnet.

Reserving subnet IP space ​

There are situations where the IP space for a subnet or number of subnets will need to be reserved. This is useful in situations where subnets would need to be added after the vpc is originally deployed, without causing IP renumbering for existing subnets. The IP space for a subnet may be reserved by setting the reserved subnetConfiguration property to true, as shown below:

ts
const vpc = new ec2.Vpc(this, 'TheVPC', {
  natGateways: 1,
  subnetConfiguration: [
    {
      cidrMask: 26,
      name: 'Public',
      subnetType: ec2.SubnetType.PUBLIC,
    },
    {
      cidrMask: 26,
      name: 'Application1',
      subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
    },
    {
      cidrMask: 26,
      name: 'Application2',
      subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
      reserved: true,   // <---- This subnet group is reserved
    },
    {
      cidrMask: 27,
      name: 'Database',
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
    }
  ],
});
python
vpc = ec2.Vpc(self, "TheVPC",
    nat_gateways=1,
    subnet_configuration=[ec2.SubnetConfiguration(
        cidr_mask=26,
        name="Public",
        subnet_type=ec2.SubnetType.PUBLIC
    ), ec2.SubnetConfiguration(
        cidr_mask=26,
        name="Application1",
        subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS
    ), ec2.SubnetConfiguration(
        cidr_mask=26,
        name="Application2",
        subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
        reserved=True
    ), ec2.SubnetConfiguration(
        cidr_mask=27,
        name="Database",
        subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
    )
    ]
)
java
Vpc vpc = Vpc.Builder.create(this, "TheVPC")
        .natGateways(1)
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                .cidrMask(26)
                .name("Public")
                .subnetType(SubnetType.PUBLIC)
                .build(), SubnetConfiguration.builder()
                .cidrMask(26)
                .name("Application1")
                .subnetType(SubnetType.PRIVATE_WITH_EGRESS)
                .build(), SubnetConfiguration.builder()
                .cidrMask(26)
                .name("Application2")
                .subnetType(SubnetType.PRIVATE_WITH_EGRESS)
                .reserved(true)
                .build(), SubnetConfiguration.builder()
                .cidrMask(27)
                .name("Database")
                .subnetType(SubnetType.PRIVATE_ISOLATED)
                .build()))
        .build();
csharp
var vpc = new Vpc(this, "TheVPC", new VpcProps {
    NatGateways = 1,
    SubnetConfiguration = new [] { new SubnetConfiguration {
        CidrMask = 26,
        Name = "Public",
        SubnetType = SubnetType.PUBLIC
    }, new SubnetConfiguration {
        CidrMask = 26,
        Name = "Application1",
        SubnetType = SubnetType.PRIVATE_WITH_EGRESS
    }, new SubnetConfiguration {
        CidrMask = 26,
        Name = "Application2",
        SubnetType = SubnetType.PRIVATE_WITH_EGRESS,
        Reserved = true
    }, new SubnetConfiguration {
        CidrMask = 27,
        Name = "Database",
        SubnetType = SubnetType.PRIVATE_ISOLATED
    } }
});
go
vpc := ec2.NewVpc(this, jsii.String("TheVPC"), &VpcProps{
	NatGateways: jsii.Number(1),
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			CidrMask: jsii.Number(26),
			Name: jsii.String("Public"),
			SubnetType: ec2.SubnetType_PUBLIC,
		},
		&SubnetConfiguration{
			CidrMask: jsii.Number(26),
			Name: jsii.String("Application1"),
			SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
		},
		&SubnetConfiguration{
			CidrMask: jsii.Number(26),
			Name: jsii.String("Application2"),
			SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
			Reserved: jsii.Boolean(true),
		},
		&SubnetConfiguration{
			CidrMask: jsii.Number(27),
			Name: jsii.String("Database"),
			SubnetType: ec2.SubnetType_PRIVATE_ISOLATED,
		},
	},
})

In the example above, the subnet for Application2 is not actually provisioned but its IP space is still reserved. If in the future this subnet needs to be provisioned, then the reserved: true property should be removed. Reserving parts of the IP space prevents the other subnets from getting renumbered.

Sharing VPCs between stacks ​

If you are creating multiple Stacks inside the same CDK application, you can reuse a VPC defined in one Stack in another by simply passing the VPC instance around:

ts
/**
 * Stack1 creates the VPC
 */
class Stack1 extends cdk.Stack {
  public readonly vpc: ec2.Vpc;

  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    this.vpc = new ec2.Vpc(this, 'VPC');
  }
}

interface Stack2Props extends cdk.StackProps {
  vpc: ec2.IVpc;
}

/**
 * Stack2 consumes the VPC
 */
class Stack2 extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props: Stack2Props) {
    super(scope, id, props);

    // Pass the VPC to a construct that needs it
    new ConstructThatTakesAVpc(this, 'Construct', {
      vpc: props.vpc,
    });
  }
}

const stack1 = new Stack1(app, 'Stack1');
const stack2 = new Stack2(app, 'Stack2', {
  vpc: stack1.vpc,
});
python
#
# Stack1 creates the VPC
#
class Stack1(cdk.Stack):

    def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        self.vpc = ec2.Vpc(self, "VPC")

#
# Stack2 consumes the VPC
#
class Stack2(cdk.Stack):
    def __init__(self, scope, id, *, vpc, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, vpc=vpc, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        # Pass the VPC to a construct that needs it
        ConstructThatTakesAVpc(self, "Construct",
            vpc=vpc
        )

stack1 = Stack1(app, "Stack1")
stack2 = Stack2(app, "Stack2",
    vpc=stack1.vpc
)
java
/**
 * Stack1 creates the VPC
 */
public class Stack1 extends Stack {
    public final Vpc vpc;

    public Stack1(App scope, String id) {
        this(scope, id, null);
    }

    public Stack1(App scope, String id, StackProps props) {
        super(scope, id, props);

        this.vpc = new Vpc(this, "VPC");
    }
}

public class Stack2Props extends StackProps {
    private IVpc vpc;
    public IVpc getVpc() {
        return this.vpc;
    }
    public Stack2Props vpc(IVpc vpc) {
        this.vpc = vpc;
        return this;
    }
}

/**
 * Stack2 consumes the VPC
 */
public class Stack2 extends Stack {
    public Stack2(App scope, String id, Stack2Props props) {
        super(scope, id, props);

        // Pass the VPC to a construct that needs it
        // Pass the VPC to a construct that needs it
        new ConstructThatTakesAVpc(this, "Construct", new ConstructThatTakesAVpcProps()
                .vpc(props.getVpc())
                );
    }
}

Stack1 stack1 = new Stack1(app, "Stack1");
Stack2 stack2 = new Stack2(app, "Stack2", new Stack2Props()
        .vpc(stack1.getVpc())
        );
csharp
/**
 * Stack1 creates the VPC
 */
class Stack1 : Stack
{
    public Vpc Vpc { get; }

    public Stack1(App scope, string id, StackProps? props=null) : base(scope, id, props)
    {

        Vpc = new Vpc(this, "VPC");
    }
}

class Stack2Props : StackProps
{
    public IVpc Vpc { get; set; }
}

/**
 * Stack2 consumes the VPC
 */
class Stack2 : Stack
{
    public Stack2(App scope, string id, Stack2Props props) : base(scope, id, props)
    {

        // Pass the VPC to a construct that needs it
        // Pass the VPC to a construct that needs it
        new ConstructThatTakesAVpc(this, "Construct", new ConstructThatTakesAVpcProps {
            Vpc = props.Vpc
        });
    }
}

var stack1 = new Stack1(app, "Stack1");
var stack2 = new Stack2(app, "Stack2", new Stack2Props {
    Vpc = stack1.Vpc
});
go
/**
 * Stack1 creates the VPC
 */
type stack1 struct {
	Stack
	vpc Vpc
}

func newStack1(scope App, id *string, props StackProps) *stack1 {
	this := &stack1{}
	cdk.NewStack_Override(this, scope, id, props)

	this.vpc = ec2.NewVpc(this, jsii.String("VPC"))
	return this
}

type stack2Props struct {
	StackProps
	vpc IVpc
}

/**
 * Stack2 consumes the VPC
 */
type stack2 struct {
	Stack
}

func newStack2(scope App, id *string, props stack2Props) *stack2 {
	this := &stack2{}
	cdk.NewStack_Override(this, scope, id, props)

	// Pass the VPC to a construct that needs it
	// Pass the VPC to a construct that needs it
	NewConstructThatTakesAVpc(this, jsii.String("Construct"), &constructThatTakesAVpcProps{
		vpc: props.vpc,
	})
	return this
}

stack1 := NewStack1(app, jsii.String("Stack1"))
stack2 := NewStack2(app, jsii.String("Stack2"), &stack2Props{
	vpc: stack1.vpc,
})

Note: If you encounter an error like "Delete canceled. Cannot delete export ..." when using a cross-stack reference to a VPC, it's likely due to CloudFormation export/import constraints. In such cases, it's safer to use Vpc.fromLookup() in the consuming stack instead of directly referencing the VPC object, more details is provided in Importing an existing VPC. This avoids creating CloudFormation exports and gives more flexibility, especially when stacks need to be deleted or updated independently.

Importing an existing VPC ​

If your VPC is created outside your CDK app, you can use Vpc.fromLookup(). The CDK CLI will search for the specified VPC in the stack's region and account, and import the subnet configuration. Looking up can be done by VPC ID, but more flexibly by searching for a specific tag on the VPC.

Subnet types will be determined from the aws-cdk:subnet-type tag on the subnet if it exists, or the presence of a route to an Internet Gateway otherwise. Subnet names will be determined from the aws-cdk:subnet-name tag on the subnet if it exists, or will mirror the subnet type otherwise (i.e. a public subnet will have the name "Public").

The result of the Vpc.fromLookup() operation will be written to a file called cdk.context.json. You must commit this file to source control so that the lookup values are available in non-privileged environments such as CI build steps, and to ensure your template builds are repeatable.

Here's how Vpc.fromLookup() can be used:

ts
const vpc = ec2.Vpc.fromLookup(stack, 'VPC', {
  // This imports the default VPC but you can also
  // specify a 'vpcName' or 'tags'.
  isDefault: true,
});
python
vpc = ec2.Vpc.from_lookup(stack, "VPC",
    # This imports the default VPC but you can also
    # specify a 'vpcName' or 'tags'.
    is_default=True
)
java
IVpc vpc = Vpc.fromLookup(stack, "VPC", VpcLookupOptions.builder()
        // This imports the default VPC but you can also
        // specify a 'vpcName' or 'tags'.
        .isDefault(true)
        .build());
csharp
var vpc = Vpc.FromLookup(stack, "VPC", new VpcLookupOptions {
    // This imports the default VPC but you can also
    // specify a 'vpcName' or 'tags'.
    IsDefault = true
});
go
vpc := ec2.Vpc_FromLookup(stack, jsii.String("VPC"), &VpcLookupOptions{
	// This imports the default VPC but you can also
	// specify a 'vpcName' or 'tags'.
	IsDefault: jsii.Boolean(true),
})

Vpc.fromLookup is the recommended way to import VPCs. If for whatever reason you do not want to use the context mechanism to look up a VPC at synthesis time, you can also use Vpc.fromVpcAttributes. This has the following limitations:

  • Every subnet group in the VPC must have a subnet in each availability zone (for example, each AZ must have both a public and private subnet). Asymmetric VPCs are not supported.
  • All VpcId, SubnetId, RouteTableId, ... parameters must either be known at synthesis time, or they must come from deploy-time list parameters whose deploy-time lengths are known at synthesis time.

Using Vpc.fromVpcAttributes() looks like this:

ts
const vpc = ec2.Vpc.fromVpcAttributes(this, 'VPC', {
  vpcId: 'vpc-1234',
  availabilityZones: ['us-east-1a', 'us-east-1b'],

  // Either pass literals for all IDs
  publicSubnetIds: ['s-12345', 's-67890'],

  // OR: import a list of known length
  privateSubnetIds: Fn.importListValue('PrivateSubnetIds', 2),

  // OR: split an imported string to a list of known length
  isolatedSubnetIds: Fn.split(',', ssm.StringParameter.valueForStringParameter(this, `MyParameter`), 2),
});
python
vpc = ec2.Vpc.from_vpc_attributes(self, "VPC",
    vpc_id="vpc-1234",
    availability_zones=["us-east-1a", "us-east-1b"],

    # Either pass literals for all IDs
    public_subnet_ids=["s-12345", "s-67890"],

    # OR: import a list of known length
    private_subnet_ids=Fn.import_list_value("PrivateSubnetIds", 2),

    # OR: split an imported string to a list of known length
    isolated_subnet_ids=Fn.split(",", ssm.StringParameter.value_for_string_parameter(self, "MyParameter"), 2)
)
java
IVpc vpc = Vpc.fromVpcAttributes(this, "VPC", VpcAttributes.builder()
        .vpcId("vpc-1234")
        .availabilityZones(List.of("us-east-1a", "us-east-1b"))

        // Either pass literals for all IDs
        .publicSubnetIds(List.of("s-12345", "s-67890"))

        // OR: import a list of known length
        .privateSubnetIds(Fn.importListValue("PrivateSubnetIds", 2))

        // OR: split an imported string to a list of known length
        .isolatedSubnetIds(Fn.split(",", StringParameter.valueForStringParameter(this, "MyParameter"), 2))
        .build());
csharp
var vpc = Vpc.FromVpcAttributes(this, "VPC", new VpcAttributes {
    VpcId = "vpc-1234",
    AvailabilityZones = new [] { "us-east-1a", "us-east-1b" },

    // Either pass literals for all IDs
    PublicSubnetIds = new [] { "s-12345", "s-67890" },

    // OR: import a list of known length
    PrivateSubnetIds = Fn.ImportListValue("PrivateSubnetIds", 2),

    // OR: split an imported string to a list of known length
    IsolatedSubnetIds = Fn.Split(",", StringParameter.ValueForStringParameter(this, "MyParameter"), 2)
});
go
vpc := ec2.Vpc_FromVpcAttributes(this, jsii.String("VPC"), &VpcAttributes{
	VpcId: jsii.String("vpc-1234"),
	AvailabilityZones: []*string{
		jsii.String("us-east-1a"),
		jsii.String("us-east-1b"),
	},

	// Either pass literals for all IDs
	PublicSubnetIds: []*string{
		jsii.String("s-12345"),
		jsii.String("s-67890"),
	},

	// OR: import a list of known length
	PrivateSubnetIds: awscdk.Fn_ImportListValue(jsii.String("PrivateSubnetIds"), jsii.Number(2)),

	// OR: split an imported string to a list of known length
	IsolatedSubnetIds: awscdk.Fn_Split(jsii.String(","), ssm.StringParameter_ValueForStringParameter(this, jsii.String("MyParameter")), jsii.Number(2)),
})

For each subnet group the import function accepts optional parameters for subnet names, route table ids and IPv4 CIDR blocks. When supplied, the length of these lists are required to match the length of the list of subnet ids, allowing the lists to be zipped together to form ISubnet instances.

Public subnet group example (for private or isolated subnet groups, use the properties with the respective prefix):

ts
const vpc = ec2.Vpc.fromVpcAttributes(this, 'VPC', {
  vpcId: 'vpc-1234',
  availabilityZones: ['us-east-1a', 'us-east-1b', 'us-east-1c'],
  publicSubnetIds: ['s-12345', 's-34567', 's-56789'],
  publicSubnetNames: ['Subnet A', 'Subnet B', 'Subnet C'],
  publicSubnetRouteTableIds: ['rt-12345', 'rt-34567', 'rt-56789'],
  publicSubnetIpv4CidrBlocks: ['10.0.0.0/24', '10.0.1.0/24', '10.0.2.0/24'],
});
python
vpc = ec2.Vpc.from_vpc_attributes(self, "VPC",
    vpc_id="vpc-1234",
    availability_zones=["us-east-1a", "us-east-1b", "us-east-1c"],
    public_subnet_ids=["s-12345", "s-34567", "s-56789"],
    public_subnet_names=["Subnet A", "Subnet B", "Subnet C"],
    public_subnet_route_table_ids=["rt-12345", "rt-34567", "rt-56789"],
    public_subnet_ipv4_cidr_blocks=["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
)
java
IVpc vpc = Vpc.fromVpcAttributes(this, "VPC", VpcAttributes.builder()
        .vpcId("vpc-1234")
        .availabilityZones(List.of("us-east-1a", "us-east-1b", "us-east-1c"))
        .publicSubnetIds(List.of("s-12345", "s-34567", "s-56789"))
        .publicSubnetNames(List.of("Subnet A", "Subnet B", "Subnet C"))
        .publicSubnetRouteTableIds(List.of("rt-12345", "rt-34567", "rt-56789"))
        .publicSubnetIpv4CidrBlocks(List.of("10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"))
        .build());
csharp
var vpc = Vpc.FromVpcAttributes(this, "VPC", new VpcAttributes {
    VpcId = "vpc-1234",
    AvailabilityZones = new [] { "us-east-1a", "us-east-1b", "us-east-1c" },
    PublicSubnetIds = new [] { "s-12345", "s-34567", "s-56789" },
    PublicSubnetNames = new [] { "Subnet A", "Subnet B", "Subnet C" },
    PublicSubnetRouteTableIds = new [] { "rt-12345", "rt-34567", "rt-56789" },
    PublicSubnetIpv4CidrBlocks = new [] { "10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24" }
});
go
vpc := ec2.Vpc_FromVpcAttributes(this, jsii.String("VPC"), &VpcAttributes{
	VpcId: jsii.String("vpc-1234"),
	AvailabilityZones: []*string{
		jsii.String("us-east-1a"),
		jsii.String("us-east-1b"),
		jsii.String("us-east-1c"),
	},
	PublicSubnetIds: []*string{
		jsii.String("s-12345"),
		jsii.String("s-34567"),
		jsii.String("s-56789"),
	},
	PublicSubnetNames: []*string{
		jsii.String("Subnet A"),
		jsii.String("Subnet B"),
		jsii.String("Subnet C"),
	},
	PublicSubnetRouteTableIds: []*string{
		jsii.String("rt-12345"),
		jsii.String("rt-34567"),
		jsii.String("rt-56789"),
	},
	PublicSubnetIpv4CidrBlocks: []*string{
		jsii.String("10.0.0.0/24"),
		jsii.String("10.0.1.0/24"),
		jsii.String("10.0.2.0/24"),
	},
})

The above example will create an IVpc instance with three public subnets:

| Subnet id | Availability zone | Subnet name | Route table id | IPv4 CIDR | | --------- | ----------------- | ----------- | -------------- | ----------- | | s-12345 | us-east-1a | Subnet A | rt-12345 | 10.0.0.0/24 | | s-34567 | us-east-1b | Subnet B | rt-34567 | 10.0.1.0/24 | | s-56789 | us-east-1c | Subnet B | rt-56789 | 10.0.2.0/24 |

Restricting access to the VPC default security group ​

AWS Security best practices recommend that the VPC default security group should not allow inbound and outbound traffic. When the @aws-cdk/aws-ec2:restrictDefaultSecurityGroup feature flag is set to true (default for new projects) this will be enabled by default. If you do not have this feature flag set you can either set the feature flag or you can set the restrictDefaultSecurityGroup property to true.

ts
new ec2.Vpc(this, 'VPC', {
  restrictDefaultSecurityGroup: true,
});
python
ec2.Vpc(self, "VPC",
    restrict_default_security_group=True
)
java
Vpc.Builder.create(this, "VPC")
        .restrictDefaultSecurityGroup(true)
        .build();
csharp
new Vpc(this, "VPC", new VpcProps {
    RestrictDefaultSecurityGroup = true
});
go
ec2.NewVpc(this, jsii.String("VPC"), &VpcProps{
	RestrictDefaultSecurityGroup: jsii.Boolean(true),
})

If you set this property to true and then later remove it or set it to false the default ingress/egress will be restored on the default security group.

Allowing Connections ​

In AWS, all network traffic in and out of Elastic Network Interfaces (ENIs) is controlled by Security Groups. You can think of Security Groups as a firewall with a set of rules. By default, Security Groups allow no incoming (ingress) traffic and all outgoing (egress) traffic. You can add ingress rules to them to allow incoming traffic streams. To exert fine-grained control over egress traffic, set allowAllOutbound: false on the SecurityGroup, after which you can add egress traffic rules.

You can manipulate Security Groups directly:

ts
const mySecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
  vpc,
  description: 'Allow ssh access to ec2 instances',
  allowAllOutbound: true   // Can be set to false
});
mySecurityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'allow ssh access from the world');
python
my_security_group = ec2.SecurityGroup(self, "SecurityGroup",
    vpc=vpc,
    description="Allow ssh access to ec2 instances",
    allow_all_outbound=True
)
my_security_group.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(22), "allow ssh access from the world")
java
SecurityGroup mySecurityGroup = SecurityGroup.Builder.create(this, "SecurityGroup")
        .vpc(vpc)
        .description("Allow ssh access to ec2 instances")
        .allowAllOutbound(true)
        .build();
mySecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(22), "allow ssh access from the world");
csharp
var mySecurityGroup = new SecurityGroup(this, "SecurityGroup", new SecurityGroupProps {
    Vpc = vpc,
    Description = "Allow ssh access to ec2 instances",
    AllowAllOutbound = true
});
mySecurityGroup.AddIngressRule(Peer.AnyIpv4(), Port.Tcp(22), "allow ssh access from the world");
go
mySecurityGroup := ec2.NewSecurityGroup(this, jsii.String("SecurityGroup"), &SecurityGroupProps{
	Vpc: Vpc,
	Description: jsii.String("Allow ssh access to ec2 instances"),
	AllowAllOutbound: jsii.Boolean(true),
})
mySecurityGroup.AddIngressRule(ec2.Peer_AnyIpv4(), ec2.Port_Tcp(jsii.Number(22)), jsii.String("allow ssh access from the world"))

All constructs that create ENIs on your behalf (typically constructs that create EC2 instances or other VPC-connected resources) will all have security groups automatically assigned. Those constructs have an attribute called connections, which is an object that makes it convenient to update the security groups. If you want to allow connections between two constructs that have security groups, you have to add an Egress rule to one Security Group, and an Ingress rule to the other. The connections object will automatically take care of this for you:

ts
declare const loadBalancer: elbv2.ApplicationLoadBalancer;
declare const appFleet: autoscaling.AutoScalingGroup;
declare const dbFleet: autoscaling.AutoScalingGroup;

// Allow connections from anywhere
loadBalancer.connections.allowFromAnyIpv4(ec2.Port.HTTPS, 'Allow inbound HTTPS');

// The same, but an explicit IP address
loadBalancer.connections.allowFrom(ec2.Peer.ipv4('1.2.3.4/32'), ec2.Port.HTTPS, 'Allow inbound HTTPS');

// Allow connection between AutoScalingGroups
appFleet.connections.allowTo(dbFleet, ec2.Port.HTTPS, 'App can call database');
python
# load_balancer: elbv2.ApplicationLoadBalancer
# app_fleet: autoscaling.AutoScalingGroup
# db_fleet: autoscaling.AutoScalingGroup


# Allow connections from anywhere
load_balancer.connections.allow_from_any_ipv4(ec2.Port.HTTPS, "Allow inbound HTTPS")

# The same, but an explicit IP address
load_balancer.connections.allow_from(ec2.Peer.ipv4("1.2.3.4/32"), ec2.Port.HTTPS, "Allow inbound HTTPS")

# Allow connection between AutoScalingGroups
app_fleet.connections.allow_to(db_fleet, ec2.Port.HTTPS, "App can call database")
java
ApplicationLoadBalancer loadBalancer;
AutoScalingGroup appFleet;
AutoScalingGroup dbFleet;


// Allow connections from anywhere
loadBalancer.connections.allowFromAnyIpv4(Port.HTTPS, "Allow inbound HTTPS");

// The same, but an explicit IP address
loadBalancer.connections.allowFrom(Peer.ipv4("1.2.3.4/32"), Port.HTTPS, "Allow inbound HTTPS");

// Allow connection between AutoScalingGroups
appFleet.connections.allowTo(dbFleet, Port.HTTPS, "App can call database");
csharp
ApplicationLoadBalancer loadBalancer;
AutoScalingGroup appFleet;
AutoScalingGroup dbFleet;


// Allow connections from anywhere
loadBalancer.Connections.AllowFromAnyIpv4(Port.HTTPS, "Allow inbound HTTPS");

// The same, but an explicit IP address
loadBalancer.Connections.AllowFrom(Peer.Ipv4("1.2.3.4/32"), Port.HTTPS, "Allow inbound HTTPS");

// Allow connection between AutoScalingGroups
appFleet.Connections.AllowTo(dbFleet, Port.HTTPS, "App can call database");
go
var loadBalancer ApplicationLoadBalancer
var appFleet AutoScalingGroup
var dbFleet AutoScalingGroup


// Allow connections from anywhere
loadBalancer.Connections.AllowFromAnyIpv4(ec2.Port_HTTPS(), jsii.String("Allow inbound HTTPS"))

// The same, but an explicit IP address
loadBalancer.Connections.AllowFrom(ec2.Peer_Ipv4(jsii.String("1.2.3.4/32")), ec2.Port_HTTPS(), jsii.String("Allow inbound HTTPS"))

// Allow connection between AutoScalingGroups
appFleet.connections.AllowTo(dbFleet, ec2.Port_HTTPS(), jsii.String("App can call database"))

Connection Peers ​

There are various classes that implement the connection peer part:

ts
declare const appFleet: autoscaling.AutoScalingGroup;
declare const dbFleet: autoscaling.AutoScalingGroup;

// Simple connection peers
let peer = ec2.Peer.ipv4('10.0.0.0/16');
peer = ec2.Peer.anyIpv4();
peer = ec2.Peer.ipv6('::0/0');
peer = ec2.Peer.anyIpv6();
appFleet.connections.allowTo(peer, ec2.Port.HTTPS, 'Allow outbound HTTPS');
python
# app_fleet: autoscaling.AutoScalingGroup
# db_fleet: autoscaling.AutoScalingGroup


# Simple connection peers
peer = ec2.Peer.ipv4("10.0.0.0/16")
peer = ec2.Peer.any_ipv4()
peer = ec2.Peer.ipv6("::0/0")
peer = ec2.Peer.any_ipv6()
app_fleet.connections.allow_to(peer, ec2.Port.HTTPS, "Allow outbound HTTPS")
java
AutoScalingGroup appFleet;
AutoScalingGroup dbFleet;


// Simple connection peers
IPeer peer = Peer.ipv4("10.0.0.0/16");
peer = Peer.anyIpv4();
peer = Peer.ipv6("::0/0");
peer = Peer.anyIpv6();
appFleet.connections.allowTo(peer, Port.HTTPS, "Allow outbound HTTPS");
csharp
AutoScalingGroup appFleet;
AutoScalingGroup dbFleet;


// Simple connection peers
var peer = Peer.Ipv4("10.0.0.0/16");
peer = Peer.AnyIpv4();
peer = Peer.Ipv6("::0/0");
peer = Peer.AnyIpv6();
appFleet.Connections.AllowTo(peer, Port.HTTPS, "Allow outbound HTTPS");
go
var appFleet AutoScalingGroup
var dbFleet AutoScalingGroup


// Simple connection peers
peer := ec2.Peer_Ipv4(jsii.String("10.0.0.0/16"))
peer = ec2.Peer_AnyIpv4()
peer = ec2.Peer_Ipv6(jsii.String("::0/0"))
peer = ec2.Peer_AnyIpv6()
appFleet.connections.AllowTo(peer, ec2.Port_HTTPS(), jsii.String("Allow outbound HTTPS"))

Any object that has a security group can itself be used as a connection peer:

ts
declare const fleet1: autoscaling.AutoScalingGroup;
declare const fleet2: autoscaling.AutoScalingGroup;
declare const appFleet: autoscaling.AutoScalingGroup;

// These automatically create appropriate ingress and egress rules in both security groups
fleet1.connections.allowTo(fleet2, ec2.Port.HTTP, 'Allow between fleets');

appFleet.connections.allowFromAnyIpv4(ec2.Port.HTTP, 'Allow from load balancer');
python
# fleet1: autoscaling.AutoScalingGroup
# fleet2: autoscaling.AutoScalingGroup
# app_fleet: autoscaling.AutoScalingGroup


# These automatically create appropriate ingress and egress rules in both security groups
fleet1.connections.allow_to(fleet2, ec2.Port.HTTP, "Allow between fleets")

app_fleet.connections.allow_from_any_ipv4(ec2.Port.HTTP, "Allow from load balancer")
java
AutoScalingGroup fleet1;
AutoScalingGroup fleet2;
AutoScalingGroup appFleet;


// These automatically create appropriate ingress and egress rules in both security groups
fleet1.connections.allowTo(fleet2, Port.HTTP, "Allow between fleets");

appFleet.connections.allowFromAnyIpv4(Port.HTTP, "Allow from load balancer");
csharp
AutoScalingGroup fleet1;
AutoScalingGroup fleet2;
AutoScalingGroup appFleet;


// These automatically create appropriate ingress and egress rules in both security groups
fleet1.Connections.AllowTo(fleet2, Port.HTTP, "Allow between fleets");

appFleet.Connections.AllowFromAnyIpv4(Port.HTTP, "Allow from load balancer");
go
var fleet1 AutoScalingGroup
var fleet2 AutoScalingGroup
var appFleet AutoScalingGroup


// These automatically create appropriate ingress and egress rules in both security groups
fleet1.connections.AllowTo(fleet2, ec2.Port_HTTP(), jsii.String("Allow between fleets"))

appFleet.connections.AllowFromAnyIpv4(ec2.Port_HTTP(), jsii.String("Allow from load balancer"))

A managed prefix list is also a connection peer:

ts
declare const appFleet: autoscaling.AutoScalingGroup;

const prefixList = new ec2.PrefixList(this, 'PrefixList', { maxEntries: 10 });
appFleet.connections.allowFrom(prefixList, ec2.Port.HTTPS);
python
# app_fleet: autoscaling.AutoScalingGroup


prefix_list = ec2.PrefixList(self, "PrefixList", max_entries=10)
app_fleet.connections.allow_from(prefix_list, ec2.Port.HTTPS)
java
AutoScalingGroup appFleet;


PrefixList prefixList = PrefixList.Builder.create(this, "PrefixList").maxEntries(10).build();
appFleet.connections.allowFrom(prefixList, Port.HTTPS);
csharp
AutoScalingGroup appFleet;


var prefixList = new PrefixList(this, "PrefixList", new PrefixListProps { MaxEntries = 10 });
appFleet.Connections.AllowFrom(prefixList, Port.HTTPS);
go
var appFleet AutoScalingGroup


prefixList := ec2.NewPrefixList(this, jsii.String("PrefixList"), &PrefixListProps{
	MaxEntries: jsii.Number(10),
})
appFleet.connections.AllowFrom(prefixList, ec2.Port_HTTPS())

Rule Configuration Interfaces ​

The IPeer interface provides type-safe methods for generating security group rule configurations. The toIngressRuleConfig() and toEgressRuleConfig() methods return strongly-typed interfaces instead of any, enabling better IDE autocompletion and compile-time type checking:

  • IngressRuleConfig: Configuration for ingress rules with properties like cidrIp, cidrIpv6, sourcePrefixListId, sourceSecurityGroupId, and sourceSecurityGroupOwnerId
  • EgressRuleConfig: Configuration for egress rules with properties like cidrIp, cidrIpv6, destinationPrefixListId, and destinationSecurityGroupId

Port Ranges ​

The connections that are allowed are specified by port ranges. A number of classes provide the connection specifier:

ts
ec2.Port.tcp(80)
ec2.Port.HTTPS
ec2.Port.tcpRange(60000, 65535)
ec2.Port.allTcp()
ec2.Port.allIcmp()
ec2.Port.allIcmpV6()
ec2.Port.allTraffic()
python
ec2.Port.tcp(80)
ec2.Port.HTTPS
ec2.Port.tcp_range(60000, 65535)
ec2.Port.all_tcp()
ec2.Port.all_icmp()
ec2.Port.all_icmp_v6()
ec2.Port.all_traffic()
java
Port.tcp(80);
Port.HTTPS;
Port.tcpRange(60000, 65535);
Port.allTcp();
Port.allIcmp();
Port.allIcmpV6();
Port.allTraffic();
csharp
Port.Tcp(80);
Port.HTTPS;
Port.TcpRange(60000, 65535);
Port.AllTcp();
Port.AllIcmp();
Port.AllIcmpV6();
Port.AllTraffic();
go
ec2.Port_Tcp(jsii.Number(80))
ec2.Port_HTTPS()
ec2.Port_TcpRange(jsii.Number(60000), jsii.Number(65535))
ec2.Port_AllTcp()
ec2.Port_AllIcmp()
ec2.Port_AllIcmpV6()
ec2.Port_AllTraffic()

NOTE: Not all protocols have corresponding helper methods. In the absence of a helper method, you can instantiate Port yourself with your own settings. You are also welcome to contribute new helper methods.

Default Ports ​

Some Constructs have default ports associated with them. For example, the listener of a load balancer does (it's the public port), or instances of an RDS database (it's the port the database is accepting connections on).

If the object you're calling the peering method on has a default port associated with it, you can call allowDefaultPortFrom() and omit the port specifier. If the argument has an associated default port, call allowDefaultPortTo().

For example:

ts
declare const listener: elbv2.ApplicationListener;
declare const appFleet: autoscaling.AutoScalingGroup;
declare const rdsDatabase: rds.DatabaseCluster;

// Port implicit in listener
listener.connections.allowDefaultPortFromAnyIpv4('Allow public');

// Port implicit in peer
appFleet.connections.allowDefaultPortTo(rdsDatabase, 'Fleet can access database');
python
# listener: elbv2.ApplicationListener
# app_fleet: autoscaling.AutoScalingGroup
# rds_database: rds.DatabaseCluster


# Port implicit in listener
listener.connections.allow_default_port_from_any_ipv4("Allow public")

# Port implicit in peer
app_fleet.connections.allow_default_port_to(rds_database, "Fleet can access database")
java
ApplicationListener listener;
AutoScalingGroup appFleet;
DatabaseCluster rdsDatabase;


// Port implicit in listener
listener.connections.allowDefaultPortFromAnyIpv4("Allow public");

// Port implicit in peer
appFleet.connections.allowDefaultPortTo(rdsDatabase, "Fleet can access database");
csharp
ApplicationListener listener;
AutoScalingGroup appFleet;
DatabaseCluster rdsDatabase;


// Port implicit in listener
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public");

// Port implicit in peer
appFleet.Connections.AllowDefaultPortTo(rdsDatabase, "Fleet can access database");
go
var listener ApplicationListener
var appFleet AutoScalingGroup
var rdsDatabase DatabaseCluster


// Port implicit in listener
listener.Connections.AllowDefaultPortFromAnyIpv4(jsii.String("Allow public"))

// Port implicit in peer
appFleet.connections.AllowDefaultPortTo(rdsDatabase, jsii.String("Fleet can access database"))

Security group rules ​

By default, security group wills be added inline to the security group in the output cloud formation template, if applicable. This includes any static rules by ip address and port range. This optimization helps to minimize the size of the template.

In some environments this is not desirable, for example if your security group access is controlled via tags. You can disable inline rules per security group or globally via the context key @aws-cdk/aws-ec2.securityGroupDisableInlineRules.

ts
const mySecurityGroupWithoutInlineRules = new ec2.SecurityGroup(this, 'SecurityGroup', {
  vpc,
  description: 'Allow ssh access to ec2 instances',
  allowAllOutbound: true,
  disableInlineRules: true
});
//This will add the rule as an external cloud formation construct
mySecurityGroupWithoutInlineRules.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.SSH, 'allow ssh access from the world');
python
my_security_group_without_inline_rules = ec2.SecurityGroup(self, "SecurityGroup",
    vpc=vpc,
    description="Allow ssh access to ec2 instances",
    allow_all_outbound=True,
    disable_inline_rules=True
)
# This will add the rule as an external cloud formation construct
my_security_group_without_inline_rules.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.SSH, "allow ssh access from the world")
java
SecurityGroup mySecurityGroupWithoutInlineRules = SecurityGroup.Builder.create(this, "SecurityGroup")
        .vpc(vpc)
        .description("Allow ssh access to ec2 instances")
        .allowAllOutbound(true)
        .disableInlineRules(true)
        .build();
//This will add the rule as an external cloud formation construct
mySecurityGroupWithoutInlineRules.addIngressRule(Peer.anyIpv4(), Port.SSH, "allow ssh access from the world");
csharp
var mySecurityGroupWithoutInlineRules = new SecurityGroup(this, "SecurityGroup", new SecurityGroupProps {
    Vpc = vpc,
    Description = "Allow ssh access to ec2 instances",
    AllowAllOutbound = true,
    DisableInlineRules = true
});
//This will add the rule as an external cloud formation construct
mySecurityGroupWithoutInlineRules.AddIngressRule(Peer.AnyIpv4(), Port.SSH, "allow ssh access from the world");
go
mySecurityGroupWithoutInlineRules := ec2.NewSecurityGroup(this, jsii.String("SecurityGroup"), &SecurityGroupProps{
	Vpc: Vpc,
	Description: jsii.String("Allow ssh access to ec2 instances"),
	AllowAllOutbound: jsii.Boolean(true),
	DisableInlineRules: jsii.Boolean(true),
})
//This will add the rule as an external cloud formation construct
mySecurityGroupWithoutInlineRules.AddIngressRule(ec2.Peer_AnyIpv4(), ec2.Port_SSH(), jsii.String("allow ssh access from the world"))

Importing an existing security group ​

If you know the ID and the configuration of the security group to import, you can use SecurityGroup.fromSecurityGroupId:

ts
const sg = ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroupImport', 'sg-1234', {
  allowAllOutbound: true,
});
python
sg = ec2.SecurityGroup.from_security_group_id(self, "SecurityGroupImport", "sg-1234",
    allow_all_outbound=True
)
java
ISecurityGroup sg = SecurityGroup.fromSecurityGroupId(this, "SecurityGroupImport", "sg-1234", SecurityGroupImportOptions.builder()
        .allowAllOutbound(true)
        .build());
csharp
var sg = SecurityGroup.FromSecurityGroupId(this, "SecurityGroupImport", "sg-1234", new SecurityGroupImportOptions {
    AllowAllOutbound = true
});
go
sg := ec2.SecurityGroup_FromSecurityGroupId(this, jsii.String("SecurityGroupImport"), jsii.String("sg-1234"), &SecurityGroupImportOptions{
	AllowAllOutbound: jsii.Boolean(true),
})

Alternatively, use lookup methods to import security groups if you do not know the ID or the configuration details. Method SecurityGroup.fromLookupByName looks up a security group if the security group ID is unknown.

ts
const sg = ec2.SecurityGroup.fromLookupByName(this, 'SecurityGroupLookup', 'security-group-name', vpc);
python
sg = ec2.SecurityGroup.from_lookup_by_name(self, "SecurityGroupLookup", "security-group-name", vpc)
java
ISecurityGroup sg = SecurityGroup.fromLookupByName(this, "SecurityGroupLookup", "security-group-name", vpc);
csharp
var sg = SecurityGroup.FromLookupByName(this, "SecurityGroupLookup", "security-group-name", vpc);
go
sg := ec2.SecurityGroup_FromLookupByName(this, jsii.String("SecurityGroupLookup"), jsii.String("security-group-name"), vpc)

If the security group ID is known and configuration details are unknown, use method SecurityGroup.fromLookupById instead. This method will lookup property allowAllOutbound from the current configuration of the security group.

ts
const sg = ec2.SecurityGroup.fromLookupById(this, 'SecurityGroupLookup', 'sg-1234');
python
sg = ec2.SecurityGroup.from_lookup_by_id(self, "SecurityGroupLookup", "sg-1234")
java
ISecurityGroup sg = SecurityGroup.fromLookupById(this, "SecurityGroupLookup", "sg-1234");
csharp
var sg = SecurityGroup.FromLookupById(this, "SecurityGroupLookup", "sg-1234");
go
sg := ec2.SecurityGroup_FromLookupById(this, jsii.String("SecurityGroupLookup"), jsii.String("sg-1234"))

The result of SecurityGroup.fromLookupByName and SecurityGroup.fromLookupById operations will be written to a file called cdk.context.json. You must commit this file to source control so that the lookup values are available in non-privileged environments such as CI build steps, and to ensure your template builds are repeatable.

Cross Stack Connections ​

If you are attempting to add a connection from a peer in one stack to a peer in a different stack, sometimes it is necessary to ensure that you are making the connection in a specific stack in order to avoid a cyclic reference. If there are no other dependencies between stacks then it will not matter in which stack you make the connection, but if there are existing dependencies (i.e. stack1 already depends on stack2), then it is important to make the connection in the dependent stack (i.e. stack1).

Whenever you make a connections function call, the ingress and egress security group rules will be added to the stack that the calling object exists in. So if you are doing something like peer1.connections.allowFrom(peer2), then the security group rules (both ingress and egress) will be created in peer1's Stack.

As an example, if we wanted to allow a connection from a security group in one stack (egress) to a security group in a different stack (ingress), we would make the connection like:

If Stack1 depends on Stack2

ts
// Stack 1
declare const stack1: Stack;
declare const stack2: Stack;

const sg1 = new ec2.SecurityGroup(stack1, 'SG1', {
  allowAllOutbound: false, // if this is `true` then no egress rule will be created
  vpc,
});

// Stack 2
const sg2 = new ec2.SecurityGroup(stack2, 'SG2', {
  allowAllOutbound: false, // if this is `true` then no egress rule will be created
  vpc,
});


// `connections.allowTo` on `sg1` since we want the
// rules to be created in Stack1
sg1.connections.allowTo(sg2, ec2.Port.tcp(3333));
python
# Stack 1
# stack1: Stack
# stack2: Stack


sg1 = ec2.SecurityGroup(stack1, "SG1",
    allow_all_outbound=False,  # if this is `true` then no egress rule will be created
    vpc=vpc
)

# Stack 2
sg2 = ec2.SecurityGroup(stack2, "SG2",
    allow_all_outbound=False,  # if this is `true` then no egress rule will be created
    vpc=vpc
)

# `connections.allowTo` on `sg1` since we want the
# rules to be created in Stack1
sg1.connections.allow_to(sg2, ec2.Port.tcp(3333))
java
// Stack 1
Stack stack1;
Stack stack2;


SecurityGroup sg1 = SecurityGroup.Builder.create(stack1, "SG1")
        .allowAllOutbound(false) // if this is `true` then no egress rule will be created
        .vpc(vpc)
        .build();

// Stack 2
SecurityGroup sg2 = SecurityGroup.Builder.create(stack2, "SG2")
        .allowAllOutbound(false) // if this is `true` then no egress rule will be created
        .vpc(vpc)
        .build();

// `connections.allowTo` on `sg1` since we want the
// rules to be created in Stack1
sg1.connections.allowTo(sg2, Port.tcp(3333));
csharp
// Stack 1
Stack stack1;
Stack stack2;


var sg1 = new SecurityGroup(stack1, "SG1", new SecurityGroupProps {
    AllowAllOutbound = false,  // if this is `true` then no egress rule will be created
    Vpc = vpc
});

// Stack 2
var sg2 = new SecurityGroup(stack2, "SG2", new SecurityGroupProps {
    AllowAllOutbound = false,  // if this is `true` then no egress rule will be created
    Vpc = vpc
});

// `connections.allowTo` on `sg1` since we want the
// rules to be created in Stack1
sg1.Connections.AllowTo(sg2, Port.Tcp(3333));
go
// Stack 1
var stack1 Stack
var stack2 Stack


sg1 := ec2.NewSecurityGroup(stack1, jsii.String("SG1"), &SecurityGroupProps{
	AllowAllOutbound: jsii.Boolean(false),
	 // if this is `true` then no egress rule will be created
	Vpc: Vpc,
})

// Stack 2
sg2 := ec2.NewSecurityGroup(stack2, jsii.String("SG2"), &SecurityGroupProps{
	AllowAllOutbound: jsii.Boolean(false),
	 // if this is `true` then no egress rule will be created
	Vpc: Vpc,
})

// `connections.allowTo` on `sg1` since we want the
// rules to be created in Stack1
sg1.connections.AllowTo(sg2, ec2.Port_Tcp(jsii.Number(3333)))

In this case both the Ingress Rule for sg2 and the Egress Rule for sg1 will both be created in Stack 1 which avoids the cyclic reference.

If Stack2 depends on Stack1

ts
// Stack 1
declare const stack1: Stack;
declare const stack2: Stack;

const sg1 = new ec2.SecurityGroup(stack1, 'SG1', {
  allowAllOutbound: false, // if this is `true` then no egress rule will be created
  vpc,
});

// Stack 2
const sg2 = new ec2.SecurityGroup(stack2, 'SG2', {
  allowAllOutbound: false, // if this is `true` then no egress rule will be created
  vpc,
});


// `connections.allowFrom` on `sg2` since we want the
// rules to be created in Stack2
sg2.connections.allowFrom(sg1, ec2.Port.tcp(3333));
python
# Stack 1
# stack1: Stack
# stack2: Stack


sg1 = ec2.SecurityGroup(stack1, "SG1",
    allow_all_outbound=False,  # if this is `true` then no egress rule will be created
    vpc=vpc
)

# Stack 2
sg2 = ec2.SecurityGroup(stack2, "SG2",
    allow_all_outbound=False,  # if this is `true` then no egress rule will be created
    vpc=vpc
)

# `connections.allowFrom` on `sg2` since we want the
# rules to be created in Stack2
sg2.connections.allow_from(sg1, ec2.Port.tcp(3333))
java
// Stack 1
Stack stack1;
Stack stack2;


SecurityGroup sg1 = SecurityGroup.Builder.create(stack1, "SG1")
        .allowAllOutbound(false) // if this is `true` then no egress rule will be created
        .vpc(vpc)
        .build();

// Stack 2
SecurityGroup sg2 = SecurityGroup.Builder.create(stack2, "SG2")
        .allowAllOutbound(false) // if this is `true` then no egress rule will be created
        .vpc(vpc)
        .build();

// `connections.allowFrom` on `sg2` since we want the
// rules to be created in Stack2
sg2.connections.allowFrom(sg1, Port.tcp(3333));
csharp
// Stack 1
Stack stack1;
Stack stack2;


var sg1 = new SecurityGroup(stack1, "SG1", new SecurityGroupProps {
    AllowAllOutbound = false,  // if this is `true` then no egress rule will be created
    Vpc = vpc
});

// Stack 2
var sg2 = new SecurityGroup(stack2, "SG2", new SecurityGroupProps {
    AllowAllOutbound = false,  // if this is `true` then no egress rule will be created
    Vpc = vpc
});

// `connections.allowFrom` on `sg2` since we want the
// rules to be created in Stack2
sg2.Connections.AllowFrom(sg1, Port.Tcp(3333));
go
// Stack 1
var stack1 Stack
var stack2 Stack


sg1 := ec2.NewSecurityGroup(stack1, jsii.String("SG1"), &SecurityGroupProps{
	AllowAllOutbound: jsii.Boolean(false),
	 // if this is `true` then no egress rule will be created
	Vpc: Vpc,
})

// Stack 2
sg2 := ec2.NewSecurityGroup(stack2, jsii.String("SG2"), &SecurityGroupProps{
	AllowAllOutbound: jsii.Boolean(false),
	 // if this is `true` then no egress rule will be created
	Vpc: Vpc,
})

// `connections.allowFrom` on `sg2` since we want the
// rules to be created in Stack2
sg2.connections.AllowFrom(sg1, ec2.Port_Tcp(jsii.Number(3333)))

In this case both the Ingress Rule for sg2 and the Egress Rule for sg1 will both be created in Stack 2 which avoids the cyclic reference.

Machine Images (AMIs) ​

AMIs control the OS that gets launched when you start your EC2 instance. The EC2 library contains constructs to select the AMI you want to use.

Depending on the type of AMI, you select it a different way. Here are some examples of images you might want to use:

ts
// Pick the right Amazon Linux edition. All arguments shown are optional
// and will default to these values when omitted.
const amznLinux = ec2.MachineImage.latestAmazonLinux({
  generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX,
  edition: ec2.AmazonLinuxEdition.STANDARD,
  virtualization: ec2.AmazonLinuxVirt.HVM,
  storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
  cpuType: ec2.AmazonLinuxCpuType.X86_64,
});

// Pick a Windows edition to use
const windows = ec2.MachineImage.latestWindows(ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE);

// Read AMI id from SSM parameter store
const ssm = ec2.MachineImage.fromSsmParameter('/my/ami', { os: ec2.OperatingSystemType.LINUX });

// Look up the most recent image matching a set of AMI filters.
// In this case, look up the NAT instance AMI, by using a wildcard
// in the 'name' field:
const natAmi = ec2.MachineImage.lookup({
  name: 'amzn-ami-vpc-nat-*',
  owners: ['amazon'],
});

// For other custom (Linux) images, instantiate a `GenericLinuxImage` with
// a map giving the AMI to in for each region:
const linux = ec2.MachineImage.genericLinux({
  'us-east-1': 'ami-97785bed',
  'eu-west-1': 'ami-12345678',
  // ...
});

// For other custom (Windows) images, instantiate a `GenericWindowsImage` with
// a map giving the AMI to in for each region:
const genericWindows = ec2.MachineImage.genericWindows({
  'us-east-1': 'ami-97785bed',
  'eu-west-1': 'ami-12345678',
  // ...
});
python
# Pick the right Amazon Linux edition. All arguments shown are optional
# and will default to these values when omitted.
amzn_linux = ec2.MachineImage.latest_amazon_linux(
    generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX,
    edition=ec2.AmazonLinuxEdition.STANDARD,
    virtualization=ec2.AmazonLinuxVirt.HVM,
    storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
    cpu_type=ec2.AmazonLinuxCpuType.X86_64
)

# Pick a Windows edition to use
windows = ec2.MachineImage.latest_windows(ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE)

# Read AMI id from SSM parameter store
ssm = ec2.MachineImage.from_ssm_parameter("/my/ami", os=ec2.OperatingSystemType.LINUX)

# Look up the most recent image matching a set of AMI filters.
# In this case, look up the NAT instance AMI, by using a wildcard
# in the 'name' field:
nat_ami = ec2.MachineImage.lookup(
    name="amzn-ami-vpc-nat-*",
    owners=["amazon"]
)

# For other custom (Linux) images, instantiate a `GenericLinuxImage` with
# a map giving the AMI to in for each region:
linux = ec2.MachineImage.generic_linux({
    "us-east-1": "ami-97785bed",
    "eu-west-1": "ami-12345678"
})

# For other custom (Windows) images, instantiate a `GenericWindowsImage` with
# a map giving the AMI to in for each region:
generic_windows = ec2.MachineImage.generic_windows({
    "us-east-1": "ami-97785bed",
    "eu-west-1": "ami-12345678"
})
java
// Pick the right Amazon Linux edition. All arguments shown are optional
// and will default to these values when omitted.
IMachineImage amznLinux = MachineImage.latestAmazonLinux(AmazonLinuxImageProps.builder()
        .generation(AmazonLinuxGeneration.AMAZON_LINUX)
        .edition(AmazonLinuxEdition.STANDARD)
        .virtualization(AmazonLinuxVirt.HVM)
        .storage(AmazonLinuxStorage.GENERAL_PURPOSE)
        .cpuType(AmazonLinuxCpuType.X86_64)
        .build());

// Pick a Windows edition to use
IMachineImage windows = MachineImage.latestWindows(WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE);

// Read AMI id from SSM parameter store
IMachineImage ssm = MachineImage.fromSsmParameter("/my/ami", SsmParameterImageOptions.builder().os(OperatingSystemType.LINUX).build());

// Look up the most recent image matching a set of AMI filters.
// In this case, look up the NAT instance AMI, by using a wildcard
// in the 'name' field:
IMachineImage natAmi = MachineImage.lookup(LookupMachineImageProps.builder()
        .name("amzn-ami-vpc-nat-*")
        .owners(List.of("amazon"))
        .build());

// For other custom (Linux) images, instantiate a `GenericLinuxImage` with
// a map giving the AMI to in for each region:
IMachineImage linux = MachineImage.genericLinux(Map.of(
        "us-east-1", "ami-97785bed",
        "eu-west-1", "ami-12345678"));

// For other custom (Windows) images, instantiate a `GenericWindowsImage` with
// a map giving the AMI to in for each region:
IMachineImage genericWindows = MachineImage.genericWindows(Map.of(
        "us-east-1", "ami-97785bed",
        "eu-west-1", "ami-12345678"));
csharp
// Pick the right Amazon Linux edition. All arguments shown are optional
// and will default to these values when omitted.
var amznLinux = MachineImage.LatestAmazonLinux(new AmazonLinuxImageProps {
    Generation = AmazonLinuxGeneration.AMAZON_LINUX,
    Edition = AmazonLinuxEdition.STANDARD,
    Virtualization = AmazonLinuxVirt.HVM,
    Storage = AmazonLinuxStorage.GENERAL_PURPOSE,
    CpuType = AmazonLinuxCpuType.X86_64
});

// Pick a Windows edition to use
var windows = MachineImage.LatestWindows(WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE);

// Read AMI id from SSM parameter store
var ssm = MachineImage.FromSsmParameter("/my/ami", new SsmParameterImageOptions { Os = OperatingSystemType.LINUX });

// Look up the most recent image matching a set of AMI filters.
// In this case, look up the NAT instance AMI, by using a wildcard
// in the 'name' field:
var natAmi = MachineImage.Lookup(new LookupMachineImageProps {
    Name = "amzn-ami-vpc-nat-*",
    Owners = new [] { "amazon" }
});

// For other custom (Linux) images, instantiate a `GenericLinuxImage` with
// a map giving the AMI to in for each region:
var linux = MachineImage.GenericLinux(new Dictionary<string, string> {
    { "us-east-1", "ami-97785bed" },
    { "eu-west-1", "ami-12345678" }
});

// For other custom (Windows) images, instantiate a `GenericWindowsImage` with
// a map giving the AMI to in for each region:
var genericWindows = MachineImage.GenericWindows(new Dictionary<string, string> {
    { "us-east-1", "ami-97785bed" },
    { "eu-west-1", "ami-12345678" }
});
go
// Pick the right Amazon Linux edition. All arguments shown are optional
// and will default to these values when omitted.
amznLinux := ec2.MachineImage_LatestAmazonLinux(&AmazonLinuxImageProps{
	Generation: ec2.AmazonLinuxGeneration_AMAZON_LINUX,
	Edition: ec2.AmazonLinuxEdition_STANDARD,
	Virtualization: ec2.AmazonLinuxVirt_HVM,
	Storage: ec2.AmazonLinuxStorage_GENERAL_PURPOSE,
	CpuType: ec2.AmazonLinuxCpuType_X86_64,
})

// Pick a Windows edition to use
windows := ec2.MachineImage_LatestWindows(ec2.WindowsVersion_WINDOWS_SERVER_2019_ENGLISH_FULL_BASE)

// Read AMI id from SSM parameter store
ssm := ec2.MachineImage_FromSsmParameter(jsii.String("/my/ami"), &SsmParameterImageOptions{
	Os: ec2.OperatingSystemType_LINUX,
})

// Look up the most recent image matching a set of AMI filters.
// In this case, look up the NAT instance AMI, by using a wildcard
// in the 'name' field:
natAmi := ec2.MachineImage_Lookup(&LookupMachineImageProps{
	Name: jsii.String("amzn-ami-vpc-nat-*"),
	Owners: []*string{
		jsii.String("amazon"),
	},
})

// For other custom (Linux) images, instantiate a `GenericLinuxImage` with
// a map giving the AMI to in for each region:
linux := ec2.MachineImage_GenericLinux(map[string]*string{
	"us-east-1": jsii.String("ami-97785bed"),
	"eu-west-1": jsii.String("ami-12345678"),
})

// For other custom (Windows) images, instantiate a `GenericWindowsImage` with
// a map giving the AMI to in for each region:
genericWindows := ec2.MachineImage_GenericWindows(map[string]*string{
	"us-east-1": jsii.String("ami-97785bed"),
	"eu-west-1": jsii.String("ami-12345678"),
})

NOTE: The AMIs selected by MachineImage.lookup() will be cached in cdk.context.json, so that your AutoScalingGroup instances aren't replaced while you are making unrelated changes to your CDK app.

To query for the latest AMI again, remove the relevant cache entry from cdk.context.json, or use the cdk context command. For more information, see Runtime Context in the CDK developer guide.

To customize the cache key, use the additionalCacheKey parameter. This allows you to have multiple lookups with the same parameters cache their values separately. This can be useful if you want to scope the context variable to a construct (ie, using additionalCacheKey: this.node.path), so that if the value in the cache needs to be updated, it does not need to be updated for all constructs at the same time.

MachineImage.genericLinux(), MachineImage.genericWindows() will use CfnMapping in an agnostic stack.

Special VPC configurations ​

VPN connections to a VPC ​

Create your VPC with VPN connections by specifying the vpnConnections props (keys are construct ids):

ts
import { SecretValue } from 'aws-cdk-lib/core';

const vpc = new ec2.Vpc(this, 'MyVpc', {
  vpnConnections: {
    dynamic: { // Dynamic routing (BGP)
      ip: '1.2.3.4',
      tunnelOptions: [
        {
          preSharedKeySecret: SecretValue.unsafePlainText('secretkey1234'),
        },
        {
          preSharedKeySecret: SecretValue.unsafePlainText('secretkey5678'),
        },
      ],
    },
    static: { // Static routing
      ip: '4.5.6.7',
      staticRoutes: [
        '192.168.10.0/24',
        '192.168.20.0/24'
      ]
    }
  }
});
python
from aws_cdk import SecretValue


vpc = ec2.Vpc(self, "MyVpc",
    vpn_connections={
        "dynamic": ec2.VpnConnectionOptions( # Dynamic routing (BGP)
            ip="1.2.3.4",
            tunnel_options=[ec2.VpnTunnelOption(
                pre_shared_key_secret=SecretValue.unsafe_plain_text("secretkey1234")
            ), ec2.VpnTunnelOption(
                pre_shared_key_secret=SecretValue.unsafe_plain_text("secretkey5678")
            )
            ]),
        "static": ec2.VpnConnectionOptions( # Static routing
            ip="4.5.6.7",
            static_routes=["192.168.10.0/24", "192.168.20.0/24"
            ])
    }
)
java
import software.amazon.awscdk.SecretValue;


Vpc vpc = Vpc.Builder.create(this, "MyVpc")
        .vpnConnections(Map.of(
                "dynamic", VpnConnectionOptions.builder() // Dynamic routing (BGP)
                        .ip("1.2.3.4")
                        .tunnelOptions(List.of(VpnTunnelOption.builder()
                                .preSharedKeySecret(SecretValue.unsafePlainText("secretkey1234"))
                                .build(), VpnTunnelOption.builder()
                                .preSharedKeySecret(SecretValue.unsafePlainText("secretkey5678"))
                                .build())).build(),
                "static", VpnConnectionOptions.builder() // Static routing
                        .ip("4.5.6.7")
                        .staticRoutes(List.of("192.168.10.0/24", "192.168.20.0/24")).build()))
        .build();
csharp
using Amazon.CDK;


var vpc = new Vpc(this, "MyVpc", new VpcProps {
    VpnConnections = new Dictionary<string, VpnConnectionOptions> {
        { "dynamic", new VpnConnectionOptions {  // Dynamic routing (BGP)
            Ip = "1.2.3.4",
            TunnelOptions = new [] { new VpnTunnelOption {
                PreSharedKeySecret = SecretValue.UnsafePlainText("secretkey1234")
            }, new VpnTunnelOption {
                PreSharedKeySecret = SecretValue.UnsafePlainText("secretkey5678")
            } } } },
        { "static", new VpnConnectionOptions {  // Static routing
            Ip = "4.5.6.7",
            StaticRoutes = new [] { "192.168.10.0/24", "192.168.20.0/24" } } }
    }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


vpc := ec2.NewVpc(this, jsii.String("MyVpc"), &VpcProps{
	VpnConnections: map[string]VpnConnectionOptions{
		"dynamic": &VpnConnectionOptions{
			 // Dynamic routing (BGP)
			"ip": jsii.String("1.2.3.4"),
			"tunnelOptions": []VpnTunnelOption{
				&VpnTunnelOption{
					"preSharedKeySecret": awscdk.SecretValue_unsafePlainText(jsii.String("secretkey1234")),
				},
				&VpnTunnelOption{
					"preSharedKeySecret": awscdk.SecretValue_unsafePlainText(jsii.String("secretkey5678")),
				},
			},
		},
		"static": &VpnConnectionOptions{
			 // Static routing
			"ip": jsii.String("4.5.6.7"),
			"staticRoutes": []*string{
				jsii.String("192.168.10.0/24"),
				jsii.String("192.168.20.0/24"),
			},
		},
	},
})

To create a VPC that can accept VPN connections, set vpnGateway to true:

ts
const vpc = new ec2.Vpc(this, 'MyVpc', {
  vpnGateway: true
});
python
vpc = ec2.Vpc(self, "MyVpc",
    vpn_gateway=True
)
java
Vpc vpc = Vpc.Builder.create(this, "MyVpc")
        .vpnGateway(true)
        .build();
csharp
var vpc = new Vpc(this, "MyVpc", new VpcProps {
    VpnGateway = true
});
go
vpc := ec2.NewVpc(this, jsii.String("MyVpc"), &VpcProps{
	VpnGateway: jsii.Boolean(true),
})

VPN connections can then be added:

ts
vpc.addVpnConnection('Dynamic', {
  ip: '1.2.3.4'
});
python
vpc.add_vpn_connection("Dynamic",
    ip="1.2.3.4"
)
java
vpc.addVpnConnection("Dynamic", VpnConnectionOptions.builder()
        .ip("1.2.3.4")
        .build());
csharp
vpc.AddVpnConnection("Dynamic", new VpnConnectionOptions {
    Ip = "1.2.3.4"
});
go
vpc.addVpnConnection(jsii.String("Dynamic"), &VpnConnectionOptions{
	Ip: jsii.String("1.2.3.4"),
})

By default, routes will be propagated on the route tables associated with the private subnets. If no private subnets exist, isolated subnets are used. If no isolated subnets exist, public subnets are used. Use the Vpc property vpnRoutePropagation to customize this behavior.

VPN connections expose metrics (cloudwatch.Metric) across all tunnels in the account/region and per connection:

ts
// Across all tunnels in the account/region
const allDataOut = ec2.VpnConnection.metricAllTunnelDataOut();

// For a specific vpn connection
const vpnConnection = vpc.addVpnConnection('Dynamic', {
  ip: '1.2.3.4'
});
const state = vpnConnection.metricTunnelState();
python
# Across all tunnels in the account/region
all_data_out = ec2.VpnConnection.metric_all_tunnel_data_out()

# For a specific vpn connection
vpn_connection = vpc.add_vpn_connection("Dynamic",
    ip="1.2.3.4"
)
state = vpn_connection.metric_tunnel_state()
java
// Across all tunnels in the account/region
Metric allDataOut = VpnConnection.metricAllTunnelDataOut();

// For a specific vpn connection
VpnConnection vpnConnection = vpc.addVpnConnection("Dynamic", VpnConnectionOptions.builder()
        .ip("1.2.3.4")
        .build());
Metric state = vpnConnection.metricTunnelState();
csharp
// Across all tunnels in the account/region
var allDataOut = VpnConnection.MetricAllTunnelDataOut();

// For a specific vpn connection
var vpnConnection = vpc.AddVpnConnection("Dynamic", new VpnConnectionOptions {
    Ip = "1.2.3.4"
});
var state = vpnConnection.MetricTunnelState();
go
// Across all tunnels in the account/region
allDataOut := ec2.VpnConnection_MetricAllTunnelDataOut()

// For a specific vpn connection
vpnConnection := vpc.addVpnConnection(jsii.String("Dynamic"), &VpnConnectionOptions{
	Ip: jsii.String("1.2.3.4"),
})
state := vpnConnection.metricTunnelState()

VPC endpoints ​

A VPC endpoint enables you to privately connect your VPC to supported AWS services and VPC endpoint services powered by PrivateLink without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC do not require public IP addresses to communicate with resources in the service. Traffic between your VPC and the other service does not leave the Amazon network.

Endpoints are virtual devices. They are horizontally scaled, redundant, and highly available VPC components that allow communication between instances in your VPC and services without imposing availability risks or bandwidth constraints on your network traffic.

ts
    // Add gateway endpoints when creating the VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      gatewayEndpoints: {
        S3: {
          service: ec2.GatewayVpcEndpointAwsService.S3,
        },
      },
    });

    // Alternatively gateway endpoints can be added on the VPC
    const dynamoDbEndpoint = vpc.addGatewayEndpoint('DynamoDbEndpoint', {
      service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,
    });

    // This allows to customize the endpoint policy
    dynamoDbEndpoint.addToPolicy(
      new iam.PolicyStatement({ // Restrict to listing and describing tables
        principals: [new iam.AnyPrincipal()],
        actions: ['dynamodb:DescribeTable', 'dynamodb:ListTables'],
        resources: ['*'],
      }));

    // Add an interface endpoint
    vpc.addInterfaceEndpoint('EcrDockerEndpoint', {
      service: ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER,

      // Uncomment the following to allow more fine-grained control over
      // who can access the endpoint via the '.connections' object.
      // open: false
    });
python
# Add gateway endpoints when creating the VPC
vpc = ec2.Vpc(self, "MyVpc",
    gateway_endpoints={
        "S3": cdk.aws_ec2.GatewayVpcEndpointOptions(
            service=ec2.GatewayVpcEndpointAwsService.S3
        )
    }
)

# Alternatively gateway endpoints can be added on the VPC
dynamo_db_endpoint = vpc.add_gateway_endpoint("DynamoDbEndpoint",
    service=ec2.GatewayVpcEndpointAwsService.DYNAMODB
)

# This allows to customize the endpoint policy
dynamo_db_endpoint.add_to_policy(
    iam.PolicyStatement( # Restrict to listing and describing tables
        principals=[iam.AnyPrincipal()],
        actions=["dynamodb:DescribeTable", "dynamodb:ListTables"],
        resources=["*"]))

# Add an interface endpoint
vpc.add_interface_endpoint("EcrDockerEndpoint",
    service=ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER
)
java
// Add gateway endpoints when creating the VPC
Vpc vpc = Vpc.Builder.create(this, "MyVpc")
        .gatewayEndpoints(Map.of(
                "S3", GatewayVpcEndpointOptions.builder()
                        .service(GatewayVpcEndpointAwsService.S3)
                        .build()))
        .build();

// Alternatively gateway endpoints can be added on the VPC
GatewayVpcEndpoint dynamoDbEndpoint = vpc.addGatewayEndpoint("DynamoDbEndpoint", GatewayVpcEndpointOptions.builder()
        .service(GatewayVpcEndpointAwsService.DYNAMODB)
        .build());

// This allows to customize the endpoint policy
dynamoDbEndpoint.addToPolicy(
PolicyStatement.Builder.create() // Restrict to listing and describing tables
        .principals(List.of(new AnyPrincipal()))
        .actions(List.of("dynamodb:DescribeTable", "dynamodb:ListTables"))
        .resources(List.of("*")).build());

// Add an interface endpoint
vpc.addInterfaceEndpoint("EcrDockerEndpoint", InterfaceVpcEndpointOptions.builder()
        .service(InterfaceVpcEndpointAwsService.ECR_DOCKER)
        .build());
csharp
// Add gateway endpoints when creating the VPC
var vpc = new Vpc(this, "MyVpc", new VpcProps {
    GatewayEndpoints = new Dictionary<string, GatewayVpcEndpointOptions> {
        { "S3", new GatewayVpcEndpointOptions {
            Service = GatewayVpcEndpointAwsService.S3
        } }
    }
});

// Alternatively gateway endpoints can be added on the VPC
var dynamoDbEndpoint = vpc.AddGatewayEndpoint("DynamoDbEndpoint", new GatewayVpcEndpointOptions {
    Service = GatewayVpcEndpointAwsService.DYNAMODB
});

// This allows to customize the endpoint policy
dynamoDbEndpoint.AddToPolicy(
new PolicyStatement(new PolicyStatementProps {  // Restrict to listing and describing tables
    Principals = new [] { new AnyPrincipal() },
    Actions = new [] { "dynamodb:DescribeTable", "dynamodb:ListTables" },
    Resources = new [] { "*" } }));

// Add an interface endpoint
vpc.AddInterfaceEndpoint("EcrDockerEndpoint", new InterfaceVpcEndpointOptions {
    Service = InterfaceVpcEndpointAwsService.ECR_DOCKER
});
go
// Add gateway endpoints when creating the VPC
vpc := ec2.NewVpc(this, jsii.String("MyVpc"), &VpcProps{
	GatewayEndpoints: map[string]GatewayVpcEndpointOptions{
		"S3": &GatewayVpcEndpointOptions{
			"service": ec2.GatewayVpcEndpointAwsService_S3(),
		},
	},
})

// Alternatively gateway endpoints can be added on the VPC
dynamoDbEndpoint := vpc.addGatewayEndpoint(jsii.String("DynamoDbEndpoint"), &GatewayVpcEndpointOptions{
	Service: ec2.GatewayVpcEndpointAwsService_DYNAMODB(),
})

// This allows to customize the endpoint policy
dynamoDbEndpoint.AddToPolicy(
iam.NewPolicyStatement(&PolicyStatementProps{
	 // Restrict to listing and describing tables
	Principals: []IPrincipal{
		iam.NewAnyPrincipal(),
	},
	Actions: []*string{
		jsii.String("dynamodb:DescribeTable"),
		jsii.String("dynamodb:ListTables"),
	},
	Resources: []*string{
		jsii.String("*"),
	},
}))

// Add an interface endpoint
vpc.addInterfaceEndpoint(jsii.String("EcrDockerEndpoint"), &InterfaceVpcEndpointOptions{
	Service: ec2.InterfaceVpcEndpointAwsService_ECR_DOCKER(),
})

By default, CDK will place a VPC endpoint in one subnet per AZ. If you wish to override the AZs CDK places the VPC endpoint in, use the subnets parameter as follows:

ts
declare const vpc: ec2.Vpc;

new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', {
  vpc,
  service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443),
  // Choose which availability zones to place the VPC endpoint in, based on
  // available AZs
  subnets: {
    availabilityZones: ['us-east-1a', 'us-east-1c']
  }
});
python
# vpc: ec2.Vpc


ec2.InterfaceVpcEndpoint(self, "VPC Endpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    # Choose which availability zones to place the VPC endpoint in, based on
    # available AZs
    subnets=ec2.SubnetSelection(
        availability_zones=["us-east-1a", "us-east-1c"]
    )
)
java
Vpc vpc;


InterfaceVpcEndpoint.Builder.create(this, "VPC Endpoint")
        .vpc(vpc)
        .service(new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443))
        // Choose which availability zones to place the VPC endpoint in, based on
        // available AZs
        .subnets(SubnetSelection.builder()
                .availabilityZones(List.of("us-east-1a", "us-east-1c"))
                .build())
        .build();
csharp
Vpc vpc;


new InterfaceVpcEndpoint(this, "VPC Endpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    // Choose which availability zones to place the VPC endpoint in, based on
    // available AZs
    Subnets = new SubnetSelection {
        AvailabilityZones = new [] { "us-east-1a", "us-east-1c" }
    }
});
go
var vpc Vpc


ec2.NewInterfaceVpcEndpoint(this, jsii.String("VPC Endpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.NewInterfaceVpcEndpointService(jsii.String("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc"), jsii.Number(443)),
	// Choose which availability zones to place the VPC endpoint in, based on
	// available AZs
	Subnets: &SubnetSelection{
		AvailabilityZones: []*string{
			jsii.String("us-east-1a"),
			jsii.String("us-east-1c"),
		},
	},
})

Per the AWS documentation, not all VPC endpoint services are available in all AZs. If you specify the parameter lookupSupportedAzs, CDK attempts to discover which AZs an endpoint service is available in, and will ensure the VPC endpoint is not placed in a subnet that doesn't match those AZs. These AZs will be stored in cdk.context.json.

ts
declare const vpc: ec2.Vpc;

new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', {
  vpc,
  service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443),
  // Choose which availability zones to place the VPC endpoint in, based on
  // available AZs
  lookupSupportedAzs: true
});
python
# vpc: ec2.Vpc


ec2.InterfaceVpcEndpoint(self, "VPC Endpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    # Choose which availability zones to place the VPC endpoint in, based on
    # available AZs
    lookup_supported_azs=True
)
java
Vpc vpc;


InterfaceVpcEndpoint.Builder.create(this, "VPC Endpoint")
        .vpc(vpc)
        .service(new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443))
        // Choose which availability zones to place the VPC endpoint in, based on
        // available AZs
        .lookupSupportedAzs(true)
        .build();
csharp
Vpc vpc;


new InterfaceVpcEndpoint(this, "VPC Endpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    // Choose which availability zones to place the VPC endpoint in, based on
    // available AZs
    LookupSupportedAzs = true
});
go
var vpc Vpc


ec2.NewInterfaceVpcEndpoint(this, jsii.String("VPC Endpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.NewInterfaceVpcEndpointService(jsii.String("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc"), jsii.Number(443)),
	// Choose which availability zones to place the VPC endpoint in, based on
	// available AZs
	LookupSupportedAzs: jsii.Boolean(true),
})

Pre-defined AWS services are defined in the InterfaceVpcEndpointAwsService class, and can be used to create VPC endpoints without having to configure name, ports, etc. For example, a Keyspaces endpoint can be created for use in your VPC:

ts
declare const vpc: ec2.Vpc;

new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', {
  vpc,
  service: ec2.InterfaceVpcEndpointAwsService.KEYSPACES,
});
python
# vpc: ec2.Vpc


ec2.InterfaceVpcEndpoint(self, "VPC Endpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointAwsService.KEYSPACES
)
java
Vpc vpc;


InterfaceVpcEndpoint.Builder.create(this, "VPC Endpoint")
        .vpc(vpc)
        .service(InterfaceVpcEndpointAwsService.KEYSPACES)
        .build();
csharp
Vpc vpc;


new InterfaceVpcEndpoint(this, "VPC Endpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = InterfaceVpcEndpointAwsService.KEYSPACES
});
go
var vpc Vpc


ec2.NewInterfaceVpcEndpoint(this, jsii.String("VPC Endpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.InterfaceVpcEndpointAwsService_KEYSPACES(),
})

For cross-region VPC endpoints, specify the serviceRegion parameter:

ts
declare const vpc: ec2.Vpc;

new ec2.InterfaceVpcEndpoint(this, 'CrossRegionEndpoint', {
  vpc,
  service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-123456', 443),
  serviceRegion: 'us-east-1', // Same region as the service endpoint above
});
python
# vpc: ec2.Vpc


ec2.InterfaceVpcEndpoint(self, "CrossRegionEndpoint",
    vpc=vpc,
    service=ec2.InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-123456", 443),
    service_region="us-east-1"
)
java
Vpc vpc;


InterfaceVpcEndpoint.Builder.create(this, "CrossRegionEndpoint")
        .vpc(vpc)
        .service(new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-123456", 443))
        .serviceRegion("us-east-1")
        .build();
csharp
Vpc vpc;


new InterfaceVpcEndpoint(this, "CrossRegionEndpoint", new InterfaceVpcEndpointProps {
    Vpc = vpc,
    Service = new InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-123456", 443),
    ServiceRegion = "us-east-1"
});
go
var vpc Vpc


ec2.NewInterfaceVpcEndpoint(this, jsii.String("CrossRegionEndpoint"), &InterfaceVpcEndpointProps{
	Vpc: Vpc,
	Service: ec2.NewInterfaceVpcEndpointService(jsii.String("com.amazonaws.vpce.us-east-1.vpce-svc-123456"), jsii.Number(443)),
	ServiceRegion: jsii.String("us-east-1"),
})

Security groups for interface VPC endpoints ​

By default, interface VPC endpoints create a new security group and all traffic to the endpoint from within the VPC will be automatically allowed.

Use the connections object to allow other traffic to flow to the endpoint:

ts
declare const myEndpoint: ec2.InterfaceVpcEndpoint;

myEndpoint.connections.allowDefaultPortFromAnyIpv4();
python
# my_endpoint: ec2.InterfaceVpcEndpoint


my_endpoint.connections.allow_default_port_from_any_ipv4()
java
InterfaceVpcEndpoint myEndpoint;


myEndpoint.connections.allowDefaultPortFromAnyIpv4();
csharp
InterfaceVpcEndpoint myEndpoint;


myEndpoint.Connections.AllowDefaultPortFromAnyIpv4();
go
var myEndpoint InterfaceVpcEndpoint


myEndpoint.Connections.AllowDefaultPortFromAnyIpv4()

Alternatively, existing security groups can be used by specifying the securityGroups prop.

IPv6 and Dualstack support ​

As IPv4 addresses are running out, many AWS services are adding support for IPv6 or Dualstack (IPv4 and IPv6 support) for their VPC Endpoints.

IPv6 and Dualstack address types can be configured for both interface and gateway endpoints using ipAddressType and dnsRecordIpType:

ts
// Interface endpoint with IPv6
vpc.addInterfaceEndpoint('ExampleEndpoint', {
  service: ec2.InterfaceVpcEndpointAwsService.ECR,
  ipAddressType: ec2.VpcEndpointIpAddressType.IPV6,
  dnsRecordIpType: ec2.VpcEndpointDnsRecordIpType.IPV6,
});

// Gateway endpoint with dualstack
vpc.addGatewayEndpoint('S3DualstackEndpoint', {
  service: ec2.GatewayVpcEndpointAwsService.S3,
  ipAddressType: ec2.VpcEndpointIpAddressType.DUALSTACK,
  dnsRecordIpType: ec2.VpcEndpointDnsRecordIpType.DUALSTACK,
});
python
# Interface endpoint with IPv6
vpc.add_interface_endpoint("ExampleEndpoint",
    service=ec2.InterfaceVpcEndpointAwsService.ECR,
    ip_address_type=ec2.VpcEndpointIpAddressType.IPV6,
    dns_record_ip_type=ec2.VpcEndpointDnsRecordIpType.IPV6
)

# Gateway endpoint with dualstack
vpc.add_gateway_endpoint("S3DualstackEndpoint",
    service=ec2.GatewayVpcEndpointAwsService.S3,
    ip_address_type=ec2.VpcEndpointIpAddressType.DUALSTACK,
    dns_record_ip_type=ec2.VpcEndpointDnsRecordIpType.DUALSTACK
)
java
// Interface endpoint with IPv6
vpc.addInterfaceEndpoint("ExampleEndpoint", InterfaceVpcEndpointOptions.builder()
        .service(InterfaceVpcEndpointAwsService.ECR)
        .ipAddressType(VpcEndpointIpAddressType.IPV6)
        .dnsRecordIpType(VpcEndpointDnsRecordIpType.IPV6)
        .build());

// Gateway endpoint with dualstack
vpc.addGatewayEndpoint("S3DualstackEndpoint", GatewayVpcEndpointOptions.builder()
        .service(GatewayVpcEndpointAwsService.S3)
        .ipAddressType(VpcEndpointIpAddressType.DUALSTACK)
        .dnsRecordIpType(VpcEndpointDnsRecordIpType.DUALSTACK)
        .build());
csharp
// Interface endpoint with IPv6
vpc.AddInterfaceEndpoint("ExampleEndpoint", new InterfaceVpcEndpointOptions {
    Service = InterfaceVpcEndpointAwsService.ECR,
    IpAddressType = VpcEndpointIpAddressType.IPV6,
    DnsRecordIpType = VpcEndpointDnsRecordIpType.IPV6
});

// Gateway endpoint with dualstack
vpc.AddGatewayEndpoint("S3DualstackEndpoint", new GatewayVpcEndpointOptions {
    Service = GatewayVpcEndpointAwsService.S3,
    IpAddressType = VpcEndpointIpAddressType.DUALSTACK,
    DnsRecordIpType = VpcEndpointDnsRecordIpType.DUALSTACK
});
go
// Interface endpoint with IPv6
vpc.addInterfaceEndpoint(jsii.String("ExampleEndpoint"), &InterfaceVpcEndpointOptions{
	Service: ec2.InterfaceVpcEndpointAwsService_ECR(),
	IpAddressType: ec2.VpcEndpointIpAddressType_IPV6,
	DnsRecordIpType: ec2.VpcEndpointDnsRecordIpType_IPV6,
})

// Gateway endpoint with dualstack
vpc.addGatewayEndpoint(jsii.String("S3DualstackEndpoint"), &GatewayVpcEndpointOptions{
	Service: ec2.GatewayVpcEndpointAwsService_S3(),
	IpAddressType: ec2.VpcEndpointIpAddressType_DUALSTACK,
	DnsRecordIpType: ec2.VpcEndpointDnsRecordIpType_DUALSTACK,
})

The possible values for ipAddressType are:

  • IPV4 This option is supported only if all selected subnets have IPv4 address ranges and the endpoint service accepts IPv4 requests.
  • IPV6 This option is supported only if all selected subnets are IPv6 only subnets and the endpoint service accepts IPv6 requests.
  • DUALSTACK Assign both IPv4 and IPv6 addresses to the endpoint network interfaces. This option is supported only if all selected subnets have both IPv4 and IPv6 address ranges and the endpoint service accepts both IPv4 and IPv6 requests. The possible values for dnsRecordIpType are:
  • IPV4 Create A records for the private, Regional, and zonal DNS names. ipAddressType MUST be IPV4 or DUALSTACK
  • IPV6 Create AAAA records for the private, Regional, and zonal DNS names. ipAddressType MUST be IPV6 or DUALSTACK
  • DUALSTACK Create A and AAAA records for the private, Regional, and zonal DNS names. ipAddressType MUST be DUALSTACK
  • SERVICE_DEFINED Create A records for the private, Regional, and zonal DNS names and AAAA records for the Regional and zonal DNS names. ipAddressType MUST be DUALSTACK We can only configure dnsRecordIpType when ipAddressType is specified and private DNS must be enabled to use any DNS related features. To avoid complications, it is recommended to always set privateDnsEnabled to true (defaults to true) and set the ipAddressType and dnsRecordIpType explicitly when needing specific IP type behavior. Furthermore, check that the VPC being used supports the IP address type that is being configued. More documentation on compatibility and specifications can be found here

VPC endpoint services ​

A VPC endpoint service enables you to expose a Network Load Balancer(s) as a provider service to consumers, who connect to your service over a VPC endpoint. You can restrict access to your service via allowed principals (anything that extends ArnPrincipal), and require that new connections be manually accepted. You can also enable Contributor Insight rules.

ts
declare const networkLoadBalancer1: elbv2.NetworkLoadBalancer;
declare const networkLoadBalancer2: elbv2.NetworkLoadBalancer;

new ec2.VpcEndpointService(this, 'EndpointService', {
  vpcEndpointServiceLoadBalancers: [networkLoadBalancer1, networkLoadBalancer2],
  acceptanceRequired: true,
  allowedPrincipals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:root')],
  contributorInsights: true
});
python
# network_load_balancer1: elbv2.NetworkLoadBalancer
# network_load_balancer2: elbv2.NetworkLoadBalancer


ec2.VpcEndpointService(self, "EndpointService",
    vpc_endpoint_service_load_balancers=[network_load_balancer1, network_load_balancer2],
    acceptance_required=True,
    allowed_principals=[iam.ArnPrincipal("arn:aws:iam::123456789012:root")],
    contributor_insights=True
)
java
NetworkLoadBalancer networkLoadBalancer1;
NetworkLoadBalancer networkLoadBalancer2;


VpcEndpointService.Builder.create(this, "EndpointService")
        .vpcEndpointServiceLoadBalancers(List.of(networkLoadBalancer1, networkLoadBalancer2))
        .acceptanceRequired(true)
        .allowedPrincipals(List.of(new ArnPrincipal("arn:aws:iam::123456789012:root")))
        .contributorInsights(true)
        .build();
csharp
NetworkLoadBalancer networkLoadBalancer1;
NetworkLoadBalancer networkLoadBalancer2;


new VpcEndpointService(this, "EndpointService", new VpcEndpointServiceProps {
    VpcEndpointServiceLoadBalancers = new [] { networkLoadBalancer1, networkLoadBalancer2 },
    AcceptanceRequired = true,
    AllowedPrincipals = new [] { new ArnPrincipal("arn:aws:iam::123456789012:root") },
    ContributorInsights = true
});
go
var networkLoadBalancer1 NetworkLoadBalancer
var networkLoadBalancer2 NetworkLoadBalancer


ec2.NewVpcEndpointService(this, jsii.String("EndpointService"), &VpcEndpointServiceProps{
	VpcEndpointServiceLoadBalancers: []IVpcEndpointServiceLoadBalancer{
		networkLoadBalancer1,
		networkLoadBalancer2,
	},
	AcceptanceRequired: jsii.Boolean(true),
	AllowedPrincipals: []ArnPrincipal{
		iam.NewArnPrincipal(jsii.String("arn:aws:iam::123456789012:root")),
	},
	ContributorInsights: jsii.Boolean(true),
})

You can also include a service principal in the allowedPrincipals property by specifying it as a parameter to the ArnPrincipal constructor. The resulting VPC endpoint will have an allowlisted principal of type Service, instead of Arn for that item in the list.

ts
declare const networkLoadBalancer: elbv2.NetworkLoadBalancer;

new ec2.VpcEndpointService(this, 'EndpointService', {
  vpcEndpointServiceLoadBalancers: [networkLoadBalancer],
  allowedPrincipals: [new iam.ArnPrincipal('ec2.amazonaws.com')],
});
python
# network_load_balancer: elbv2.NetworkLoadBalancer


ec2.VpcEndpointService(self, "EndpointService",
    vpc_endpoint_service_load_balancers=[network_load_balancer],
    allowed_principals=[iam.ArnPrincipal("ec2.amazonaws.com")]
)
java
NetworkLoadBalancer networkLoadBalancer;


VpcEndpointService.Builder.create(this, "EndpointService")
        .vpcEndpointServiceLoadBalancers(List.of(networkLoadBalancer))
        .allowedPrincipals(List.of(new ArnPrincipal("ec2.amazonaws.com")))
        .build();
csharp
NetworkLoadBalancer networkLoadBalancer;


new VpcEndpointService(this, "EndpointService", new VpcEndpointServiceProps {
    VpcEndpointServiceLoadBalancers = new [] { networkLoadBalancer },
    AllowedPrincipals = new [] { new ArnPrincipal("ec2.amazonaws.com") }
});
go
var networkLoadBalancer NetworkLoadBalancer


ec2.NewVpcEndpointService(this, jsii.String("EndpointService"), &VpcEndpointServiceProps{
	VpcEndpointServiceLoadBalancers: []IVpcEndpointServiceLoadBalancer{
		networkLoadBalancer,
	},
	AllowedPrincipals: []ArnPrincipal{
		iam.NewArnPrincipal(jsii.String("ec2.amazonaws.com")),
	},
})

You can specify which IP address types (IPv4, IPv6, or both) are supported for your VPC endpoint service:

ts
declare const networkLoadBalancer: elbv2.NetworkLoadBalancer;

new ec2.VpcEndpointService(this, 'EndpointService', {
  vpcEndpointServiceLoadBalancers: [networkLoadBalancer],
  // Support both IPv4 and IPv6 connections to the endpoint service
  supportedIpAddressTypes: [
    ec2.IpAddressType.IPV4,
    ec2.IpAddressType.IPV6,
  ],
});
python
# network_load_balancer: elbv2.NetworkLoadBalancer


ec2.VpcEndpointService(self, "EndpointService",
    vpc_endpoint_service_load_balancers=[network_load_balancer],
    # Support both IPv4 and IPv6 connections to the endpoint service
    supported_ip_address_types=[ec2.IpAddressType.IPV4, ec2.IpAddressType.IPV6
    ]
)
java
NetworkLoadBalancer networkLoadBalancer;


VpcEndpointService.Builder.create(this, "EndpointService")
        .vpcEndpointServiceLoadBalancers(List.of(networkLoadBalancer))
        // Support both IPv4 and IPv6 connections to the endpoint service
        .supportedIpAddressTypes(List.of(IpAddressType.IPV4, IpAddressType.IPV6))
        .build();
csharp
NetworkLoadBalancer networkLoadBalancer;


new VpcEndpointService(this, "EndpointService", new VpcEndpointServiceProps {
    VpcEndpointServiceLoadBalancers = new [] { networkLoadBalancer },
    // Support both IPv4 and IPv6 connections to the endpoint service
    SupportedIpAddressTypes = new [] { IpAddressType.IPV4, IpAddressType.IPV6 }
});
go
var networkLoadBalancer NetworkLoadBalancer


ec2.NewVpcEndpointService(this, jsii.String("EndpointService"), &VpcEndpointServiceProps{
	VpcEndpointServiceLoadBalancers: []IVpcEndpointServiceLoadBalancer{
		networkLoadBalancer,
	},
	// Support both IPv4 and IPv6 connections to the endpoint service
	SupportedIpAddressTypes: []IpAddressType{
		ec2.IpAddressType_IPV4,
		ec2.IpAddressType_IPV6,
	},
})

You can restrict access to your endpoint service to specific AWS regions:

ts
declare const networkLoadBalancer: elbv2.NetworkLoadBalancer;

new ec2.VpcEndpointService(this, 'EndpointService', {
  vpcEndpointServiceLoadBalancers: [networkLoadBalancer],
  // Allow service consumers from these regions only
  allowedRegions: ['us-east-1', 'eu-west-1'],
});
python
# network_load_balancer: elbv2.NetworkLoadBalancer


ec2.VpcEndpointService(self, "EndpointService",
    vpc_endpoint_service_load_balancers=[network_load_balancer],
    # Allow service consumers from these regions only
    allowed_regions=["us-east-1", "eu-west-1"]
)
java
NetworkLoadBalancer networkLoadBalancer;


VpcEndpointService.Builder.create(this, "EndpointService")
        .vpcEndpointServiceLoadBalancers(List.of(networkLoadBalancer))
        // Allow service consumers from these regions only
        .allowedRegions(List.of("us-east-1", "eu-west-1"))
        .build();
csharp
NetworkLoadBalancer networkLoadBalancer;


new VpcEndpointService(this, "EndpointService", new VpcEndpointServiceProps {
    VpcEndpointServiceLoadBalancers = new [] { networkLoadBalancer },
    // Allow service consumers from these regions only
    AllowedRegions = new [] { "us-east-1", "eu-west-1" }
});
go
var networkLoadBalancer NetworkLoadBalancer


ec2.NewVpcEndpointService(this, jsii.String("EndpointService"), &VpcEndpointServiceProps{
	VpcEndpointServiceLoadBalancers: []IVpcEndpointServiceLoadBalancer{
		networkLoadBalancer,
	},
	// Allow service consumers from these regions only
	AllowedRegions: []*string{
		jsii.String("us-east-1"),
		jsii.String("eu-west-1"),
	},
})

Endpoint services support private DNS, which makes it easier for clients to connect to your service by automatically setting up DNS in their VPC. You can enable private DNS on an endpoint service like so:

ts
import { PublicHostedZone, VpcEndpointServiceDomainName } from 'aws-cdk-lib/aws-route53';
declare const zone: PublicHostedZone;
declare const vpces: ec2.VpcEndpointService;

new VpcEndpointServiceDomainName(this, 'EndpointDomain', {
  endpointService: vpces,
  domainName: 'my-stuff.aws-cdk.dev',
  publicHostedZone: zone,
});
python
from aws_cdk.aws_route53 import PublicHostedZone, VpcEndpointServiceDomainName
# zone: PublicHostedZone
# vpces: ec2.VpcEndpointService


VpcEndpointServiceDomainName(self, "EndpointDomain",
    endpoint_service=vpces,
    domain_name="my-stuff.aws-cdk.dev",
    public_hosted_zone=zone
)
java
import software.amazon.awscdk.services.route53.PublicHostedZone;
import software.amazon.awscdk.services.route53.VpcEndpointServiceDomainName;
PublicHostedZone zone;
VpcEndpointService vpces;


VpcEndpointServiceDomainName.Builder.create(this, "EndpointDomain")
        .endpointService(vpces)
        .domainName("my-stuff.aws-cdk.dev")
        .publicHostedZone(zone)
        .build();
csharp
using Amazon.CDK.AWS.Route53;
PublicHostedZone zone;
VpcEndpointService vpces;


new VpcEndpointServiceDomainName(this, "EndpointDomain", new VpcEndpointServiceDomainNameProps {
    EndpointService = vpces,
    DomainName = "my-stuff.aws-cdk.dev",
    PublicHostedZone = zone
});
go
import "github.com/aws/aws-cdk-go/awscdk"
var zone PublicHostedZone
var vpces VpcEndpointService


awscdk.NewVpcEndpointServiceDomainName(this, jsii.String("EndpointDomain"), &VpcEndpointServiceDomainNameProps{
	EndpointService: vpces,
	DomainName: jsii.String("my-stuff.aws-cdk.dev"),
	PublicHostedZone: zone,
})

Note: The domain name must be owned (registered through Route53) by the account the endpoint service is in, or delegated to the account. The VpcEndpointServiceDomainName will handle the AWS side of domain verification, the process for which can be found here

Client VPN endpoint ​

AWS Client VPN is a managed client-based VPN service that enables you to securely access your AWS resources and resources in your on-premises network. With Client VPN, you can access your resources from any location using an OpenVPN-based VPN client.

Use the addClientVpnEndpoint() method to add a client VPN endpoint to a VPC:

ts
vpc.addClientVpnEndpoint('Endpoint', {
  cidr: '10.100.0.0/16',
  serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
  // Mutual authentication
  clientCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id',
  // User-based authentication
  userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
});
python
vpc.add_client_vpn_endpoint("Endpoint",
    cidr="10.100.0.0/16",
    server_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    # Mutual authentication
    client_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    # User-based authentication
    user_based_authentication=ec2.ClientVpnUserBasedAuthentication.federated(saml_provider)
)
java
vpc.addClientVpnEndpoint("Endpoint", ClientVpnEndpointOptions.builder()
        .cidr("10.100.0.0/16")
        .serverCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id")
        // Mutual authentication
        .clientCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id")
        // User-based authentication
        .userBasedAuthentication(ClientVpnUserBasedAuthentication.federated(samlProvider))
        .build());
csharp
vpc.AddClientVpnEndpoint("Endpoint", new ClientVpnEndpointOptions {
    Cidr = "10.100.0.0/16",
    ServerCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    // Mutual authentication
    ClientCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    // User-based authentication
    UserBasedAuthentication = ClientVpnUserBasedAuthentication.Federated(samlProvider)
});
go
vpc.addClientVpnEndpoint(jsii.String("Endpoint"), &ClientVpnEndpointOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	ServerCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id"),
	// Mutual authentication
	ClientCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id"),
	// User-based authentication
	UserBasedAuthentication: ec2.ClientVpnUserBasedAuthentication_Federated(samlProvider),
})

The endpoint must use at least one authentication method:

  • Mutual authentication with a client certificate
  • User-based authentication (directory or federated)

If user-based authentication is used, the self-service portal URL is made available via a CloudFormation output.

By default, a new security group is created, and logging is enabled. Moreover, a rule to authorize all users to the VPC CIDR is created.

To customize authorization rules, set the authorizeAllUsersToVpcCidr prop to false and use addAuthorizationRule():

ts
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
  cidr: '10.100.0.0/16',
  serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
  userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
  authorizeAllUsersToVpcCidr: false,
});

endpoint.addAuthorizationRule('Rule', {
  cidr: '10.0.10.0/32',
  groupId: 'group-id',
});
python
endpoint = vpc.add_client_vpn_endpoint("Endpoint",
    cidr="10.100.0.0/16",
    server_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    user_based_authentication=ec2.ClientVpnUserBasedAuthentication.federated(saml_provider),
    authorize_all_users_to_vpc_cidr=False
)

endpoint.add_authorization_rule("Rule",
    cidr="10.0.10.0/32",
    group_id="group-id"
)
java
ClientVpnEndpoint endpoint = vpc.addClientVpnEndpoint("Endpoint", ClientVpnEndpointOptions.builder()
        .cidr("10.100.0.0/16")
        .serverCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id")
        .userBasedAuthentication(ClientVpnUserBasedAuthentication.federated(samlProvider))
        .authorizeAllUsersToVpcCidr(false)
        .build());

endpoint.addAuthorizationRule("Rule", ClientVpnAuthorizationRuleOptions.builder()
        .cidr("10.0.10.0/32")
        .groupId("group-id")
        .build());
csharp
var endpoint = vpc.AddClientVpnEndpoint("Endpoint", new ClientVpnEndpointOptions {
    Cidr = "10.100.0.0/16",
    ServerCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    UserBasedAuthentication = ClientVpnUserBasedAuthentication.Federated(samlProvider),
    AuthorizeAllUsersToVpcCidr = false
});

endpoint.AddAuthorizationRule("Rule", new ClientVpnAuthorizationRuleOptions {
    Cidr = "10.0.10.0/32",
    GroupId = "group-id"
});
go
endpoint := vpc.addClientVpnEndpoint(jsii.String("Endpoint"), &ClientVpnEndpointOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	ServerCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id"),
	UserBasedAuthentication: ec2.ClientVpnUserBasedAuthentication_Federated(samlProvider),
	AuthorizeAllUsersToVpcCidr: jsii.Boolean(false),
})

endpoint.AddAuthorizationRule(jsii.String("Rule"), &ClientVpnAuthorizationRuleOptions{
	Cidr: jsii.String("10.0.10.0/32"),
	GroupId: jsii.String("group-id"),
})

Use addRoute() to configure network routes:

ts
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
  cidr: '10.100.0.0/16',
  serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
  userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
});

// Client-to-client access
endpoint.addRoute('Route', {
  cidr: '10.100.0.0/16',
  target: ec2.ClientVpnRouteTarget.local(),
});
python
endpoint = vpc.add_client_vpn_endpoint("Endpoint",
    cidr="10.100.0.0/16",
    server_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    user_based_authentication=ec2.ClientVpnUserBasedAuthentication.federated(saml_provider)
)

# Client-to-client access
endpoint.add_route("Route",
    cidr="10.100.0.0/16",
    target=ec2.ClientVpnRouteTarget.local()
)
java
ClientVpnEndpoint endpoint = vpc.addClientVpnEndpoint("Endpoint", ClientVpnEndpointOptions.builder()
        .cidr("10.100.0.0/16")
        .serverCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id")
        .userBasedAuthentication(ClientVpnUserBasedAuthentication.federated(samlProvider))
        .build());

// Client-to-client access
endpoint.addRoute("Route", ClientVpnRouteOptions.builder()
        .cidr("10.100.0.0/16")
        .target(ClientVpnRouteTarget.local())
        .build());
csharp
var endpoint = vpc.AddClientVpnEndpoint("Endpoint", new ClientVpnEndpointOptions {
    Cidr = "10.100.0.0/16",
    ServerCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    UserBasedAuthentication = ClientVpnUserBasedAuthentication.Federated(samlProvider)
});

// Client-to-client access
endpoint.AddRoute("Route", new ClientVpnRouteOptions {
    Cidr = "10.100.0.0/16",
    Target = ClientVpnRouteTarget.Local()
});
go
endpoint := vpc.addClientVpnEndpoint(jsii.String("Endpoint"), &ClientVpnEndpointOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	ServerCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id"),
	UserBasedAuthentication: ec2.ClientVpnUserBasedAuthentication_Federated(samlProvider),
})

// Client-to-client access
endpoint.AddRoute(jsii.String("Route"), &ClientVpnRouteOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	Target: ec2.ClientVpnRouteTarget_Local(),
})

Use the connections object of the endpoint to allow traffic to other security groups.

To enable client route enforcement, configure the clientRouteEnforcementOptions.enforced prop to true:

ts
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
  cidr: '10.100.0.0/16',
  serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
  clientCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id',
  clientRouteEnforcementOptions: {
    enforced: true,
  },
});
python
endpoint = vpc.add_client_vpn_endpoint("Endpoint",
    cidr="10.100.0.0/16",
    server_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    client_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    client_route_enforcement_options=ec2.ClientRouteEnforcementOptions(
        enforced=True
    )
)
java
ClientVpnEndpoint endpoint = vpc.addClientVpnEndpoint("Endpoint", ClientVpnEndpointOptions.builder()
        .cidr("10.100.0.0/16")
        .serverCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id")
        .clientCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id")
        .clientRouteEnforcementOptions(ClientRouteEnforcementOptions.builder()
                .enforced(true)
                .build())
        .build());
csharp
var endpoint = vpc.AddClientVpnEndpoint("Endpoint", new ClientVpnEndpointOptions {
    Cidr = "10.100.0.0/16",
    ServerCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    ClientCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    ClientRouteEnforcementOptions = new ClientRouteEnforcementOptions {
        Enforced = true
    }
});
go
endpoint := vpc.addClientVpnEndpoint(jsii.String("Endpoint"), &ClientVpnEndpointOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	ServerCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id"),
	ClientCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id"),
	ClientRouteEnforcementOptions: &ClientRouteEnforcementOptions{
		Enforced: jsii.Boolean(true),
	},
})

To control whether clients are automatically disconnected when the maximum session duration is reached, use the disconnectOnSessionTimeout prop. By default (true), clients are disconnected and must manually reconnect. Set to false to allow automatic reconnection attempts:

ts
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
  cidr: '10.100.0.0/16',
  serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
  clientCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id',
  disconnectOnSessionTimeout: false, // Allow automatic reconnection attempts
});
python
endpoint = vpc.add_client_vpn_endpoint("Endpoint",
    cidr="10.100.0.0/16",
    server_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    client_certificate_arn="arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    disconnect_on_session_timeout=False
)
java
ClientVpnEndpoint endpoint = vpc.addClientVpnEndpoint("Endpoint", ClientVpnEndpointOptions.builder()
        .cidr("10.100.0.0/16")
        .serverCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id")
        .clientCertificateArn("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id")
        .disconnectOnSessionTimeout(false)
        .build());
csharp
var endpoint = vpc.AddClientVpnEndpoint("Endpoint", new ClientVpnEndpointOptions {
    Cidr = "10.100.0.0/16",
    ServerCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id",
    ClientCertificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id",
    DisconnectOnSessionTimeout = false
});
go
endpoint := vpc.addClientVpnEndpoint(jsii.String("Endpoint"), &ClientVpnEndpointOptions{
	Cidr: jsii.String("10.100.0.0/16"),
	ServerCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id"),
	ClientCertificateArn: jsii.String("arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id"),
	DisconnectOnSessionTimeout: jsii.Boolean(false),
})

Detail information about maximum VPN session duration timeout can be found in the AWS documentation.

Instances ​

You can use the Instance class to start up a single EC2 instance. For production setups, we recommend you use an AutoScalingGroup from the aws-autoscaling module instead, as AutoScalingGroups will take care of restarting your instance if it ever fails.

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;

// Amazon Linux 2
new ec2.Instance(this, 'Instance2', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2(),
});

// Amazon Linux 2 with kernel 5.x
new ec2.Instance(this, 'Instance3', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2({
    kernel: ec2.AmazonLinux2Kernel.KERNEL_5_10,
  }),
});

// Amazon Linux 2023
new ec2.Instance(this, 'Instance4', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
});

// Graviton 3 Processor
new ec2.Instance(this, 'Instance5', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2023({
    cpuType: ec2.AmazonLinuxCpuType.ARM_64,
  }),
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType


# Amazon Linux 2
ec2.Instance(self, "Instance2",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2()
)

# Amazon Linux 2 with kernel 5.x
ec2.Instance(self, "Instance3",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2(
        kernel=ec2.AmazonLinux2Kernel.KERNEL_5_10
    )
)

# Amazon Linux 2023
ec2.Instance(self, "Instance4",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023()
)

# Graviton 3 Processor
ec2.Instance(self, "Instance5",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2023(
        cpu_type=ec2.AmazonLinuxCpuType.ARM_64
    )
)
java
Vpc vpc;
InstanceType instanceType;


// Amazon Linux 2
// Amazon Linux 2
Instance.Builder.create(this, "Instance2")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2())
        .build();

// Amazon Linux 2 with kernel 5.x
// Amazon Linux 2 with kernel 5.x
Instance.Builder.create(this, "Instance3")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2(AmazonLinux2ImageSsmParameterProps.builder()
                .kernel(AmazonLinux2Kernel.KERNEL_5_10)
                .build()))
        .build();

// Amazon Linux 2023
// Amazon Linux 2023
Instance.Builder.create(this, "Instance4")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        .build();

// Graviton 3 Processor
// Graviton 3 Processor
Instance.Builder.create(this, "Instance5")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2023(AmazonLinux2023ImageSsmParameterProps.builder()
                .cpuType(AmazonLinuxCpuType.ARM_64)
                .build()))
        .build();
csharp
Vpc vpc;
InstanceType instanceType;


// Amazon Linux 2
// Amazon Linux 2
new Instance(this, "Instance2", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2()
});

// Amazon Linux 2 with kernel 5.x
// Amazon Linux 2 with kernel 5.x
new Instance(this, "Instance3", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2(new AmazonLinux2ImageSsmParameterProps {
        Kernel = AmazonLinux2Kernel.KERNEL_5_10
    })
});

// Amazon Linux 2023
// Amazon Linux 2023
new Instance(this, "Instance4", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023()
});

// Graviton 3 Processor
// Graviton 3 Processor
new Instance(this, "Instance5", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2023(new AmazonLinux2023ImageSsmParameterProps {
        CpuType = AmazonLinuxCpuType.ARM_64
    })
});
go
var vpc Vpc
var instanceType InstanceType


// Amazon Linux 2
// Amazon Linux 2
ec2.NewInstance(this, jsii.String("Instance2"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2(),
})

// Amazon Linux 2 with kernel 5.x
// Amazon Linux 2 with kernel 5.x
ec2.NewInstance(this, jsii.String("Instance3"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_*LatestAmazonLinux2(&AmazonLinux2ImageSsmParameterProps{
		Kernel: ec2.AmazonLinux2Kernel_KERNEL_5_10(),
	}),
})

// Amazon Linux 2023
// Amazon Linux 2023
ec2.NewInstance(this, jsii.String("Instance4"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
})

// Graviton 3 Processor
// Graviton 3 Processor
ec2.NewInstance(this, jsii.String("Instance5"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_*LatestAmazonLinux2023(&AmazonLinux2023ImageSsmParameterProps{
		CpuType: ec2.AmazonLinuxCpuType_ARM_64,
	}),
})

Latest Amazon Linux Images ​

Rather than specifying a specific AMI ID to use, it is possible to specify a SSM Parameter that contains the AMI ID. AWS publishes a set of public parameters that contain the latest Amazon Linux AMIs. To make it easier to query a particular image parameter, the CDK provides a couple of constructs AmazonLinux2ImageSsmParameter, AmazonLinux2022ImageSsmParameter, & AmazonLinux2023SsmParameter. For example to use the latest al2023 image:

ts
declare const vpc: ec2.Vpc;

new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
});
python
# vpc: ec2.Vpc


ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2023()
)
java
Vpc vpc;


Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2023())
        .build();
csharp
Vpc vpc;


new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2023()
});
go
var vpc Vpc


ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
})

Warning Since this retrieves the value from an SSM parameter at deployment time, the value will be resolved each time the stack is deployed. This means that if the parameter contains a different value on your next deployment, the instance will be replaced.

It is also possible to perform the lookup once at synthesis time and then cache the value in CDK context. This way the value will not change on future deployments unless you manually refresh the context.

ts
declare const vpc: ec2.Vpc;

new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2023({
    cachedInContext: true, // default is false
  }),
});

// or
new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  // context cache is turned on by default
  machineImage: new ec2.AmazonLinux2023ImageSsmParameter(),
});

// or
new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2023({
    cachedInContext: true,
    // creates a distinct context variable for this image, instead of resolving to the same
    // value anywhere this lookup is done in your app
    additionalCacheKey: this.node.path,
  }),
});

// or
new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  // context cache is turned on by default
  machineImage: new ec2.AmazonLinux2023ImageSsmParameter({
    // creates a distinct context variable for this image, instead of resolving to the same
    // value anywhere this lookup is done in your app
    additionalCacheKey: this.node.path,
  }),
});
python
# vpc: ec2.Vpc


ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2023(
        cached_in_context=True
    )
)

# or
ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    # context cache is turned on by default
    machine_image=ec2.AmazonLinux2023ImageSsmParameter()
)

# or
ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2023(
        cached_in_context=True,
        # creates a distinct context variable for this image, instead of resolving to the same
        # value anywhere this lookup is done in your app
        additional_cache_key=self.node.path
    )
)

# or
ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    # context cache is turned on by default
    machine_image=ec2.AmazonLinux2023ImageSsmParameter(
        # creates a distinct context variable for this image, instead of resolving to the same
        # value anywhere this lookup is done in your app
        additional_cache_key=self.node.path
    )
)
java
Vpc vpc;


Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2023(AmazonLinux2023ImageSsmParameterProps.builder()
                .cachedInContext(true)
                .build()))
        .build();

// or
// or
Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        // context cache is turned on by default
        .machineImage(new AmazonLinux2023ImageSsmParameter())
        .build();

// or
// or
Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2023(AmazonLinux2023ImageSsmParameterProps.builder()
                .cachedInContext(true)
                // creates a distinct context variable for this image, instead of resolving to the same
                // value anywhere this lookup is done in your app
                .additionalCacheKey(this.node.getPath())
                .build()))
        .build();

// or
// or
Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        // context cache is turned on by default
        .machineImage(AmazonLinux2023ImageSsmParameter.Builder.create()
                // creates a distinct context variable for this image, instead of resolving to the same
                // value anywhere this lookup is done in your app
                .additionalCacheKey(this.node.getPath())
                .build())
        .build();
csharp
Vpc vpc;


new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2023(new AmazonLinux2023ImageSsmParameterProps {
        CachedInContext = true
    })
});

// or
// or
new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    // context cache is turned on by default
    MachineImage = new AmazonLinux2023ImageSsmParameter()
});

// or
// or
new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2023(new AmazonLinux2023ImageSsmParameterProps {
        CachedInContext = true,
        // creates a distinct context variable for this image, instead of resolving to the same
        // value anywhere this lookup is done in your app
        AdditionalCacheKey = Node.Path
    })
});

// or
// or
new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    // context cache is turned on by default
    MachineImage = new AmazonLinux2023ImageSsmParameter(new AmazonLinux2023ImageSsmParameterProps {
        // creates a distinct context variable for this image, instead of resolving to the same
        // value anywhere this lookup is done in your app
        AdditionalCacheKey = Node.Path
    })
});
go
var vpc Vpc


ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(&AmazonLinux2023ImageSsmParameterProps{
		CachedInContext: jsii.Boolean(true),
	}),
})

// or
// or
ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_*Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	// context cache is turned on by default
	MachineImage: ec2.NewAmazonLinux2023ImageSsmParameter(),
})

// or
// or
ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_*Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_*LatestAmazonLinux2023(&AmazonLinux2023ImageSsmParameterProps{
		CachedInContext: jsii.Boolean(true),
		// creates a distinct context variable for this image, instead of resolving to the same
		// value anywhere this lookup is done in your app
		AdditionalCacheKey: this.Node.path,
	}),
})

// or
// or
ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_*Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	// context cache is turned on by default
	MachineImage: ec2.NewAmazonLinux2023ImageSsmParameter(&AmazonLinux2023ImageSsmParameterProps{
		// creates a distinct context variable for this image, instead of resolving to the same
		// value anywhere this lookup is done in your app
		AdditionalCacheKey: this.*Node.path,
	}),
})

Kernel Versions ​

Each Amazon Linux AMI uses a specific kernel version. Most Amazon Linux generations come with an AMI using the "default" kernel and then 1 or more AMIs using a specific kernel version, which may or may not be different from the default kernel version.

For example, Amazon Linux 2 has two different AMIs available from the SSM parameters.

  • /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
    • This is the "default" kernel which uses kernel-4.14
  • /aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-ebs

If a new Amazon Linux generation AMI is published with a new kernel version, then a new SSM parameter will be created with the new version (e.g. /aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.15-hvm-x86_64-ebs), but the "default" AMI may or may not be updated.

If you would like to make sure you always have the latest kernel version, then either specify the specific latest kernel version or opt-in to using the CDK latest kernel version.

ts
declare const vpc: ec2.Vpc;

new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  // context cache is turned on by default
  machineImage: new ec2.AmazonLinux2023ImageSsmParameter({
    kernel: ec2.AmazonLinux2023Kernel.KERNEL_6_1,
  }),
});
python
# vpc: ec2.Vpc


ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    # context cache is turned on by default
    machine_image=ec2.AmazonLinux2023ImageSsmParameter(
        kernel=ec2.AmazonLinux2023Kernel.KERNEL_6_1
    )
)
java
Vpc vpc;


Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        // context cache is turned on by default
        .machineImage(AmazonLinux2023ImageSsmParameter.Builder.create()
                .kernel(AmazonLinux2023Kernel.KERNEL_6_1)
                .build())
        .build();
csharp
Vpc vpc;


new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    // context cache is turned on by default
    MachineImage = new AmazonLinux2023ImageSsmParameter(new AmazonLinux2023ImageSsmParameterProps {
        Kernel = AmazonLinux2023Kernel.KERNEL_6_1
    })
});
go
var vpc Vpc


ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	// context cache is turned on by default
	MachineImage: ec2.NewAmazonLinux2023ImageSsmParameter(&AmazonLinux2023ImageSsmParameterProps{
		Kernel: ec2.AmazonLinux2023Kernel_KERNEL_6_1(),
	}),
})

CDK managed latest

ts
declare const vpc: ec2.Vpc;

new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  // context cache is turned on by default
  machineImage: new ec2.AmazonLinux2023ImageSsmParameter({
    kernel: ec2.AmazonLinux2023Kernel.CDK_LATEST,
  }),
});

// or

new ec2.Instance(this, 'LatestAl2023', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2023(), // always uses latest kernel version
});
python
# vpc: ec2.Vpc


ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    # context cache is turned on by default
    machine_image=ec2.AmazonLinux2023ImageSsmParameter(
        kernel=ec2.AmazonLinux2023Kernel.CDK_LATEST
    )
)

# or

ec2.Instance(self, "LatestAl2023",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.C7G, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2023()
)
java
Vpc vpc;


Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        // context cache is turned on by default
        .machineImage(AmazonLinux2023ImageSsmParameter.Builder.create()
                .kernel(AmazonLinux2023Kernel.CDK_LATEST)
                .build())
        .build();

// or

// or
Instance.Builder.create(this, "LatestAl2023")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.C7G, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2023())
        .build();
csharp
Vpc vpc;


new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    // context cache is turned on by default
    MachineImage = new AmazonLinux2023ImageSsmParameter(new AmazonLinux2023ImageSsmParameterProps {
        Kernel = AmazonLinux2023Kernel.CDK_LATEST
    })
});

// or

// or
new Instance(this, "LatestAl2023", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.C7G, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2023()
});
go
var vpc Vpc


ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	// context cache is turned on by default
	MachineImage: ec2.NewAmazonLinux2023ImageSsmParameter(&AmazonLinux2023ImageSsmParameterProps{
		Kernel: ec2.AmazonLinux2023Kernel_CDK_LATEST(),
	}),
})

// or

// or
ec2.NewInstance(this, jsii.String("LatestAl2023"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_*Of(ec2.InstanceClass_C7G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
})

When using the CDK managed latest version, when a new kernel version is made available the LATEST will be updated to point to the new kernel version. You then would be required to update the newest CDK version for it to take effect.

Configuring Instances using CloudFormation Init (cfn-init) ​

CloudFormation Init allows you to configure your instances by writing files to them, installing software packages, starting services and running arbitrary commands. By default, if any of the instance setup commands throw an error; the deployment will fail and roll back to the previously known good state. The following documentation also applies to AutoScalingGroups.

For the full set of capabilities of this system, see the documentation for AWS::CloudFormation::Init. Here is an example of applying some configuration to an instance:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,

  // Showing the most complex setup, if you have simpler requirements
  // you can use `CloudFormationInit.fromElements()`.
  init: ec2.CloudFormationInit.fromConfigSets({
    configSets: {
      // Applies the configs below in this order
      default: ['yumPreinstall', 'config'],
    },
    configs: {
      yumPreinstall: new ec2.InitConfig([
        // Install an Amazon Linux package using yum
        ec2.InitPackage.yum('git'),
      ]),
      config: new ec2.InitConfig([
        // Create a JSON file from tokens (can also create other files)
        ec2.InitFile.fromObject('/etc/stack.json', {
          stackId: Stack.of(this).stackId,
          stackName: Stack.of(this).stackName,
          region: Stack.of(this).region,
        }),

        // Create a group and user
        ec2.InitGroup.fromName('my-group'),
        ec2.InitUser.fromName('my-user'),

        // Install an RPM from the internet
        ec2.InitPackage.rpm('http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm'),
      ]),
    },
  }),
  initOptions: {
    // Optional, which configsets to activate (['default'] by default)
    configSets: ['default'],

    // Optional, how long the installation is expected to take (5 minutes by default)
    timeout: Duration.minutes(30),

    // Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default)
    includeUrl: true,

    // Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default)
    includeRole: true,
  },
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,

    # Showing the most complex setup, if you have simpler requirements
    # you can use `CloudFormationInit.fromElements()`.
    init=ec2.CloudFormationInit.from_config_sets(
        config_sets={
            # Applies the configs below in this order
            "default": ["yumPreinstall", "config"]
        },
        configs={
            "yum_preinstall": ec2.InitConfig([
                # Install an Amazon Linux package using yum
                ec2.InitPackage.yum("git")
            ]),
            "config": ec2.InitConfig([
                # Create a JSON file from tokens (can also create other files)
                ec2.InitFile.from_object("/etc/stack.json", {
                    "stack_id": Stack.of(self).stack_id,
                    "stack_name": Stack.of(self).stack_name,
                    "region": Stack.of(self).region
                }),

                # Create a group and user
                ec2.InitGroup.from_name("my-group"),
                ec2.InitUser.from_name("my-user"),

                # Install an RPM from the internet
                ec2.InitPackage.rpm("http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm")
            ])
        }
    ),
    init_options=ec2.ApplyCloudFormationInitOptions(
        # Optional, which configsets to activate (['default'] by default)
        config_sets=["default"],

        # Optional, how long the installation is expected to take (5 minutes by default)
        timeout=Duration.minutes(30),

        # Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default)
        include_url=True,

        # Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default)
        include_role=True
    )
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)

        // Showing the most complex setup, if you have simpler requirements
        // you can use `CloudFormationInit.fromElements()`.
        .init(CloudFormationInit.fromConfigSets(ConfigSetProps.builder()
                .configSets(Map.of(
                        // Applies the configs below in this order
                        "default", List.of("yumPreinstall", "config")))
                .configs(Map.of(
                        "yumPreinstall", new InitConfig(List.of(InitPackage.yum("git"))),
                        "config", new InitConfig(List.of(InitFile.fromObject("/etc/stack.json", Map.of(
                                "stackId", Stack.of(this).getStackId(),
                                "stackName", Stack.of(this).getStackName(),
                                "region", Stack.of(this).getRegion())), InitGroup.fromName("my-group"), InitUser.fromName("my-user"), InitPackage.rpm("http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm")))))
                .build()))
        .initOptions(ApplyCloudFormationInitOptions.builder()
                // Optional, which configsets to activate (['default'] by default)
                .configSets(List.of("default"))

                // Optional, how long the installation is expected to take (5 minutes by default)
                .timeout(Duration.minutes(30))

                // Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default)
                .includeUrl(true)

                // Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default)
                .includeRole(true)
                .build())
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,

    // Showing the most complex setup, if you have simpler requirements
    // you can use `CloudFormationInit.fromElements()`.
    Init = CloudFormationInit.FromConfigSets(new ConfigSetProps {
        ConfigSets = new Dictionary<string, string[]> {
            // Applies the configs below in this order
            { "default", new [] { "yumPreinstall", "config" } }
        },
        Configs = new Dictionary<string, InitConfig> {
            { "yumPreinstall", new InitConfig(new [] { InitPackage.Yum("git") }) },
            { "config", new InitConfig(new [] { InitFile.FromObject("/etc/stack.json", new Dictionary<string, object> {
                { "stackId", Stack.Of(this).StackId },
                { "stackName", Stack.Of(this).StackName },
                { "region", Stack.Of(this).Region }
            }), InitGroup.FromName("my-group"), InitUser.FromName("my-user"), InitPackage.Rpm("http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm") }) }
        }
    }),
    InitOptions = new ApplyCloudFormationInitOptions {
        // Optional, which configsets to activate (['default'] by default)
        ConfigSets = new [] { "default" },

        // Optional, how long the installation is expected to take (5 minutes by default)
        Timeout = Duration.Minutes(30),

        // Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default)
        IncludeUrl = true,

        // Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default)
        IncludeRole = true
    }
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,

	// Showing the most complex setup, if you have simpler requirements
	// you can use `CloudFormationInit.fromElements()`.
	Init: ec2.CloudFormationInit_FromConfigSets(&ConfigSetProps{
		ConfigSets: map[string][]*string{
			// Applies the configs below in this order
			"default": []*string{
				jsii.String("yumPreinstall"),
				jsii.String("config"),
			},
		},
		Configs: map[string]InitConfig{
			"yumPreinstall": ec2.NewInitConfig([]InitElement{
				ec2.InitPackage_yum(jsii.String("git")),
			}),
			"config": ec2.NewInitConfig([]InitElement{
				ec2.InitFile_fromObject(jsii.String("/etc/stack.json"), map[string]interface{}{
					"stackId": awscdk.*stack_of(this).stackId,
					"stackName": awscdk.*stack_of(this).stackName,
					"region": awscdk.*stack_of(this).region,
				}),
				ec2.InitGroup_fromName(jsii.String("my-group")),
				ec2.InitUser_fromName(jsii.String("my-user")),
				ec2.InitPackage_rpm(jsii.String("http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm")),
			}),
		},
	}),
	InitOptions: &ApplyCloudFormationInitOptions{
		// Optional, which configsets to activate (['default'] by default)
		ConfigSets: []*string{
			jsii.String("default"),
		},

		// Optional, how long the installation is expected to take (5 minutes by default)
		Timeout: awscdk.Duration_Minutes(jsii.Number(30)),

		// Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default)
		IncludeUrl: jsii.Boolean(true),

		// Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default)
		IncludeRole: jsii.Boolean(true),
	},
})

InitCommand can not be used to start long-running processes. At deploy time, cfn-init will always wait for the process to exit before continuing, causing the CloudFormation deployment to fail because the signal hasn't been received within the expected timeout.

Instead, you should install a service configuration file onto your machine InitFile, and then use InitService to start it.

If your Linux OS is using SystemD (like Amazon Linux 2 or higher), the CDK has helpers to create a long-running service using CFN Init. You can create a SystemD-compatible config file using InitService.systemdConfigFile(), and start it immediately. The following examples shows how to start a trivial Python 3 web server:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),

  init: ec2.CloudFormationInit.fromElements(
    // Create a simple config file that runs a Python web server
    ec2.InitService.systemdConfigFile('simpleserver', {
      command: '/usr/bin/python3 -m http.server 8080',
      cwd: '/var/www/html',
    }),
    // Start the server using SystemD
    ec2.InitService.enable('simpleserver', {
      serviceManager: ec2.ServiceManager.SYSTEMD,
    }),
    // Drop an example file to show the web server working
    ec2.InitFile.fromString('/var/www/html/index.html', 'Hello! It\'s working!'),
  ),
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),

    init=ec2.CloudFormationInit.from_elements(
        # Create a simple config file that runs a Python web server
        ec2.InitService.systemd_config_file("simpleserver",
            command="/usr/bin/python3 -m http.server 8080",
            cwd="/var/www/html"
        ),
        # Start the server using SystemD
        ec2.InitService.enable("simpleserver",
            service_manager=ec2.ServiceManager.SYSTEMD
        ),
        # Drop an example file to show the web server working
        ec2.InitFile.from_string("/var/www/html/index.html", "Hello! It's working!"))
)
java
Vpc vpc;
InstanceType instanceType;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())

        .init(CloudFormationInit.fromElements(InitService.systemdConfigFile("simpleserver", SystemdConfigFileOptions.builder()
                .command("/usr/bin/python3 -m http.server 8080")
                .cwd("/var/www/html")
                .build()), InitService.enable("simpleserver", InitServiceOptions.builder()
                .serviceManager(ServiceManager.SYSTEMD)
                .build()), InitFile.fromString("/var/www/html/index.html", "Hello! It's working!")))
        .build();
csharp
Vpc vpc;
InstanceType instanceType;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),

    Init = CloudFormationInit.FromElements(InitService.SystemdConfigFile("simpleserver", new SystemdConfigFileOptions {
        Command = "/usr/bin/python3 -m http.server 8080",
        Cwd = "/var/www/html"
    }), InitService.Enable("simpleserver", new InitServiceOptions {
        ServiceManager = ServiceManager.SYSTEMD
    }), InitFile.FromString("/var/www/html/index.html", "Hello! It's working!"))
});
go
var vpc Vpc
var instanceType InstanceType


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),

	Init: ec2.CloudFormationInit_FromElements(ec2.InitService_SystemdConfigFile(jsii.String("simpleserver"), &SystemdConfigFileOptions{
		Command: jsii.String("/usr/bin/python3 -m http.server 8080"),
		Cwd: jsii.String("/var/www/html"),
	}), ec2.InitService_Enable(jsii.String("simpleserver"), &InitServiceOptions{
		ServiceManager: ec2.ServiceManager_SYSTEMD,
	}), ec2.InitFile_FromString(jsii.String("/var/www/html/index.html"), jsii.String("Hello! It's working!"))),
})

You can have services restarted after the init process has made changes to the system. To do that, instantiate an InitServiceRestartHandle and pass it to the config elements that need to trigger the restart and the service itself. For example, the following config writes a config file for nginx, extracts an archive to the root directory, and then restarts nginx so that it picks up the new config and files:

ts
declare const myBucket: s3.Bucket;

const handle = new ec2.InitServiceRestartHandle();

ec2.CloudFormationInit.fromElements(
  ec2.InitFile.fromString('/etc/nginx/nginx.conf', '...', { serviceRestartHandles: [handle] }),
  ec2.InitSource.fromS3Object('/var/www/html', myBucket, 'html.zip', { serviceRestartHandles: [handle] }),
  ec2.InitService.enable('nginx', {
    serviceRestartHandle: handle,
  })
);
python
# my_bucket: s3.Bucket


handle = ec2.InitServiceRestartHandle()

ec2.CloudFormationInit.from_elements(
    ec2.InitFile.from_string("/etc/nginx/nginx.conf", "...", service_restart_handles=[handle]),
    ec2.InitSource.from_s3_object("/var/www/html", my_bucket, "html.zip", service_restart_handles=[handle]),
    ec2.InitService.enable("nginx",
        service_restart_handle=handle
    ))
java
Bucket myBucket;


InitServiceRestartHandle handle = new InitServiceRestartHandle();

CloudFormationInit.fromElements(InitFile.fromString("/etc/nginx/nginx.conf", "...", InitFileOptions.builder().serviceRestartHandles(List.of(handle)).build()), InitSource.fromS3Object("/var/www/html", myBucket, "html.zip", InitSourceOptions.builder().serviceRestartHandles(List.of(handle)).build()), InitService.enable("nginx", InitServiceOptions.builder()
        .serviceRestartHandle(handle)
        .build()));
csharp
Bucket myBucket;


var handle = new InitServiceRestartHandle();

CloudFormationInit.FromElements(InitFile.FromString("/etc/nginx/nginx.conf", "...", new InitFileOptions { ServiceRestartHandles = new [] { handle } }), InitSource.FromS3Object("/var/www/html", myBucket, "html.zip", new InitSourceOptions { ServiceRestartHandles = new [] { handle } }), InitService.Enable("nginx", new InitServiceOptions {
    ServiceRestartHandle = handle
}));
go
var myBucket Bucket


handle := ec2.NewInitServiceRestartHandle()

ec2.CloudFormationInit_FromElements(ec2.InitFile_FromString(jsii.String("/etc/nginx/nginx.conf"), jsii.String("..."), &InitFileOptions{
	ServiceRestartHandles: []InitServiceRestartHandle{
		handle,
	},
}), ec2.InitSource_FromS3Object(jsii.String("/var/www/html"), myBucket, jsii.String("html.zip"), &InitSourceOptions{
	ServiceRestartHandles: []InitServiceRestartHandle{
		handle,
	},
}), ec2.InitService_Enable(jsii.String("nginx"), &InitServiceOptions{
	ServiceRestartHandle: handle,
}))

You can use the environmentVariables or environmentFiles parameters to specify environment variables for your services:

ts
new ec2.InitConfig([
  ec2.InitFile.fromString('/myvars.env', 'VAR_FROM_FILE="VAR_FROM_FILE"'),
  ec2.InitService.systemdConfigFile('myapp', {
    command: '/usr/bin/python3 -m http.server 8080',
    cwd: '/var/www/html',
    environmentVariables: {
      MY_VAR: 'MY_VAR',
    },
    environmentFiles: ['/myvars.env'],
  }),
])
python
ec2.InitConfig([
    ec2.InitFile.from_string("/myvars.env", "VAR_FROM_FILE=\"VAR_FROM_FILE\""),
    ec2.InitService.systemd_config_file("myapp",
        command="/usr/bin/python3 -m http.server 8080",
        cwd="/var/www/html",
        environment_variables={
            "MY_VAR": "MY_VAR"
        },
        environment_files=["/myvars.env"]
    )
])
java
new InitConfig(List.of(InitFile.fromString("/myvars.env", "VAR_FROM_FILE=\"VAR_FROM_FILE\""), InitService.systemdConfigFile("myapp", SystemdConfigFileOptions.builder()
        .command("/usr/bin/python3 -m http.server 8080")
        .cwd("/var/www/html")
        .environmentVariables(Map.of(
                "MY_VAR", "MY_VAR"))
        .environmentFiles(List.of("/myvars.env"))
        .build())));
csharp
new InitConfig(new [] { InitFile.FromString("/myvars.env", "VAR_FROM_FILE=\"VAR_FROM_FILE\""), InitService.SystemdConfigFile("myapp", new SystemdConfigFileOptions {
    Command = "/usr/bin/python3 -m http.server 8080",
    Cwd = "/var/www/html",
    EnvironmentVariables = new Dictionary<string, string> {
        { "MY_VAR", "MY_VAR" }
    },
    EnvironmentFiles = new [] { "/myvars.env" }
}) });
go
ec2.NewInitConfig([]InitElement{
	ec2.InitFile_FromString(jsii.String("/myvars.env"), jsii.String("VAR_FROM_FILE=\"VAR_FROM_FILE\"")),
	ec2.InitService_SystemdConfigFile(jsii.String("myapp"), &SystemdConfigFileOptions{
		Command: jsii.String("/usr/bin/python3 -m http.server 8080"),
		Cwd: jsii.String("/var/www/html"),
		EnvironmentVariables: map[string]*string{
			"MY_VAR": jsii.String("MY_VAR"),
		},
		EnvironmentFiles: []*string{
			jsii.String("/myvars.env"),
		},
	}),
})

Bastion Hosts ​

A bastion host functions as an instance used to access servers and resources in a VPC without open up the complete VPC on a network level. You can use bastion hosts using a standard SSH connection targeting port 22 on the host. As an alternative, you can connect the SSH connection feature of AWS Systems Manager Session Manager, which does not need an opened security group. (https://aws.amazon.com/about-aws/whats-new/2019/07/session-manager-launches-tunneling-support-for-ssh-and-scp/)

A default bastion host for use via SSM can be configured like:

ts
const host = new ec2.BastionHostLinux(this, 'BastionHost', { vpc });
python
host = ec2.BastionHostLinux(self, "BastionHost", vpc=vpc)
java
BastionHostLinux host = BastionHostLinux.Builder.create(this, "BastionHost").vpc(vpc).build();
csharp
var host = new BastionHostLinux(this, "BastionHost", new BastionHostLinuxProps { Vpc = vpc });
go
host := ec2.NewBastionHostLinux(this, jsii.String("BastionHost"), &BastionHostLinuxProps{
	Vpc: Vpc,
})

If you want to connect from the internet using SSH, you need to place the host into a public subnet. You can then configure allowed source hosts.

ts
const host = new ec2.BastionHostLinux(this, 'BastionHost', {
  vpc,
  subnetSelection: { subnetType: ec2.SubnetType.PUBLIC },
});
host.allowSshAccessFrom(ec2.Peer.ipv4('1.2.3.4/32'));
python
host = ec2.BastionHostLinux(self, "BastionHost",
    vpc=vpc,
    subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC)
)
host.allow_ssh_access_from(ec2.Peer.ipv4("1.2.3.4/32"))
java
BastionHostLinux host = BastionHostLinux.Builder.create(this, "BastionHost")
        .vpc(vpc)
        .subnetSelection(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build())
        .build();
host.allowSshAccessFrom(Peer.ipv4("1.2.3.4/32"));
csharp
var host = new BastionHostLinux(this, "BastionHost", new BastionHostLinuxProps {
    Vpc = vpc,
    SubnetSelection = new SubnetSelection { SubnetType = SubnetType.PUBLIC }
});
host.AllowSshAccessFrom(Peer.Ipv4("1.2.3.4/32"));
go
host := ec2.NewBastionHostLinux(this, jsii.String("BastionHost"), &BastionHostLinuxProps{
	Vpc: Vpc,
	SubnetSelection: &SubnetSelection{
		SubnetType: ec2.SubnetType_PUBLIC,
	},
})
host.AllowSshAccessFrom(ec2.Peer_Ipv4(jsii.String("1.2.3.4/32")))

As there are no SSH public keys deployed on this machine, you need to use EC2 Instance Connect with the command aws ec2-instance-connect send-ssh-public-key to provide your SSH public key.

EBS volume for the bastion host can be encrypted like:

ts
const host = new ec2.BastionHostLinux(this, 'BastionHost', {
  vpc,
  blockDevices: [{
    deviceName: '/dev/sdh',
    volume: ec2.BlockDeviceVolume.ebs(10, {
      encrypted: true,
    }),
  }],
});
python
host = ec2.BastionHostLinux(self, "BastionHost",
    vpc=vpc,
    block_devices=[ec2.BlockDevice(
        device_name="/dev/sdh",
        volume=ec2.BlockDeviceVolume.ebs(10,
            encrypted=True
        )
    )]
)
java
BastionHostLinux host = BastionHostLinux.Builder.create(this, "BastionHost")
        .vpc(vpc)
        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/sdh")
                .volume(BlockDeviceVolume.ebs(10, EbsDeviceOptions.builder()
                        .encrypted(true)
                        .build()))
                .build()))
        .build();
csharp
var host = new BastionHostLinux(this, "BastionHost", new BastionHostLinuxProps {
    Vpc = vpc,
    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/sdh",
        Volume = BlockDeviceVolume.Ebs(10, new EbsDeviceOptions {
            Encrypted = true
        })
    } }
});
go
host := ec2.NewBastionHostLinux(this, jsii.String("BastionHost"), &BastionHostLinuxProps{
	Vpc: Vpc,
	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/sdh"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(10), &EbsDeviceOptions{
				Encrypted: jsii.Boolean(true),
			}),
		},
	},
})

It's recommended to set the @aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefaultfeature flag to true to use Amazon Linux 2023 as the bastion host AMI. Without this flag set, the bastion host will default to Amazon Linux 2, which will be unsupported in June 2025.

json
{
  "context": {
    "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true
  }
}

Placement Group ​

Specify placementGroup to enable the placement group support:

ts
declare const instanceType: ec2.InstanceType;

const pg = new ec2.PlacementGroup(this, 'test-pg', {
  strategy: ec2.PlacementGroupStrategy.SPREAD,
});

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  placementGroup: pg,
});
python
# instance_type: ec2.InstanceType


pg = ec2.PlacementGroup(self, "test-pg",
    strategy=ec2.PlacementGroupStrategy.SPREAD
)

ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    placement_group=pg
)
java
InstanceType instanceType;


PlacementGroup pg = PlacementGroup.Builder.create(this, "test-pg")
        .strategy(PlacementGroupStrategy.SPREAD)
        .build();

Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        .placementGroup(pg)
        .build();
csharp
InstanceType instanceType;


var pg = new PlacementGroup(this, "test-pg", new PlacementGroupProps {
    Strategy = PlacementGroupStrategy.SPREAD
});

new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    PlacementGroup = pg
});
go
var instanceType InstanceType


pg := ec2.NewPlacementGroup(this, jsii.String("test-pg"), &PlacementGroupProps{
	Strategy: ec2.PlacementGroupStrategy_SPREAD,
})

ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	PlacementGroup: pg,
})

Block Devices ​

To add EBS block device mappings, specify the blockDevices property. The following example sets the EBS-backed root device (/dev/sda1) size to 50 GiB, and adds another EBS-backed device mapped to /dev/sdm that is 100 GiB in size:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,

  // ...

  blockDevices: [
    {
      deviceName: '/dev/sda1',
      volume: ec2.BlockDeviceVolume.ebs(50),
    },
    {
      deviceName: '/dev/sdm',
      volume: ec2.BlockDeviceVolume.ebs(100),
    },
  ],
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,

    # ...

    block_devices=[ec2.BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(50)
    ), ec2.BlockDevice(
        device_name="/dev/sdm",
        volume=ec2.BlockDeviceVolume.ebs(100)
    )
    ]
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)

        // ...

        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/sda1")
                .volume(BlockDeviceVolume.ebs(50))
                .build(), BlockDevice.builder()
                .deviceName("/dev/sdm")
                .volume(BlockDeviceVolume.ebs(100))
                .build()))
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,

    // ...

    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/sda1",
        Volume = BlockDeviceVolume.Ebs(50)
    }, new BlockDevice {
        DeviceName = "/dev/sdm",
        Volume = BlockDeviceVolume.Ebs(100)
    } }
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,

	// ...

	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/sda1"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(50)),
		},
		&BlockDevice{
			DeviceName: jsii.String("/dev/sdm"),
			Volume: ec2.BlockDeviceVolume_*Ebs(jsii.Number(100)),
		},
	},
})

It is also possible to encrypt the block devices. In this example we will create an customer managed key encrypted EBS-backed root device:

ts
import { Key } from 'aws-cdk-lib/aws-kms';

declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

const kmsKey = new Key(this, 'KmsKey')

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,

  // ...

  blockDevices: [
    {
      deviceName: '/dev/sda1',
      volume: ec2.BlockDeviceVolume.ebs(50, {
        encrypted: true,
        kmsKey: kmsKey,
      }),
    },
  ],
});
python
from aws_cdk.aws_kms import Key

# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


kms_key = Key(self, "KmsKey")

ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,

    # ...

    block_devices=[ec2.BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(50,
            encrypted=True,
            kms_key=kms_key
        )
    )
    ]
)
java
import software.amazon.awscdk.services.kms.Key;

Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Key kmsKey = new Key(this, "KmsKey");

Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)

        // ...

        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/sda1")
                .volume(BlockDeviceVolume.ebs(50, EbsDeviceOptions.builder()
                        .encrypted(true)
                        .kmsKey(kmsKey)
                        .build()))
                .build()))
        .build();
csharp
using Amazon.CDK.AWS.KMS;

Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


var kmsKey = new Key(this, "KmsKey");

new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,

    // ...

    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/sda1",
        Volume = BlockDeviceVolume.Ebs(50, new EbsDeviceOptions {
            Encrypted = true,
            KmsKey = kmsKey
        })
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"

var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


kmsKey := awscdk.NewKey(this, jsii.String("KmsKey"))

ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,

	// ...

	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/sda1"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(50), &EbsDeviceOptions{
				Encrypted: jsii.Boolean(true),
				KmsKey: kmsKey,
			}),
		},
	},
})

To specify the throughput value for gp3 volumes, use the throughput property:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,

  // ...

  blockDevices: [
    {
      deviceName: '/dev/sda1',
      volume: ec2.BlockDeviceVolume.ebs(100, {
        volumeType: ec2.EbsDeviceVolumeType.GP3,
        throughput: 250,
      }),
    },
  ],
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,

    # ...

    block_devices=[ec2.BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(100,
            volume_type=ec2.EbsDeviceVolumeType.GP3,
            throughput=250
        )
    )
    ]
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)

        // ...

        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/sda1")
                .volume(BlockDeviceVolume.ebs(100, EbsDeviceOptions.builder()
                        .volumeType(EbsDeviceVolumeType.GP3)
                        .throughput(250)
                        .build()))
                .build()))
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,

    // ...

    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/sda1",
        Volume = BlockDeviceVolume.Ebs(100, new EbsDeviceOptions {
            VolumeType = EbsDeviceVolumeType.GP3,
            Throughput = 250
        })
    } }
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,

	// ...

	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/sda1"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(100), &EbsDeviceOptions{
				VolumeType: ec2.EbsDeviceVolumeType_GP3,
				Throughput: jsii.Number(250),
			}),
		},
	},
})

EBS Optimized Instances ​

An Amazon EBS–optimized instance uses an optimized configuration stack and provides additional, dedicated capacity for Amazon EBS I/O. This optimization provides the best performance for your EBS volumes by minimizing contention between Amazon EBS I/O and other traffic from your instance.

Depending on the instance type, this features is enabled by default while others require explicit activation. Please refer to the documentation for details.

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,
  ebsOptimized: true,
  blockDevices: [{
    deviceName: '/dev/xvda',
    volume: ec2.BlockDeviceVolume.ebs(8),
  }],
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,
    ebs_optimized=True,
    block_devices=[ec2.BlockDevice(
        device_name="/dev/xvda",
        volume=ec2.BlockDeviceVolume.ebs(8)
    )]
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)
        .ebsOptimized(true)
        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/xvda")
                .volume(BlockDeviceVolume.ebs(8))
                .build()))
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,
    EbsOptimized = true,
    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/xvda",
        Volume = BlockDeviceVolume.Ebs(8)
    } }
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,
	EbsOptimized: jsii.Boolean(true),
	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/xvda"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(8)),
		},
	},
})

Volumes ​

Whereas a BlockDeviceVolume is an EBS volume that is created and destroyed as part of the creation and destruction of a specific instance. A Volume is for when you want an EBS volume separate from any particular instance. A Volume is an EBS block device that can be attached to, or detached from, any instance at any time. Some types of Volumes can also be attached to multiple instances at the same time to allow you to have shared storage between those instances.

A notable restriction is that a Volume can only be attached to instances in the same availability zone as the Volume itself.

The following demonstrates how to create a 500 GiB encrypted Volume in the us-west-2a availability zone, and give a role the ability to attach that Volume to a specific instance:

ts
declare const instance: ec2.Instance;
declare const role: iam.Role;

const volume = new ec2.Volume(this, 'Volume', {
  availabilityZone: 'us-west-2a',
  size: Size.gibibytes(500),
  encrypted: true,
});

volume.grantAttachVolume(role, [instance]);
python
# instance: ec2.Instance
# role: iam.Role


volume = ec2.Volume(self, "Volume",
    availability_zone="us-west-2a",
    size=Size.gibibytes(500),
    encrypted=True
)

volume.grant_attach_volume(role, [instance])
java
Instance instance;
Role role;


Volume volume = Volume.Builder.create(this, "Volume")
        .availabilityZone("us-west-2a")
        .size(Size.gibibytes(500))
        .encrypted(true)
        .build();

volume.grantAttachVolume(role, List.of(instance));
csharp
Instance instance;
Role role;


var volume = new Volume(this, "Volume", new VolumeProps {
    AvailabilityZone = "us-west-2a",
    Size = Size.Gibibytes(500),
    Encrypted = true
});

volume.GrantAttachVolume(role, new [] { instance });
go
var instance Instance
var role Role


volume := ec2.NewVolume(this, jsii.String("Volume"), &VolumeProps{
	AvailabilityZone: jsii.String("us-west-2a"),
	Size: awscdk.Size_Gibibytes(jsii.Number(500)),
	Encrypted: jsii.Boolean(true),
})

volume.grantAttachVolume(role, []IInstanceRef{
	instance,
})

Instances Attaching Volumes to Themselves ​

If you need to grant an instance the ability to attach/detach an EBS volume to/from itself, then using grantAttachVolume and grantDetachVolume as outlined above will lead to an unresolvable circular reference between the instance role and the instance. In this case, use grantAttachVolumeByResourceTag and grantDetachVolumeByResourceTag as follows:

ts
declare const instance: ec2.Instance;
declare const volume: ec2.Volume;

const attachGrant = volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]);
const detachGrant = volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance]);
python
# instance: ec2.Instance
# volume: ec2.Volume


attach_grant = volume.grant_attach_volume_by_resource_tag(instance.grant_principal, [instance])
detach_grant = volume.grant_detach_volume_by_resource_tag(instance.grant_principal, [instance])
java
Instance instance;
Volume volume;


Grant attachGrant = volume.grantAttachVolumeByResourceTag(instance.getGrantPrincipal(), List.of(instance));
Grant detachGrant = volume.grantDetachVolumeByResourceTag(instance.getGrantPrincipal(), List.of(instance));
csharp
Instance instance;
Volume volume;


var attachGrant = volume.GrantAttachVolumeByResourceTag(instance.GrantPrincipal, new [] { instance });
var detachGrant = volume.GrantDetachVolumeByResourceTag(instance.GrantPrincipal, new [] { instance });
go
var instance Instance
var volume Volume


attachGrant := volume.grantAttachVolumeByResourceTag(instance.GrantPrincipal, []Construct{
	instance,
})
detachGrant := volume.grantDetachVolumeByResourceTag(instance.GrantPrincipal, []Construct{
	instance,
})

Attaching Volumes ​

The Amazon EC2 documentation for Linux Instances and Windows Instances contains information on how to attach and detach your Volumes to/from instances, and how to format them for use.

The following is a sample skeleton of EC2 UserData that can be used to attach a Volume to the Linux instance that it is running on:

ts
declare const instance: ec2.Instance;
declare const volume: ec2.Volume;

volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]);
const targetDevice = '/dev/xvdz';
instance.userData.addCommands(
  // Retrieve token for accessing EC2 instance metadata (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html)
  `TOKEN=$(curl -SsfX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")`,
  // Retrieve the instance Id of the current EC2 instance
  `INSTANCE_ID=$(curl -SsfH "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id)`,
  // Attach the volume to /dev/xvdz
  `aws --region ${Stack.of(this).region} ec2 attach-volume --volume-id ${volume.volumeId} --instance-id $INSTANCE_ID --device ${targetDevice}`,
  // Wait until the volume has attached
  `while ! test -e ${targetDevice}; do sleep 1; done`
  // The volume will now be mounted. You may have to add additional code to format the volume if it has not been prepared.
);
python
# instance: ec2.Instance
# volume: ec2.Volume


volume.grant_attach_volume_by_resource_tag(instance.grant_principal, [instance])
target_device = "/dev/xvdz"
instance.user_data.add_commands("TOKEN=$(curl -SsfX PUT \"http://169.254.169.254/latest/api/token\" -H \"X-aws-ec2-metadata-token-ttl-seconds: 21600\")", "INSTANCE_ID=$(curl -SsfH \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data/instance-id)", f"aws --region {Stack.of(this).region} ec2 attach-volume --volume-id {volume.volumeId} --instance-id $INSTANCE_ID --device {targetDevice}", f"while ! test -e {targetDevice}; do sleep 1; done")
java
Instance instance;
Volume volume;


volume.grantAttachVolumeByResourceTag(instance.getGrantPrincipal(), List.of(instance));
String targetDevice = "/dev/xvdz";
instance.userData.addCommands("TOKEN=$(curl -SsfX PUT \"http://169.254.169.254/latest/api/token\" -H \"X-aws-ec2-metadata-token-ttl-seconds: 21600\")", "INSTANCE_ID=$(curl -SsfH \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data/instance-id)", String.format("aws --region %s ec2 attach-volume --volume-id %s --instance-id $INSTANCE_ID --device %s", Stack.of(this).getRegion(), volume.getVolumeId(), targetDevice), String.format("while ! test -e %s; do sleep 1; done", targetDevice));
csharp
Instance instance;
Volume volume;


volume.GrantAttachVolumeByResourceTag(instance.GrantPrincipal, new [] { instance });
var targetDevice = "/dev/xvdz";
instance.UserData.AddCommands("TOKEN=$(curl -SsfX PUT \"http://169.254.169.254/latest/api/token\" -H \"X-aws-ec2-metadata-token-ttl-seconds: 21600\")", "INSTANCE_ID=$(curl -SsfH \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data/instance-id)", $"aws --region {Stack.of(this).region} ec2 attach-volume --volume-id {volume.volumeId} --instance-id $INSTANCE_ID --device {targetDevice}", $"while ! test -e {targetDevice}; do sleep 1; done");
go
var instance Instance
var volume Volume


volume.grantAttachVolumeByResourceTag(instance.GrantPrincipal, []Construct{
	instance,
})
targetDevice := "/dev/xvdz"
instance.UserData.AddCommands(jsii.String("TOKEN=$(curl -SsfX PUT \"http://169.254.169.254/latest/api/token\" -H \"X-aws-ec2-metadata-token-ttl-seconds: 21600\")"), jsii.String("INSTANCE_ID=$(curl -SsfH \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data/instance-id)"),
// Attach the volume to /dev/xvdz
fmt.Sprintf("aws --region %v ec2 attach-volume --volume-id %v --instance-id $INSTANCE_ID --device %v", awscdk.stack_Of(this).Region, volume.VolumeId, targetDevice),
// Wait until the volume has attached
fmt.Sprintf("while ! test -e %v; do sleep 1; done", targetDevice))

Tagging Volumes ​

You can configure tag propagation on volume creation.

ts
  declare const vpc: ec2.Vpc;
  declare const instanceType: ec2.InstanceType;
  declare const machineImage: ec2.IMachineImage;

  new ec2.Instance(this, 'Instance', {
    vpc,
    machineImage,
    instanceType,
    propagateTagsToVolumeOnCreation: true,
  });
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    machine_image=machine_image,
    instance_type=instance_type,
    propagate_tags_to_volume_on_creation=True
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .machineImage(machineImage)
        .instanceType(instanceType)
        .propagateTagsToVolumeOnCreation(true)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    MachineImage = machineImage,
    InstanceType = instanceType,
    PropagateTagsToVolumeOnCreation = true
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	MachineImage: MachineImage,
	InstanceType: InstanceType,
	PropagateTagsToVolumeOnCreation: jsii.Boolean(true),
})

Throughput on GP3 Volumes ​

You can specify the throughput of a GP3 volume from 125 (default) to 2000.

ts
new ec2.Volume(this, 'Volume', {
  availabilityZone: 'us-east-1a',
  size: Size.gibibytes(125),
  volumeType: ec2.EbsDeviceVolumeType.GP3,
  throughput: 125,
});
python
ec2.Volume(self, "Volume",
    availability_zone="us-east-1a",
    size=Size.gibibytes(125),
    volume_type=ec2.EbsDeviceVolumeType.GP3,
    throughput=125
)
java
Volume.Builder.create(this, "Volume")
        .availabilityZone("us-east-1a")
        .size(Size.gibibytes(125))
        .volumeType(EbsDeviceVolumeType.GP3)
        .throughput(125)
        .build();
csharp
new Volume(this, "Volume", new VolumeProps {
    AvailabilityZone = "us-east-1a",
    Size = Size.Gibibytes(125),
    VolumeType = EbsDeviceVolumeType.GP3,
    Throughput = 125
});
go
ec2.NewVolume(this, jsii.String("Volume"), &VolumeProps{
	AvailabilityZone: jsii.String("us-east-1a"),
	Size: awscdk.Size_Gibibytes(jsii.Number(125)),
	VolumeType: ec2.EbsDeviceVolumeType_GP3,
	Throughput: jsii.Number(125),
})

Volume initialization rate ​

When creating an EBS volume from a snapshot, you can specify the volume initialization rate at which the snapshot blocks are downloaded from Amazon S3 to the volume. Specifying a volume initialization rate ensures that the volume is initialized at a predictable and consistent rate after creation.

ts
new ec2.Volume(this, 'Volume', {
  availabilityZone: 'us-east-1a',
  size: Size.gibibytes(500),
  snapshotId: 'snap-1234567890abcdef0',
  volumeInitializationRate: Size.mebibytes(250),
});
python
ec2.Volume(self, "Volume",
    availability_zone="us-east-1a",
    size=Size.gibibytes(500),
    snapshot_id="snap-1234567890abcdef0",
    volume_initialization_rate=Size.mebibytes(250)
)
java
Volume.Builder.create(this, "Volume")
        .availabilityZone("us-east-1a")
        .size(Size.gibibytes(500))
        .snapshotId("snap-1234567890abcdef0")
        .volumeInitializationRate(Size.mebibytes(250))
        .build();
csharp
new Volume(this, "Volume", new VolumeProps {
    AvailabilityZone = "us-east-1a",
    Size = Size.Gibibytes(500),
    SnapshotId = "snap-1234567890abcdef0",
    VolumeInitializationRate = Size.Mebibytes(250)
});
go
ec2.NewVolume(this, jsii.String("Volume"), &VolumeProps{
	AvailabilityZone: jsii.String("us-east-1a"),
	Size: awscdk.Size_Gibibytes(jsii.Number(500)),
	SnapshotId: jsii.String("snap-1234567890abcdef0"),
	VolumeInitializationRate: awscdk.Size_Mebibytes(jsii.Number(250)),
})

The volumeInitializationRate must be:

  • Between 100 and 300 MiB/s
  • Only specified when creating a volume from a snapshot

Configuring Instance Metadata Service (IMDS) ​

Comprehensive Metadata Options ​

You can configure EC2 Instance Metadata Service options using individual properties. This provides comprehensive control over all metadata service settings:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

// Example 1: Enforce IMDSv2 with comprehensive options
new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,
  httpEndpoint: true,
  httpProtocolIpv6: false,
  httpPutResponseHopLimit: 2,
  httpTokens: ec2.HttpTokens.REQUIRED,
  instanceMetadataTags: true,
});

// Example 2: Enforce IMDSv2 with minimal configuration
new ec2.Instance(this, 'SecureInstance', {
  vpc,
  instanceType,
  machineImage,
  httpTokens: ec2.HttpTokens.REQUIRED,
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


# Example 1: Enforce IMDSv2 with comprehensive options
ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,
    http_endpoint=True,
    http_protocol_ipv6=False,
    http_put_response_hop_limit=2,
    http_tokens=ec2.HttpTokens.REQUIRED,
    instance_metadata_tags=True
)

# Example 2: Enforce IMDSv2 with minimal configuration
ec2.Instance(self, "SecureInstance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,
    http_tokens=ec2.HttpTokens.REQUIRED
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


// Example 1: Enforce IMDSv2 with comprehensive options
// Example 1: Enforce IMDSv2 with comprehensive options
Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)
        .httpEndpoint(true)
        .httpProtocolIpv6(false)
        .httpPutResponseHopLimit(2)
        .httpTokens(HttpTokens.REQUIRED)
        .instanceMetadataTags(true)
        .build();

// Example 2: Enforce IMDSv2 with minimal configuration
// Example 2: Enforce IMDSv2 with minimal configuration
Instance.Builder.create(this, "SecureInstance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)
        .httpTokens(HttpTokens.REQUIRED)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


// Example 1: Enforce IMDSv2 with comprehensive options
// Example 1: Enforce IMDSv2 with comprehensive options
new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,
    HttpEndpoint = true,
    HttpProtocolIpv6 = false,
    HttpPutResponseHopLimit = 2,
    HttpTokens = HttpTokens.REQUIRED,
    InstanceMetadataTags = true
});

// Example 2: Enforce IMDSv2 with minimal configuration
// Example 2: Enforce IMDSv2 with minimal configuration
new Instance(this, "SecureInstance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,
    HttpTokens = HttpTokens.REQUIRED
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


// Example 1: Enforce IMDSv2 with comprehensive options
// Example 1: Enforce IMDSv2 with comprehensive options
ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,
	HttpEndpoint: jsii.Boolean(true),
	HttpProtocolIpv6: jsii.Boolean(false),
	HttpPutResponseHopLimit: jsii.Number(2),
	HttpTokens: ec2.HttpTokens_REQUIRED,
	InstanceMetadataTags: jsii.Boolean(true),
})

// Example 2: Enforce IMDSv2 with minimal configuration
// Example 2: Enforce IMDSv2 with minimal configuration
ec2.NewInstance(this, jsii.String("SecureInstance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,
	HttpTokens: ec2.HttpTokens_REQUIRED,
})

Simple IMDSv2 Enforcement ​

For simple IMDSv2 enforcement without additional configuration, you can use the requireImdsv2 property:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;
declare const machineImage: ec2.IMachineImage;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage,

  // Simple IMDSv2 enforcement
  requireImdsv2: true,
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType
# machine_image: ec2.IMachineImage


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=machine_image,

    # Simple IMDSv2 enforcement
    require_imdsv2=True
)
java
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(machineImage)

        // Simple IMDSv2 enforcement
        .requireImdsv2(true)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;
IMachineImage machineImage;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = machineImage,

    // Simple IMDSv2 enforcement
    RequireImdsv2 = true
});
go
var vpc Vpc
var instanceType InstanceType
var machineImage IMachineImage


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: MachineImage,

	// Simple IMDSv2 enforcement
	RequireImdsv2: jsii.Boolean(true),
})

Applying to Multiple Instances ​

You can also use the either the InstanceRequireImdsv2Aspect for EC2 instances or the LaunchTemplateRequireImdsv2Aspect for EC2 launch templates to apply the operation to multiple instances or launch templates, respectively.

The following example demonstrates how to use the InstanceRequireImdsv2Aspect to require IMDSv2 for all EC2 instances in a stack:

ts
const aspect = new ec2.InstanceRequireImdsv2Aspect();
Aspects.of(this).add(aspect);
python
aspect = ec2.InstanceRequireImdsv2Aspect()
Aspects.of(self).add(aspect)
java
InstanceRequireImdsv2Aspect aspect = new InstanceRequireImdsv2Aspect();
Aspects.of(this).add(aspect);
csharp
var aspect = new InstanceRequireImdsv2Aspect();
Aspects.Of(this).Add(aspect);
go
aspect := ec2.NewInstanceRequireImdsv2Aspect()
awscdk.Aspects_Of(this).Add(aspect)

Associating a Public IP Address with an Instance ​

All subnets have an attribute that determines whether instances launched into that subnet are assigned a public IPv4 address. This attribute is set to true by default for default public subnets. Thus, an EC2 instance launched into a default public subnet will be assigned a public IPv4 address. Nondefault public subnets have this attribute set to false by default and any EC2 instance launched into a nondefault public subnet will not be assigned a public IPv4 address automatically. To automatically assign a public IPv4 address to an instance launched into a nondefault public subnet, you can set the associatePublicIpAddress property on the Instance construct to true. Alternatively, to not automatically assign a public IPv4 address to an instance launched into a default public subnet, you can set associatePublicIpAddress to false. Including this property, removing this property, or updating the value of this property on an existing instance will result in replacement of the instance.

ts
const vpc = new ec2.Vpc(this, 'VPC', {
  cidr: '10.0.0.0/16',
  natGateways: 0,
  maxAzs: 3,
  subnetConfiguration: [
    {
      name: 'public-subnet-1',
      subnetType: ec2.SubnetType.PUBLIC,
      cidrMask: 24,
    },
  ],
});

const instance = new ec2.Instance(this, 'Instance', {
  vpc,
  vpcSubnets: { subnetGroupName: 'public-subnet-1' },
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
  machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
  detailedMonitoring: true,
  associatePublicIpAddress: true,
});
python
vpc = ec2.Vpc(self, "VPC",
    cidr="10.0.0.0/16",
    nat_gateways=0,
    max_azs=3,
    subnet_configuration=[ec2.SubnetConfiguration(
        name="public-subnet-1",
        subnet_type=ec2.SubnetType.PUBLIC,
        cidr_mask=24
    )
    ]
)

instance = ec2.Instance(self, "Instance",
    vpc=vpc,
    vpc_subnets=ec2.SubnetSelection(subnet_group_name="public-subnet-1"),
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
    machine_image=ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2),
    detailed_monitoring=True,
    associate_public_ip_address=True
)
java
Vpc vpc = Vpc.Builder.create(this, "VPC")
        .cidr("10.0.0.0/16")
        .natGateways(0)
        .maxAzs(3)
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                .name("public-subnet-1")
                .subnetType(SubnetType.PUBLIC)
                .cidrMask(24)
                .build()))
        .build();

Instance instance = Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .vpcSubnets(SubnetSelection.builder().subnetGroupName("public-subnet-1").build())
        .instanceType(InstanceType.of(InstanceClass.T3, InstanceSize.NANO))
        .machineImage(AmazonLinuxImage.Builder.create().generation(AmazonLinuxGeneration.AMAZON_LINUX_2).build())
        .detailedMonitoring(true)
        .associatePublicIpAddress(true)
        .build();
csharp
var vpc = new Vpc(this, "VPC", new VpcProps {
    Cidr = "10.0.0.0/16",
    NatGateways = 0,
    MaxAzs = 3,
    SubnetConfiguration = new [] { new SubnetConfiguration {
        Name = "public-subnet-1",
        SubnetType = SubnetType.PUBLIC,
        CidrMask = 24
    } }
});

var instance = new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    VpcSubnets = new SubnetSelection { SubnetGroupName = "public-subnet-1" },
    InstanceType = InstanceType.Of(InstanceClass.T3, InstanceSize.NANO),
    MachineImage = new AmazonLinuxImage(new AmazonLinuxImageProps { Generation = AmazonLinuxGeneration.AMAZON_LINUX_2 }),
    DetailedMonitoring = true,
    AssociatePublicIpAddress = true
});
go
vpc := ec2.NewVpc(this, jsii.String("VPC"), &VpcProps{
	Cidr: jsii.String("10.0.0.0/16"),
	NatGateways: jsii.Number(0),
	MaxAzs: jsii.Number(3),
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			Name: jsii.String("public-subnet-1"),
			SubnetType: ec2.SubnetType_PUBLIC,
			CidrMask: jsii.Number(24),
		},
	},
})

instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	VpcSubnets: &SubnetSelection{
		SubnetGroupName: jsii.String("public-subnet-1"),
	},
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_T3, ec2.InstanceSize_NANO),
	MachineImage: ec2.NewAmazonLinuxImage(&AmazonLinuxImageProps{
		Generation: ec2.AmazonLinuxGeneration_AMAZON_LINUX_2,
	}),
	DetailedMonitoring: jsii.Boolean(true),
	AssociatePublicIpAddress: jsii.Boolean(true),
})

Specifying a key pair ​

To allow SSH access to an EC2 instance by default, a Key Pair must be specified. Key pairs can be provided with the keyPair property to instances and launch templates. You can create a key pair for an instance like this:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;

const keyPair = new ec2.KeyPair(this, 'KeyPair', {
  type: ec2.KeyPairType.ED25519,
  format: ec2.KeyPairFormat.PEM,
});
const instance = new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  // Use the custom key pair
  keyPair,
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType


key_pair = ec2.KeyPair(self, "KeyPair",
    type=ec2.KeyPairType.ED25519,
    format=ec2.KeyPairFormat.PEM
)
instance = ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    # Use the custom key pair
    key_pair=key_pair
)
java
Vpc vpc;
InstanceType instanceType;


KeyPair keyPair = KeyPair.Builder.create(this, "KeyPair")
        .type(KeyPairType.ED25519)
        .format(KeyPairFormat.PEM)
        .build();
Instance instance = Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        // Use the custom key pair
        .keyPair(keyPair)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;


var keyPair = new KeyPair(this, "KeyPair", new KeyPairProps {
    Type = KeyPairType.ED25519,
    Format = KeyPairFormat.PEM
});
var instance = new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    // Use the custom key pair
    KeyPair = keyPair
});
go
var vpc Vpc
var instanceType InstanceType


keyPair := ec2.NewKeyPair(this, jsii.String("KeyPair"), &KeyPairProps{
	Type: ec2.KeyPairType_ED25519,
	Format: ec2.KeyPairFormat_PEM,
})
instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	// Use the custom key pair
	KeyPair: KeyPair,
})

When a new EC2 Key Pair is created (without imported material), the private key material is automatically stored in Systems Manager Parameter Store. This can be retrieved from the key pair construct:

ts
const keyPair = new ec2.KeyPair(this, 'KeyPair');
const privateKey = keyPair.privateKey;
python
key_pair = ec2.KeyPair(self, "KeyPair")
private_key = key_pair.private_key
java
KeyPair keyPair = new KeyPair(this, "KeyPair");
IStringParameter privateKey = keyPair.getPrivateKey();
csharp
var keyPair = new KeyPair(this, "KeyPair");
var privateKey = keyPair.PrivateKey;
go
keyPair := ec2.NewKeyPair(this, jsii.String("KeyPair"))
privateKey := keyPair.privateKey

If you already have an SSH key that you wish to use in EC2, that can be provided when constructing the KeyPair. If public key material is provided, the key pair is considered "imported" and there will not be any data automatically stored in Systems Manager Parameter Store and the type property cannot be specified for the key pair.

ts
const keyPair = new ec2.KeyPair(this, 'KeyPair', {
  publicKeyMaterial: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7jpNzG+YG0s+xIGWbxrxIZiiozHOEuzIJacvASP0mq",
})
python
key_pair = ec2.KeyPair(self, "KeyPair",
    public_key_material="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7jpNzG+YG0s+xIGWbxrxIZiiozHOEuzIJacvASP0mq"
)
java
KeyPair keyPair = KeyPair.Builder.create(this, "KeyPair")
        .publicKeyMaterial("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7jpNzG+YG0s+xIGWbxrxIZiiozHOEuzIJacvASP0mq")
        .build();
csharp
var keyPair = new KeyPair(this, "KeyPair", new KeyPairProps {
    PublicKeyMaterial = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7jpNzG+YG0s+xIGWbxrxIZiiozHOEuzIJacvASP0mq"
});
go
keyPair := ec2.NewKeyPair(this, jsii.String("KeyPair"), &KeyPairProps{
	PublicKeyMaterial: jsii.String("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7jpNzG+YG0s+xIGWbxrxIZiiozHOEuzIJacvASP0mq"),
})

Using an existing EC2 Key Pair ​

If you already have an EC2 Key Pair created outside of the CDK, you can import that key to your CDK stack.

You can import it purely by name:

ts
const keyPair = ec2.KeyPair.fromKeyPairName(this, 'KeyPair', 'the-keypair-name');
python
key_pair = ec2.KeyPair.from_key_pair_name(self, "KeyPair", "the-keypair-name")
java
IKeyPair keyPair = KeyPair.fromKeyPairName(this, "KeyPair", "the-keypair-name");
csharp
var keyPair = KeyPair.FromKeyPairName(this, "KeyPair", "the-keypair-name");
go
keyPair := ec2.KeyPair_FromKeyPairName(this, jsii.String("KeyPair"), jsii.String("the-keypair-name"))

Or by specifying additional attributes:

ts
const keyPair = ec2.KeyPair.fromKeyPairAttributes(this, 'KeyPair', {
  keyPairName: 'the-keypair-name',
  type: ec2.KeyPairType.RSA,
})
python
key_pair = ec2.KeyPair.from_key_pair_attributes(self, "KeyPair",
    key_pair_name="the-keypair-name",
    type=ec2.KeyPairType.RSA
)
java
IKeyPair keyPair = KeyPair.fromKeyPairAttributes(this, "KeyPair", KeyPairAttributes.builder()
        .keyPairName("the-keypair-name")
        .type(KeyPairType.RSA)
        .build());
csharp
var keyPair = KeyPair.FromKeyPairAttributes(this, "KeyPair", new KeyPairAttributes {
    KeyPairName = "the-keypair-name",
    Type = KeyPairType.RSA
});
go
keyPair := ec2.KeyPair_FromKeyPairAttributes(this, jsii.String("KeyPair"), &KeyPairAttributes{
	KeyPairName: jsii.String("the-keypair-name"),
	Type: ec2.KeyPairType_RSA,
})

Using IPv6 IPs ​

Instances can be given IPv6 IPs by launching them into a subnet of a dual stack VPC.

ts
const vpc = new ec2.Vpc(this, 'Ip6VpcDualStack', {
  ipProtocol: ec2.IpProtocol.DUAL_STACK,
  subnetConfiguration: [
    {
      name: 'Public',
      subnetType: ec2.SubnetType.PUBLIC,
      mapPublicIpOnLaunch: true,
    },
    {
      name: 'Private',
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
    },
  ],
});

const instance = new ec2.Instance(this, 'MyInstance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux2(),
  vpc: vpc,
  vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
  allowAllIpv6Outbound: true,

  // ...
});

instance.connections.allowFrom(ec2.Peer.anyIpv6(), ec2.Port.allIcmpV6(), 'allow ICMPv6');
python
vpc = ec2.Vpc(self, "Ip6VpcDualStack",
    ip_protocol=ec2.IpProtocol.DUAL_STACK,
    subnet_configuration=[ec2.SubnetConfiguration(
        name="Public",
        subnet_type=ec2.SubnetType.PUBLIC,
        map_public_ip_on_launch=True
    ), ec2.SubnetConfiguration(
        name="Private",
        subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
    )
    ]
)

instance = ec2.Instance(self, "MyInstance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
    machine_image=ec2.MachineImage.latest_amazon_linux2(),
    vpc=vpc,
    vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
    allow_all_ipv6_outbound=True
)

instance.connections.allow_from(ec2.Peer.any_ipv6(), ec2.Port.all_icmp_v6(), "allow ICMPv6")
java
Vpc vpc = Vpc.Builder.create(this, "Ip6VpcDualStack")
        .ipProtocol(IpProtocol.DUAL_STACK)
        .subnetConfiguration(List.of(SubnetConfiguration.builder()
                .name("Public")
                .subnetType(SubnetType.PUBLIC)
                .mapPublicIpOnLaunch(true)
                .build(), SubnetConfiguration.builder()
                .name("Private")
                .subnetType(SubnetType.PRIVATE_ISOLATED)
                .build()))
        .build();

Instance instance = Instance.Builder.create(this, "MyInstance")
        .instanceType(InstanceType.of(InstanceClass.T2, InstanceSize.MICRO))
        .machineImage(MachineImage.latestAmazonLinux2())
        .vpc(vpc)
        .vpcSubnets(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build())
        .allowAllIpv6Outbound(true)
        .build();

instance.connections.allowFrom(Peer.anyIpv6(), Port.allIcmpV6(), "allow ICMPv6");
csharp
var vpc = new Vpc(this, "Ip6VpcDualStack", new VpcProps {
    IpProtocol = IpProtocol.DUAL_STACK,
    SubnetConfiguration = new [] { new SubnetConfiguration {
        Name = "Public",
        SubnetType = SubnetType.PUBLIC,
        MapPublicIpOnLaunch = true
    }, new SubnetConfiguration {
        Name = "Private",
        SubnetType = SubnetType.PRIVATE_ISOLATED
    } }
});

var instance = new Instance(this, "MyInstance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.T2, InstanceSize.MICRO),
    MachineImage = MachineImage.LatestAmazonLinux2(),
    Vpc = vpc,
    VpcSubnets = new SubnetSelection { SubnetType = SubnetType.PUBLIC },
    AllowAllIpv6Outbound = true
});

instance.Connections.AllowFrom(Peer.AnyIpv6(), Port.AllIcmpV6(), "allow ICMPv6");
go
vpc := ec2.NewVpc(this, jsii.String("Ip6VpcDualStack"), &VpcProps{
	IpProtocol: ec2.IpProtocol_DUAL_STACK,
	SubnetConfiguration: []SubnetConfiguration{
		&SubnetConfiguration{
			Name: jsii.String("Public"),
			SubnetType: ec2.SubnetType_PUBLIC,
			MapPublicIpOnLaunch: jsii.Boolean(true),
		},
		&SubnetConfiguration{
			Name: jsii.String("Private"),
			SubnetType: ec2.SubnetType_PRIVATE_ISOLATED,
		},
	},
})

instance := ec2.NewInstance(this, jsii.String("MyInstance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_T2, ec2.InstanceSize_MICRO),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2(),
	Vpc: vpc,
	VpcSubnets: &SubnetSelection{
		SubnetType: ec2.SubnetType_PUBLIC,
	},
	AllowAllIpv6Outbound: jsii.Boolean(true),
})

instance.Connections.AllowFrom(ec2.Peer_AnyIpv6(), ec2.Port_AllIcmpV6(), jsii.String("allow ICMPv6"))

Note to set mapPublicIpOnLaunch to true in the subnetConfiguration.

Additionally, IPv6 support varies by instance type. Most instance types have IPv6 support with exception of m1-m3, c1, g2, and t1.micro. A full list can be found here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI.

Specifying the IPv6 Address ​

If you want to specify the number of IPv6 addresses to assign to the instance, you can use the ipv6AddresseCount property:

ts
// dual stack VPC
declare const vpc: ec2.Vpc;

const instance = new ec2.Instance(this, 'MyInstance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux2(),
  vpc: vpc,
  vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
  // Assign 2 IPv6 addresses to the instance
  ipv6AddressCount: 2,
});
python
# dual stack VPC
# vpc: ec2.Vpc


instance = ec2.Instance(self, "MyInstance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
    machine_image=ec2.MachineImage.latest_amazon_linux2(),
    vpc=vpc,
    vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
    # Assign 2 IPv6 addresses to the instance
    ipv6_address_count=2
)
java
// dual stack VPC
Vpc vpc;


Instance instance = Instance.Builder.create(this, "MyInstance")
        .instanceType(InstanceType.of(InstanceClass.M5, InstanceSize.LARGE))
        .machineImage(MachineImage.latestAmazonLinux2())
        .vpc(vpc)
        .vpcSubnets(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build())
        // Assign 2 IPv6 addresses to the instance
        .ipv6AddressCount(2)
        .build();
csharp
// dual stack VPC
Vpc vpc;


var instance = new Instance(this, "MyInstance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.M5, InstanceSize.LARGE),
    MachineImage = MachineImage.LatestAmazonLinux2(),
    Vpc = vpc,
    VpcSubnets = new SubnetSelection { SubnetType = SubnetType.PUBLIC },
    // Assign 2 IPv6 addresses to the instance
    Ipv6AddressCount = 2
});
go
// dual stack VPC
var vpc Vpc


instance := ec2.NewInstance(this, jsii.String("MyInstance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_M5, ec2.InstanceSize_LARGE),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2(),
	Vpc: vpc,
	VpcSubnets: &SubnetSelection{
		SubnetType: ec2.SubnetType_PUBLIC,
	},
	// Assign 2 IPv6 addresses to the instance
	Ipv6AddressCount: jsii.Number(2),
})

Credit configuration modes for burstable instances ​

You can set the credit configuration mode for burstable instances (T2, T3, T3a and T4g instance types):

ts
declare const vpc: ec2.Vpc;

const instance = new ec2.Instance(this, 'Instance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux2(),
  vpc: vpc,
  creditSpecification: ec2.CpuCredits.STANDARD,
});
python
# vpc: ec2.Vpc


instance = ec2.Instance(self, "Instance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
    machine_image=ec2.MachineImage.latest_amazon_linux2(),
    vpc=vpc,
    credit_specification=ec2.CpuCredits.STANDARD
)
java
Vpc vpc;


Instance instance = Instance.Builder.create(this, "Instance")
        .instanceType(InstanceType.of(InstanceClass.T3, InstanceSize.MICRO))
        .machineImage(MachineImage.latestAmazonLinux2())
        .vpc(vpc)
        .creditSpecification(CpuCredits.STANDARD)
        .build();
csharp
Vpc vpc;


var instance = new Instance(this, "Instance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.T3, InstanceSize.MICRO),
    MachineImage = MachineImage.LatestAmazonLinux2(),
    Vpc = vpc,
    CreditSpecification = CpuCredits.STANDARD
});
go
var vpc Vpc


instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_T3, ec2.InstanceSize_MICRO),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2(),
	Vpc: vpc,
	CreditSpecification: ec2.CpuCredits_STANDARD,
})

It is also possible to set the credit configuration mode for NAT instances.

ts
const natInstanceProvider = ec2.NatProvider.instance({
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.LARGE),
  machineImage: new ec2.AmazonLinuxImage(),
  creditSpecification: ec2.CpuCredits.UNLIMITED,
});
new ec2.Vpc(this, 'VPC', {
  natGatewayProvider: natInstanceProvider,
});
python
nat_instance_provider = ec2.NatProvider.instance(
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.LARGE),
    machine_image=ec2.AmazonLinuxImage(),
    credit_specification=ec2.CpuCredits.UNLIMITED
)
ec2.Vpc(self, "VPC",
    nat_gateway_provider=nat_instance_provider
)
java
NatInstanceProvider natInstanceProvider = NatProvider.instance(NatInstanceProps.builder()
        .instanceType(InstanceType.of(InstanceClass.T4G, InstanceSize.LARGE))
        .machineImage(new AmazonLinuxImage())
        .creditSpecification(CpuCredits.UNLIMITED)
        .build());
Vpc.Builder.create(this, "VPC")
        .natGatewayProvider(natInstanceProvider)
        .build();
csharp
var natInstanceProvider = NatProvider.Instance(new NatInstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.T4G, InstanceSize.LARGE),
    MachineImage = new AmazonLinuxImage(),
    CreditSpecification = CpuCredits.UNLIMITED
});
new Vpc(this, "VPC", new VpcProps {
    NatGatewayProvider = natInstanceProvider
});
go
natInstanceProvider := ec2.NatProvider_Instance(&NatInstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_T4G, ec2.InstanceSize_LARGE),
	MachineImage: ec2.NewAmazonLinuxImage(),
	CreditSpecification: ec2.CpuCredits_UNLIMITED,
})
ec2.NewVpc(this, jsii.String("VPC"), &VpcProps{
	NatGatewayProvider: natInstanceProvider,
})

Note: CpuCredits.UNLIMITED mode is not supported for T3 instances that are launched on a Dedicated Host.

Shutdown behavior ​

You can specify the behavior of the instance when you initiate shutdown from the instance (using the operating system command for system shutdown).

ts
declare const vpc: ec2.Vpc;

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
  machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
  instanceInitiatedShutdownBehavior: ec2.InstanceInitiatedShutdownBehavior.TERMINATE, // default is STOP
});
python
# vpc: ec2.Vpc


ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
    machine_image=ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2),
    instance_initiated_shutdown_behavior=ec2.InstanceInitiatedShutdownBehavior.TERMINATE
)
java
Vpc vpc;


Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(InstanceType.of(InstanceClass.T3, InstanceSize.NANO))
        .machineImage(AmazonLinuxImage.Builder.create().generation(AmazonLinuxGeneration.AMAZON_LINUX_2).build())
        .instanceInitiatedShutdownBehavior(InstanceInitiatedShutdownBehavior.TERMINATE)
        .build();
csharp
Vpc vpc;


new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = InstanceType.Of(InstanceClass.T3, InstanceSize.NANO),
    MachineImage = new AmazonLinuxImage(new AmazonLinuxImageProps { Generation = AmazonLinuxGeneration.AMAZON_LINUX_2 }),
    InstanceInitiatedShutdownBehavior = InstanceInitiatedShutdownBehavior.TERMINATE
});
go
var vpc Vpc


ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_T3, ec2.InstanceSize_NANO),
	MachineImage: ec2.NewAmazonLinuxImage(&AmazonLinuxImageProps{
		Generation: ec2.AmazonLinuxGeneration_AMAZON_LINUX_2,
	}),
	InstanceInitiatedShutdownBehavior: ec2.InstanceInitiatedShutdownBehavior_TERMINATE,
})

Enabling Nitro Enclaves ​

You can enable AWS Nitro Enclaves for your EC2 instances by setting the enclaveEnabled property to true. Nitro Enclaves is a feature of AWS Nitro System that enables creating isolated and highly constrained CPU environments known as enclaves.

ts
declare const vpc: ec2.Vpc;

const instance = new ec2.Instance(this, 'Instance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
  machineImage: new ec2.AmazonLinuxImage(),
  vpc: vpc,
  enclaveEnabled: true,
});
python
# vpc: ec2.Vpc


instance = ec2.Instance(self, "Instance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
    machine_image=ec2.AmazonLinuxImage(),
    vpc=vpc,
    enclave_enabled=True
)
java
Vpc vpc;


Instance instance = Instance.Builder.create(this, "Instance")
        .instanceType(InstanceType.of(InstanceClass.M5, InstanceSize.XLARGE))
        .machineImage(new AmazonLinuxImage())
        .vpc(vpc)
        .enclaveEnabled(true)
        .build();
csharp
Vpc vpc;


var instance = new Instance(this, "Instance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.M5, InstanceSize.XLARGE),
    MachineImage = new AmazonLinuxImage(),
    Vpc = vpc,
    EnclaveEnabled = true
});
go
var vpc Vpc


instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_M5, ec2.InstanceSize_XLARGE),
	MachineImage: ec2.NewAmazonLinuxImage(),
	Vpc: vpc,
	EnclaveEnabled: jsii.Boolean(true),
})

NOTE: You must use an instance type and operating system that support Nitro Enclaves. For more information, see Requirements.

Enabling Termination Protection ​

You can enable Termination Protection for your EC2 instances by setting the disableApiTermination property to true. Termination Protection controls whether the instance can be terminated using the AWS Management Console, AWS Command Line Interface (AWS CLI), or API.

ts
declare const vpc: ec2.Vpc;

const instance = new ec2.Instance(this, 'Instance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
  machineImage: new ec2.AmazonLinuxImage(),
  vpc: vpc,
  disableApiTermination: true,
});
python
# vpc: ec2.Vpc


instance = ec2.Instance(self, "Instance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
    machine_image=ec2.AmazonLinuxImage(),
    vpc=vpc,
    disable_api_termination=True
)
java
Vpc vpc;


Instance instance = Instance.Builder.create(this, "Instance")
        .instanceType(InstanceType.of(InstanceClass.M5, InstanceSize.XLARGE))
        .machineImage(new AmazonLinuxImage())
        .vpc(vpc)
        .disableApiTermination(true)
        .build();
csharp
Vpc vpc;


var instance = new Instance(this, "Instance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.M5, InstanceSize.XLARGE),
    MachineImage = new AmazonLinuxImage(),
    Vpc = vpc,
    DisableApiTermination = true
});
go
var vpc Vpc


instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_M5, ec2.InstanceSize_XLARGE),
	MachineImage: ec2.NewAmazonLinuxImage(),
	Vpc: vpc,
	DisableApiTermination: jsii.Boolean(true),
})

Enabling Instance Hibernation ​

You can enable Instance Hibernation for your EC2 instances by setting the hibernationEnabled property to true. Instance Hibernation saves the instance's in-memory (RAM) state when an instance is stopped, and restores that state when the instance is started.

ts
declare const vpc: ec2.Vpc;

const instance = new ec2.Instance(this, 'Instance', {
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
  machineImage: new ec2.AmazonLinuxImage(),
  vpc: vpc,
  hibernationEnabled: true,
  blockDevices: [{
    deviceName: '/dev/xvda',
    volume: ec2.BlockDeviceVolume.ebs(30, {
      volumeType: ec2.EbsDeviceVolumeType.GP3,
      encrypted: true,
      deleteOnTermination: true,
    }),
  }],
});
python
# vpc: ec2.Vpc


instance = ec2.Instance(self, "Instance",
    instance_type=ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
    machine_image=ec2.AmazonLinuxImage(),
    vpc=vpc,
    hibernation_enabled=True,
    block_devices=[ec2.BlockDevice(
        device_name="/dev/xvda",
        volume=ec2.BlockDeviceVolume.ebs(30,
            volume_type=ec2.EbsDeviceVolumeType.GP3,
            encrypted=True,
            delete_on_termination=True
        )
    )]
)
java
Vpc vpc;


Instance instance = Instance.Builder.create(this, "Instance")
        .instanceType(InstanceType.of(InstanceClass.M5, InstanceSize.XLARGE))
        .machineImage(new AmazonLinuxImage())
        .vpc(vpc)
        .hibernationEnabled(true)
        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("/dev/xvda")
                .volume(BlockDeviceVolume.ebs(30, EbsDeviceOptions.builder()
                        .volumeType(EbsDeviceVolumeType.GP3)
                        .encrypted(true)
                        .deleteOnTermination(true)
                        .build()))
                .build()))
        .build();
csharp
Vpc vpc;


var instance = new Instance(this, "Instance", new InstanceProps {
    InstanceType = InstanceType.Of(InstanceClass.M5, InstanceSize.XLARGE),
    MachineImage = new AmazonLinuxImage(),
    Vpc = vpc,
    HibernationEnabled = true,
    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/xvda",
        Volume = BlockDeviceVolume.Ebs(30, new EbsDeviceOptions {
            VolumeType = EbsDeviceVolumeType.GP3,
            Encrypted = true,
            DeleteOnTermination = true
        })
    } }
});
go
var vpc Vpc


instance := ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	InstanceType: ec2.InstanceType_Of(ec2.InstanceClass_M5, ec2.InstanceSize_XLARGE),
	MachineImage: ec2.NewAmazonLinuxImage(),
	Vpc: vpc,
	HibernationEnabled: jsii.Boolean(true),
	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/xvda"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(30), &EbsDeviceOptions{
				VolumeType: ec2.EbsDeviceVolumeType_GP3,
				Encrypted: jsii.Boolean(true),
				DeleteOnTermination: jsii.Boolean(true),
			}),
		},
	},
})

NOTE: You must use an instance and a volume that meet the requirements for hibernation. For more information, see Prerequisites for Amazon EC2 instance hibernation.

VPC Flow Logs ​

VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. Flow log data can be published to Amazon CloudWatch Logs and Amazon S3. After you've created a flow log, you can retrieve and view its data in the chosen destination. (<https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html>).

By default, a flow log will be created with CloudWatch Logs as the destination.

You can create a flow log like this:

ts
declare const vpc: ec2.Vpc;

new ec2.FlowLog(this, 'FlowLog', {
  resourceType: ec2.FlowLogResourceType.fromVpc(vpc)
})
python
# vpc: ec2.Vpc


ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc)
)
java
Vpc vpc;


FlowLog.Builder.create(this, "FlowLog")
        .resourceType(FlowLogResourceType.fromVpc(vpc))
        .build();
csharp
Vpc vpc;


new FlowLog(this, "FlowLog", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromVpc(vpc)
});
go
var vpc Vpc


ec2.NewFlowLog(this, jsii.String("FlowLog"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_FromVpc(vpc),
})

Or you can add a Flow Log to a VPC by using the addFlowLog method like this:

ts
const vpc = new ec2.Vpc(this, 'Vpc');

vpc.addFlowLog('FlowLog');
python
vpc = ec2.Vpc(self, "Vpc")

vpc.add_flow_log("FlowLog")
java
Vpc vpc = new Vpc(this, "Vpc");

vpc.addFlowLog("FlowLog");
csharp
var vpc = new Vpc(this, "Vpc");

vpc.AddFlowLog("FlowLog");
go
vpc := ec2.NewVpc(this, jsii.String("Vpc"))

vpc.addFlowLog(jsii.String("FlowLog"))

You can also add multiple flow logs with different destinations.

ts
const vpc = new ec2.Vpc(this, 'Vpc');

vpc.addFlowLog('FlowLogS3', {
  destination: ec2.FlowLogDestination.toS3()
});

// Only reject traffic and interval every minute.
vpc.addFlowLog('FlowLogCloudWatch', {
  trafficType: ec2.FlowLogTrafficType.REJECT,
  maxAggregationInterval: ec2.FlowLogMaxAggregationInterval.ONE_MINUTE,
});
python
vpc = ec2.Vpc(self, "Vpc")

vpc.add_flow_log("FlowLogS3",
    destination=ec2.FlowLogDestination.to_s3()
)

# Only reject traffic and interval every minute.
vpc.add_flow_log("FlowLogCloudWatch",
    traffic_type=ec2.FlowLogTrafficType.REJECT,
    max_aggregation_interval=ec2.FlowLogMaxAggregationInterval.ONE_MINUTE
)
java
Vpc vpc = new Vpc(this, "Vpc");

vpc.addFlowLog("FlowLogS3", FlowLogOptions.builder()
        .destination(FlowLogDestination.toS3())
        .build());

// Only reject traffic and interval every minute.
vpc.addFlowLog("FlowLogCloudWatch", FlowLogOptions.builder()
        .trafficType(FlowLogTrafficType.REJECT)
        .maxAggregationInterval(FlowLogMaxAggregationInterval.ONE_MINUTE)
        .build());
csharp
var vpc = new Vpc(this, "Vpc");

vpc.AddFlowLog("FlowLogS3", new FlowLogOptions {
    Destination = FlowLogDestination.ToS3()
});

// Only reject traffic and interval every minute.
vpc.AddFlowLog("FlowLogCloudWatch", new FlowLogOptions {
    TrafficType = FlowLogTrafficType.REJECT,
    MaxAggregationInterval = FlowLogMaxAggregationInterval.ONE_MINUTE
});
go
vpc := ec2.NewVpc(this, jsii.String("Vpc"))

vpc.addFlowLog(jsii.String("FlowLogS3"), &FlowLogOptions{
	Destination: ec2.FlowLogDestination_ToS3(),
})

// Only reject traffic and interval every minute.
vpc.addFlowLog(jsii.String("FlowLogCloudWatch"), &FlowLogOptions{
	TrafficType: ec2.FlowLogTrafficType_REJECT,
	MaxAggregationInterval: ec2.FlowLogMaxAggregationInterval_ONE_MINUTE,
})

To create a Transit Gateway flow log, you can use the fromTransitGatewayId method:

ts
declare const tgw: ec2.CfnTransitGateway;

new ec2.FlowLog(this, 'TransitGatewayFlowLog', {
  resourceType: ec2.FlowLogResourceType.fromTransitGatewayId(tgw.ref)
})
python
# tgw: ec2.CfnTransitGateway


ec2.FlowLog(self, "TransitGatewayFlowLog",
    resource_type=ec2.FlowLogResourceType.from_transit_gateway_id(tgw.ref)
)
java
CfnTransitGateway tgw;


FlowLog.Builder.create(this, "TransitGatewayFlowLog")
        .resourceType(FlowLogResourceType.fromTransitGatewayId(tgw.getRef()))
        .build();
csharp
CfnTransitGateway tgw;


new FlowLog(this, "TransitGatewayFlowLog", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromTransitGatewayId(tgw.Ref)
});
go
var tgw CfnTransitGateway


ec2.NewFlowLog(this, jsii.String("TransitGatewayFlowLog"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_FromTransitGatewayId(tgw.ref),
})

To create a Transit Gateway Attachment flow log, you can use the fromTransitGatewayAttachmentId method:

ts
declare const tgwAttachment: ec2.CfnTransitGatewayAttachment;

new ec2.FlowLog(this, 'TransitGatewayAttachmentFlowLog', {
  resourceType: ec2.FlowLogResourceType.fromTransitGatewayAttachmentId(tgwAttachment.ref)
})
python
# tgw_attachment: ec2.CfnTransitGatewayAttachment


ec2.FlowLog(self, "TransitGatewayAttachmentFlowLog",
    resource_type=ec2.FlowLogResourceType.from_transit_gateway_attachment_id(tgw_attachment.ref)
)
java
CfnTransitGatewayAttachment tgwAttachment;


FlowLog.Builder.create(this, "TransitGatewayAttachmentFlowLog")
        .resourceType(FlowLogResourceType.fromTransitGatewayAttachmentId(tgwAttachment.getRef()))
        .build();
csharp
CfnTransitGatewayAttachment tgwAttachment;


new FlowLog(this, "TransitGatewayAttachmentFlowLog", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromTransitGatewayAttachmentId(tgwAttachment.Ref)
});
go
var tgwAttachment CfnTransitGatewayAttachment


ec2.NewFlowLog(this, jsii.String("TransitGatewayAttachmentFlowLog"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_FromTransitGatewayAttachmentId(tgwAttachment.ref),
})

For flow logs targeting TransitGateway and TransitGatewayAttachment, specifying the trafficType is not possible.

Custom Formatting ​

You can also custom format flow logs.

ts
const vpc = new ec2.Vpc(this, 'Vpc');

vpc.addFlowLog('FlowLog', {
  logFormat: [
    ec2.LogFormat.DST_PORT,
    ec2.LogFormat.SRC_PORT,
  ],
});

// If you just want to add a field to the default field
vpc.addFlowLog('FlowLog', {
  logFormat: [
    ec2.LogFormat.VERSION,
    ec2.LogFormat.ALL_DEFAULT_FIELDS,
  ],
});

// If AWS CDK does not support the new fields
vpc.addFlowLog('FlowLog', {
  logFormat: [
    ec2.LogFormat.SRC_PORT,
    ec2.LogFormat.custom('${new-field}'),
  ],
});
python
vpc = ec2.Vpc(self, "Vpc")

vpc.add_flow_log("FlowLog",
    log_format=[ec2.LogFormat.DST_PORT, ec2.LogFormat.SRC_PORT
    ]
)

# If you just want to add a field to the default field
vpc.add_flow_log("FlowLog",
    log_format=[ec2.LogFormat.VERSION, ec2.LogFormat.ALL_DEFAULT_FIELDS
    ]
)

# If AWS CDK does not support the new fields
vpc.add_flow_log("FlowLog",
    log_format=[ec2.LogFormat.SRC_PORT,
        ec2.LogFormat.custom("${new-field}")
    ]
)
java
Vpc vpc = new Vpc(this, "Vpc");

vpc.addFlowLog("FlowLog", FlowLogOptions.builder()
        .logFormat(List.of(LogFormat.DST_PORT, LogFormat.SRC_PORT))
        .build());

// If you just want to add a field to the default field
vpc.addFlowLog("FlowLog", FlowLogOptions.builder()
        .logFormat(List.of(LogFormat.VERSION, LogFormat.ALL_DEFAULT_FIELDS))
        .build());

// If AWS CDK does not support the new fields
vpc.addFlowLog("FlowLog", FlowLogOptions.builder()
        .logFormat(List.of(LogFormat.SRC_PORT, LogFormat.custom("${new-field}")))
        .build());
csharp
var vpc = new Vpc(this, "Vpc");

vpc.AddFlowLog("FlowLog", new FlowLogOptions {
    LogFormat = new [] { LogFormat.DST_PORT, LogFormat.SRC_PORT }
});

// If you just want to add a field to the default field
vpc.AddFlowLog("FlowLog", new FlowLogOptions {
    LogFormat = new [] { LogFormat.VERSION, LogFormat.ALL_DEFAULT_FIELDS }
});

// If AWS CDK does not support the new fields
vpc.AddFlowLog("FlowLog", new FlowLogOptions {
    LogFormat = new [] { LogFormat.SRC_PORT, LogFormat.Custom("${new-field}") }
});
go
vpc := ec2.NewVpc(this, jsii.String("Vpc"))

vpc.addFlowLog(jsii.String("FlowLog"), &FlowLogOptions{
	LogFormat: []LogFormat{
		ec2.LogFormat_DST_PORT(),
		ec2.LogFormat_SRC_PORT(),
	},
})

// If you just want to add a field to the default field
vpc.addFlowLog(jsii.String("FlowLog"), &FlowLogOptions{
	LogFormat: []LogFormat{
		ec2.LogFormat_VERSION(),
		ec2.LogFormat_ALL_DEFAULT_FIELDS(),
	},
})

// If AWS CDK does not support the new fields
vpc.addFlowLog(jsii.String("FlowLog"), &FlowLogOptions{
	LogFormat: []LogFormat{
		ec2.LogFormat_SRC_PORT(),
		ec2.LogFormat_Custom(jsii.String("${new-field}")),
	},
})

By default, the CDK will create the necessary resources for the destination. For the CloudWatch Logs destination it will create a CloudWatch Logs Log Group as well as the IAM role with the necessary permissions to publish to the log group. In the case of an S3 destination, it will create the S3 bucket.

If you want to customize any of the destination resources you can provide your own as part of the destination.

CloudWatch Logs

ts
declare const vpc: ec2.Vpc;

const logGroup = new logs.LogGroup(this, 'MyCustomLogGroup');

const role = new iam.Role(this, 'MyCustomRole', {
  assumedBy: new iam.ServicePrincipal('vpc-flow-logs.amazonaws.com')
});

new ec2.FlowLog(this, 'FlowLog', {
  resourceType: ec2.FlowLogResourceType.fromVpc(vpc),
  destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup, role)
});
python
# vpc: ec2.Vpc


log_group = logs.LogGroup(self, "MyCustomLogGroup")

role = iam.Role(self, "MyCustomRole",
    assumed_by=iam.ServicePrincipal("vpc-flow-logs.amazonaws.com")
)

ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_cloud_watch_logs(log_group, role)
)
java
Vpc vpc;


LogGroup logGroup = new LogGroup(this, "MyCustomLogGroup");

Role role = Role.Builder.create(this, "MyCustomRole")
        .assumedBy(new ServicePrincipal("vpc-flow-logs.amazonaws.com"))
        .build();

FlowLog.Builder.create(this, "FlowLog")
        .resourceType(FlowLogResourceType.fromVpc(vpc))
        .destination(FlowLogDestination.toCloudWatchLogs(logGroup, role))
        .build();
csharp
Vpc vpc;


var logGroup = new LogGroup(this, "MyCustomLogGroup");

var role = new Role(this, "MyCustomRole", new RoleProps {
    AssumedBy = new ServicePrincipal("vpc-flow-logs.amazonaws.com")
});

new FlowLog(this, "FlowLog", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromVpc(vpc),
    Destination = FlowLogDestination.ToCloudWatchLogs(logGroup, role)
});
go
var vpc Vpc


logGroup := logs.NewLogGroup(this, jsii.String("MyCustomLogGroup"))

role := iam.NewRole(this, jsii.String("MyCustomRole"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("vpc-flow-logs.amazonaws.com")),
})

ec2.NewFlowLog(this, jsii.String("FlowLog"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_FromVpc(vpc),
	Destination: ec2.FlowLogDestination_ToCloudWatchLogs(logGroup, role),
})

S3

ts
declare const vpc: ec2.Vpc;

const bucket = new s3.Bucket(this, 'MyCustomBucket');

new ec2.FlowLog(this, 'FlowLog', {
  resourceType: ec2.FlowLogResourceType.fromVpc(vpc),
  destination: ec2.FlowLogDestination.toS3(bucket)
});

new ec2.FlowLog(this, 'FlowLogWithKeyPrefix', {
  resourceType: ec2.FlowLogResourceType.fromVpc(vpc),
  destination: ec2.FlowLogDestination.toS3(bucket, 'prefix/')
});
python
# vpc: ec2.Vpc


bucket = s3.Bucket(self, "MyCustomBucket")

ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_s3(bucket)
)

ec2.FlowLog(self, "FlowLogWithKeyPrefix",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_s3(bucket, "prefix/")
)
java
Vpc vpc;


Bucket bucket = new Bucket(this, "MyCustomBucket");

FlowLog.Builder.create(this, "FlowLog")
        .resourceType(FlowLogResourceType.fromVpc(vpc))
        .destination(FlowLogDestination.toS3(bucket))
        .build();

FlowLog.Builder.create(this, "FlowLogWithKeyPrefix")
        .resourceType(FlowLogResourceType.fromVpc(vpc))
        .destination(FlowLogDestination.toS3(bucket, "prefix/"))
        .build();
csharp
Vpc vpc;


var bucket = new Bucket(this, "MyCustomBucket");

new FlowLog(this, "FlowLog", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromVpc(vpc),
    Destination = FlowLogDestination.ToS3(bucket)
});

new FlowLog(this, "FlowLogWithKeyPrefix", new FlowLogProps {
    ResourceType = FlowLogResourceType.FromVpc(vpc),
    Destination = FlowLogDestination.ToS3(bucket, "prefix/")
});
go
var vpc Vpc


bucket := s3.NewBucket(this, jsii.String("MyCustomBucket"))

ec2.NewFlowLog(this, jsii.String("FlowLog"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_FromVpc(vpc),
	Destination: ec2.FlowLogDestination_ToS3(bucket),
})

ec2.NewFlowLog(this, jsii.String("FlowLogWithKeyPrefix"), &FlowLogProps{
	ResourceType: ec2.FlowLogResourceType_*FromVpc(vpc),
	Destination: ec2.FlowLogDestination_*ToS3(bucket, jsii.String("prefix/")),
})

Amazon Data Firehose

ts
import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose';

declare const vpc: ec2.Vpc;
declare const deliveryStream: firehose.IDeliveryStream;

vpc.addFlowLog('FlowLogsFirehose', {
  destination: ec2.FlowLogDestination.toFirehose(deliveryStream),
});
python
import aws_cdk.aws_kinesisfirehose as firehose

# vpc: ec2.Vpc
# delivery_stream: firehose.IDeliveryStream


vpc.add_flow_log("FlowLogsFirehose",
    destination=ec2.FlowLogDestination.to_firehose(delivery_stream)
)
java
import software.amazon.awscdk.services.kinesisfirehose.*;

Vpc vpc;
IDeliveryStream deliveryStream;


vpc.addFlowLog("FlowLogsFirehose", FlowLogOptions.builder()
        .destination(FlowLogDestination.toFirehose(deliveryStream))
        .build());
csharp
using Amazon.CDK.AWS.KinesisFirehose;

Vpc vpc;
IDeliveryStream deliveryStream;


vpc.AddFlowLog("FlowLogsFirehose", new FlowLogOptions {
    Destination = FlowLogDestination.ToFirehose(deliveryStream)
});
go
import firehose "github.com/aws/aws-cdk-go/awscdk"

var vpc Vpc
var deliveryStream IDeliveryStream


vpc.addFlowLog(jsii.String("FlowLogsFirehose"), &FlowLogOptions{
	Destination: ec2.FlowLogDestination_ToFirehose(deliveryStream),
})

When the S3 destination is configured, AWS will automatically create an S3 bucket policy that allows the service to write logs to the bucket. This makes it impossible to later update that bucket policy. To have CDK create the bucket policy so that future updates can be made, the @aws-cdk/aws-s3:createDefaultLoggingPolicy feature flag can be used. This can be set in the cdk.json file.

json
{
  "context": {
    "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true
  }
}

User Data ​

User data enables you to run a script when your instances start up. In order to configure these scripts you can add commands directly to the script or you can use the UserData's convenience functions to aid in the creation of your script.

A user data could be configured to run a script found in an asset through the following:

ts
import { Asset } from 'aws-cdk-lib/aws-s3-assets';

declare const instance: ec2.Instance;

const asset = new Asset(this, 'Asset', {
  path: './configure.sh'
});

const localPath = instance.userData.addS3DownloadCommand({
  bucket:asset.bucket,
  bucketKey:asset.s3ObjectKey,
  region: 'us-east-1', // Optional
});
instance.userData.addExecuteFileCommand({
  filePath:localPath,
  arguments: '--verbose -y'
});
asset.grantRead(instance.role);
python
from aws_cdk.aws_s3_assets import Asset

# instance: ec2.Instance


asset = Asset(self, "Asset",
    path="./configure.sh"
)

local_path = instance.user_data.add_s3_download_command(
    bucket=asset.bucket,
    bucket_key=asset.s3_object_key,
    region="us-east-1"
)
instance.user_data.add_execute_file_command(
    file_path=local_path,
    arguments="--verbose -y"
)
asset.grant_read(instance.role)
java
import software.amazon.awscdk.services.s3.assets.Asset;

Instance instance;


Asset asset = Asset.Builder.create(this, "Asset")
        .path("./configure.sh")
        .build();

String localPath = instance.userData.addS3DownloadCommand(S3DownloadOptions.builder()
        .bucket(asset.getBucket())
        .bucketKey(asset.getS3ObjectKey())
        .region("us-east-1")
        .build());
instance.userData.addExecuteFileCommand(ExecuteFileOptions.builder()
        .filePath(localPath)
        .arguments("--verbose -y")
        .build());
asset.grantRead(instance.getRole());
csharp
using Amazon.CDK.AWS.S3.Assets;

Instance instance;


var asset = new Asset(this, "Asset", new AssetProps {
    Path = "./configure.sh"
});

var localPath = instance.UserData.AddS3DownloadCommand(new S3DownloadOptions {
    Bucket = asset.Bucket,
    BucketKey = asset.S3ObjectKey,
    Region = "us-east-1"
});
instance.UserData.AddExecuteFileCommand(new ExecuteFileOptions {
    FilePath = localPath,
    Arguments = "--verbose -y"
});
asset.GrantRead(instance.Role);
go
import "github.com/aws/aws-cdk-go/awscdk"

var instance Instance


asset := awscdk.NewAsset(this, jsii.String("Asset"), &AssetProps{
	Path: jsii.String("./configure.sh"),
})

localPath := instance.UserData.AddS3DownloadCommand(&S3DownloadOptions{
	Bucket: asset.Bucket,
	BucketKey: asset.S3ObjectKey,
	Region: jsii.String("us-east-1"),
})
instance.UserData.AddExecuteFileCommand(&ExecuteFileOptions{
	FilePath: localPath,
	Arguments: jsii.String("--verbose -y"),
})
asset.GrantRead(instance.Role)

Persisting user data ​

By default, EC2 UserData is run once on only the first time that an instance is started. It is possible to make the user data script run on every start of the instance.

When creating a Windows UserData you can use the persist option to set whether or not to add <persist>true</persist> to the user data script. it can be used as follows:

ts
const windowsUserData = ec2.UserData.forWindows({ persist: true });
python
windows_user_data = ec2.UserData.for_windows(persist=True)
java
UserData windowsUserData = UserData.forWindows(WindowsUserDataOptions.builder().persist(true).build());
csharp
var windowsUserData = UserData.ForWindows(new WindowsUserDataOptions { Persist = true });
go
windowsUserData := ec2.UserData_ForWindows(&WindowsUserDataOptions{
	Persist: jsii.Boolean(true),
})

For a Linux instance, this can be accomplished by using a Multipart user data to configure cloud-config as detailed in: https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/

Multipart user data ​

In addition, to above the MultipartUserData can be used to change instance startup behavior. Multipart user data are composed from separate parts forming archive. The most common parts are scripts executed during instance set-up. However, there are other kinds, too.

The advantage of multipart archive is in flexibility when it's needed to add additional parts or to use specialized parts to fine tune instance startup. Some services (like AWS Batch) support only MultipartUserData.

The parts can be executed at different moment of instance start-up and can serve a different purpose. This is controlled by contentType property. For common scripts, text/x-shellscript; charset="utf-8" can be used as content type.

In order to create archive the MultipartUserData has to be instantiated. Than, user can add parts to multipart archive using addPart. The MultipartBody contains methods supporting creation of body parts.

If the very custom part is required, it can be created using MultipartUserData.fromRawBody, in this case full control over content type, transfer encoding, and body properties is given to the user.

Below is an example for creating multipart user data with single body part responsible for installing awscli and configuring maximum size of storage used by Docker containers:

ts
const bootHookConf = ec2.UserData.forLinux();
bootHookConf.addCommands('cloud-init-per once docker_options echo \'OPTIONS="${OPTIONS} --storage-opt dm.basesize=40G"\' >> /etc/sysconfig/docker');

const setupCommands = ec2.UserData.forLinux();
setupCommands.addCommands('sudo yum install awscli && echo Packages installed らと > /var/tmp/setup');

const multipartUserData = new ec2.MultipartUserData();
// The docker has to be configured at early stage, so content type is overridden to boothook
multipartUserData.addPart(ec2.MultipartBody.fromUserData(bootHookConf, 'text/cloud-boothook; charset="us-ascii"'));
// Execute the rest of setup
multipartUserData.addPart(ec2.MultipartBody.fromUserData(setupCommands));

new ec2.LaunchTemplate(this, '', {
  userData: multipartUserData,
  blockDevices: [
    // Block device configuration rest
  ]
});
python
boot_hook_conf = ec2.UserData.for_linux()
boot_hook_conf.add_commands("cloud-init-per once docker_options echo 'OPTIONS=\"${OPTIONS} --storage-opt dm.basesize=40G\"' >> /etc/sysconfig/docker")

setup_commands = ec2.UserData.for_linux()
setup_commands.add_commands("sudo yum install awscli && echo Packages installed らと > /var/tmp/setup")

multipart_user_data = ec2.MultipartUserData()
# The docker has to be configured at early stage, so content type is overridden to boothook
multipart_user_data.add_part(ec2.MultipartBody.from_user_data(boot_hook_conf, "text/cloud-boothook; charset=\"us-ascii\""))
# Execute the rest of setup
multipart_user_data.add_part(ec2.MultipartBody.from_user_data(setup_commands))

ec2.LaunchTemplate(self, "",
    user_data=multipart_user_data,
    block_devices=[]
)
java
UserData bootHookConf = UserData.forLinux();
bootHookConf.addCommands("cloud-init-per once docker_options echo 'OPTIONS=\"${OPTIONS} --storage-opt dm.basesize=40G\"' >> /etc/sysconfig/docker");

UserData setupCommands = UserData.forLinux();
setupCommands.addCommands("sudo yum install awscli && echo Packages installed らと > /var/tmp/setup");

MultipartUserData multipartUserData = new MultipartUserData();
// The docker has to be configured at early stage, so content type is overridden to boothook
multipartUserData.addPart(MultipartBody.fromUserData(bootHookConf, "text/cloud-boothook; charset=\"us-ascii\""));
// Execute the rest of setup
multipartUserData.addPart(MultipartBody.fromUserData(setupCommands));

LaunchTemplate.Builder.create(this, "")
        .userData(multipartUserData)
        .blockDevices(List.of())
        .build();
csharp
var bootHookConf = UserData.ForLinux();
bootHookConf.AddCommands("cloud-init-per once docker_options echo 'OPTIONS=\"${OPTIONS} --storage-opt dm.basesize=40G\"' >> /etc/sysconfig/docker");

var setupCommands = UserData.ForLinux();
setupCommands.AddCommands("sudo yum install awscli && echo Packages installed らと > /var/tmp/setup");

var multipartUserData = new MultipartUserData();
// The docker has to be configured at early stage, so content type is overridden to boothook
multipartUserData.AddPart(MultipartBody.FromUserData(bootHookConf, "text/cloud-boothook; charset=\"us-ascii\""));
// Execute the rest of setup
multipartUserData.AddPart(MultipartBody.FromUserData(setupCommands));

new LaunchTemplate(this, "", new LaunchTemplateProps {
    UserData = multipartUserData,
    BlockDevices = new [] {  }
});
go
bootHookConf := ec2.UserData_ForLinux()
bootHookConf.AddCommands(jsii.String("cloud-init-per once docker_options echo 'OPTIONS=\"${OPTIONS} --storage-opt dm.basesize=40G\"' >> /etc/sysconfig/docker"))

setupCommands := ec2.UserData_ForLinux()
setupCommands.AddCommands(jsii.String("sudo yum install awscli && echo Packages installed らと > /var/tmp/setup"))

multipartUserData := ec2.NewMultipartUserData()
// The docker has to be configured at early stage, so content type is overridden to boothook
multipartUserData.AddPart(ec2.MultipartBody_FromUserData(bootHookConf, jsii.String("text/cloud-boothook; charset=\"us-ascii\"")))
// Execute the rest of setup
multipartUserData.AddPart(ec2.MultipartBody_FromUserData(setupCommands))

ec2.NewLaunchTemplate(this, jsii.String(""), &LaunchTemplateProps{
	UserData: multipartUserData,
	BlockDevices: []BlockDevice{
	},
})

For more information see Specifying Multiple User Data Blocks Using a MIME Multi Part Archive

Using add*Command on MultipartUserData ​

To use the add*Command methods, that are inherited from the UserData interface, on MultipartUserData you must add a part to the MultipartUserData and designate it as the receiver for these methods. This is accomplished by using the addUserDataPart() method on MultipartUserData with the makeDefault argument set to true:

ts
const multipartUserData = new ec2.MultipartUserData();
const commandsUserData = ec2.UserData.forLinux();
multipartUserData.addUserDataPart(commandsUserData, ec2.MultipartBody.SHELL_SCRIPT, true);

// Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa.
multipartUserData.addCommands('touch /root/multi.txt');
commandsUserData.addCommands('touch /root/userdata.txt');
python
multipart_user_data = ec2.MultipartUserData()
commands_user_data = ec2.UserData.for_linux()
multipart_user_data.add_user_data_part(commands_user_data, ec2.MultipartBody.SHELL_SCRIPT, True)

# Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa.
multipart_user_data.add_commands("touch /root/multi.txt")
commands_user_data.add_commands("touch /root/userdata.txt")
java
MultipartUserData multipartUserData = new MultipartUserData();
UserData commandsUserData = UserData.forLinux();
multipartUserData.addUserDataPart(commandsUserData, MultipartBody.SHELL_SCRIPT, true);

// Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa.
multipartUserData.addCommands("touch /root/multi.txt");
commandsUserData.addCommands("touch /root/userdata.txt");
csharp
var multipartUserData = new MultipartUserData();
var commandsUserData = UserData.ForLinux();
multipartUserData.AddUserDataPart(commandsUserData, MultipartBody.SHELL_SCRIPT, true);

// Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa.
multipartUserData.AddCommands("touch /root/multi.txt");
commandsUserData.AddCommands("touch /root/userdata.txt");
go
multipartUserData := ec2.NewMultipartUserData()
commandsUserData := ec2.UserData_ForLinux()
multipartUserData.AddUserDataPart(commandsUserData, ec2.MultipartBody_SHELL_SCRIPT(), jsii.Boolean(true))

// Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa.
multipartUserData.AddCommands(jsii.String("touch /root/multi.txt"))
commandsUserData.AddCommands(jsii.String("touch /root/userdata.txt"))

When used on an EC2 instance, the above multipartUserData will create both multi.txt and userdata.txt in /root.

Importing existing subnet ​

To import an existing Subnet, call Subnet.fromSubnetAttributes() or Subnet.fromSubnetId(). Only if you supply the subnet's Availability Zone and Route Table Ids when calling Subnet.fromSubnetAttributes() will you be able to use the CDK features that use these values (such as selecting one subnet per AZ).

Importing an existing subnet looks like this:

ts
// Supply all properties
const subnet1 = ec2.Subnet.fromSubnetAttributes(this, 'SubnetFromAttributes', {
  subnetId: 's-1234',
  availabilityZone: 'pub-az-4465',
  routeTableId: 'rt-145'
});

// Supply only subnet id
const subnet2 = ec2.Subnet.fromSubnetId(this, 'SubnetFromId', 's-1234');
python
# Supply all properties
subnet1 = ec2.Subnet.from_subnet_attributes(self, "SubnetFromAttributes",
    subnet_id="s-1234",
    availability_zone="pub-az-4465",
    route_table_id="rt-145"
)

# Supply only subnet id
subnet2 = ec2.Subnet.from_subnet_id(self, "SubnetFromId", "s-1234")
java
// Supply all properties
ISubnet subnet1 = Subnet.fromSubnetAttributes(this, "SubnetFromAttributes", SubnetAttributes.builder()
        .subnetId("s-1234")
        .availabilityZone("pub-az-4465")
        .routeTableId("rt-145")
        .build());

// Supply only subnet id
ISubnet subnet2 = Subnet.fromSubnetId(this, "SubnetFromId", "s-1234");
csharp
// Supply all properties
var subnet1 = Subnet.FromSubnetAttributes(this, "SubnetFromAttributes", new SubnetAttributes {
    SubnetId = "s-1234",
    AvailabilityZone = "pub-az-4465",
    RouteTableId = "rt-145"
});

// Supply only subnet id
var subnet2 = Subnet.FromSubnetId(this, "SubnetFromId", "s-1234");
go
// Supply all properties
subnet1 := ec2.Subnet_FromSubnetAttributes(this, jsii.String("SubnetFromAttributes"), &SubnetAttributes{
	SubnetId: jsii.String("s-1234"),
	AvailabilityZone: jsii.String("pub-az-4465"),
	RouteTableId: jsii.String("rt-145"),
})

// Supply only subnet id
subnet2 := ec2.Subnet_FromSubnetId(this, jsii.String("SubnetFromId"), jsii.String("s-1234"))

Launch Templates ​

A Launch Template is a standardized template that contains the configuration information to launch an instance. They can be used when launching instances on their own, through Amazon EC2 Auto Scaling, EC2 Fleet, and Spot Fleet. Launch templates enable you to store launch parameters so that you do not have to specify them every time you launch an instance. For information on Launch Templates please see the official documentation.

The following demonstrates how to create a launch template with an Amazon Machine Image, security group, and an instance profile.

ts
declare const vpc: ec2.Vpc;

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
});
const instanceProfile = new iam.InstanceProfile(this, 'InstanceProfile', {
  role,
});

const template = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  launchTemplateName: 'MyTemplateV1',
  versionDescription: 'This is my v1 template',
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  securityGroup: new ec2.SecurityGroup(this, 'LaunchTemplateSG', {
    vpc: vpc,
  }),
  instanceProfile,
});
python
# vpc: ec2.Vpc


role = iam.Role(self, "Role",
    assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")
)
instance_profile = iam.InstanceProfile(self, "InstanceProfile",
    role=role
)

template = ec2.LaunchTemplate(self, "LaunchTemplate",
    launch_template_name="MyTemplateV1",
    version_description="This is my v1 template",
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    security_group=ec2.SecurityGroup(self, "LaunchTemplateSG",
        vpc=vpc
    ),
    instance_profile=instance_profile
)
java
Vpc vpc;


Role role = Role.Builder.create(this, "Role")
        .assumedBy(new ServicePrincipal("ec2.amazonaws.com"))
        .build();
InstanceProfile instanceProfile = InstanceProfile.Builder.create(this, "InstanceProfile")
        .role(role)
        .build();

LaunchTemplate template = LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .launchTemplateName("MyTemplateV1")
        .versionDescription("This is my v1 template")
        .machineImage(MachineImage.latestAmazonLinux2023())
        .securityGroup(SecurityGroup.Builder.create(this, "LaunchTemplateSG")
                .vpc(vpc)
                .build())
        .instanceProfile(instanceProfile)
        .build();
csharp
Vpc vpc;


var role = new Role(this, "Role", new RoleProps {
    AssumedBy = new ServicePrincipal("ec2.amazonaws.com")
});
var instanceProfile = new InstanceProfile(this, "InstanceProfile", new InstanceProfileProps {
    Role = role
});

var template = new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    LaunchTemplateName = "MyTemplateV1",
    VersionDescription = "This is my v1 template",
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    SecurityGroup = new SecurityGroup(this, "LaunchTemplateSG", new SecurityGroupProps {
        Vpc = vpc
    }),
    InstanceProfile = instanceProfile
});
go
var vpc Vpc


role := iam.NewRole(this, jsii.String("Role"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("ec2.amazonaws.com")),
})
instanceProfile := iam.NewInstanceProfile(this, jsii.String("InstanceProfile"), &InstanceProfileProps{
	Role: Role,
})

template := ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	LaunchTemplateName: jsii.String("MyTemplateV1"),
	VersionDescription: jsii.String("This is my v1 template"),
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	SecurityGroup: ec2.NewSecurityGroup(this, jsii.String("LaunchTemplateSG"), &SecurityGroupProps{
		Vpc: vpc,
	}),
	InstanceProfile: InstanceProfile,
})

And the following demonstrates how to enable metadata options support.

ts
new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  httpEndpoint: true,
  httpProtocolIpv6: true,
  httpPutResponseHopLimit: 1,
  httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED,
  instanceMetadataTags: true,
});
python
ec2.LaunchTemplate(self, "LaunchTemplate",
    http_endpoint=True,
    http_protocol_ipv6=True,
    http_put_response_hop_limit=1,
    http_tokens=ec2.LaunchTemplateHttpTokens.REQUIRED,
    instance_metadata_tags=True
)
java
LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .httpEndpoint(true)
        .httpProtocolIpv6(true)
        .httpPutResponseHopLimit(1)
        .httpTokens(LaunchTemplateHttpTokens.REQUIRED)
        .instanceMetadataTags(true)
        .build();
csharp
new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    HttpEndpoint = true,
    HttpProtocolIpv6 = true,
    HttpPutResponseHopLimit = 1,
    HttpTokens = LaunchTemplateHttpTokens.REQUIRED,
    InstanceMetadataTags = true
});
go
ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	HttpEndpoint: jsii.Boolean(true),
	HttpProtocolIpv6: jsii.Boolean(true),
	HttpPutResponseHopLimit: jsii.Number(1),
	HttpTokens: ec2.LaunchTemplateHttpTokens_REQUIRED,
	InstanceMetadataTags: jsii.Boolean(true),
})

And the following demonstrates how to add one or more security groups to launch template.

ts
declare const vpc: ec2.Vpc;

const sg1 = new ec2.SecurityGroup(this, 'sg1', {
  vpc: vpc,
});
const sg2 = new ec2.SecurityGroup(this, 'sg2', {
  vpc: vpc,
});

const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  securityGroup: sg1,
});

launchTemplate.addSecurityGroup(sg2);
python
# vpc: ec2.Vpc


sg1 = ec2.SecurityGroup(self, "sg1",
    vpc=vpc
)
sg2 = ec2.SecurityGroup(self, "sg2",
    vpc=vpc
)

launch_template = ec2.LaunchTemplate(self, "LaunchTemplate",
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    security_group=sg1
)

launch_template.add_security_group(sg2)
java
Vpc vpc;


SecurityGroup sg1 = SecurityGroup.Builder.create(this, "sg1")
        .vpc(vpc)
        .build();
SecurityGroup sg2 = SecurityGroup.Builder.create(this, "sg2")
        .vpc(vpc)
        .build();

LaunchTemplate launchTemplate = LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .machineImage(MachineImage.latestAmazonLinux2023())
        .securityGroup(sg1)
        .build();

launchTemplate.addSecurityGroup(sg2);
csharp
Vpc vpc;


var sg1 = new SecurityGroup(this, "sg1", new SecurityGroupProps {
    Vpc = vpc
});
var sg2 = new SecurityGroup(this, "sg2", new SecurityGroupProps {
    Vpc = vpc
});

var launchTemplate = new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    SecurityGroup = sg1
});

launchTemplate.AddSecurityGroup(sg2);
go
var vpc Vpc


sg1 := ec2.NewSecurityGroup(this, jsii.String("sg1"), &SecurityGroupProps{
	Vpc: vpc,
})
sg2 := ec2.NewSecurityGroup(this, jsii.String("sg2"), &SecurityGroupProps{
	Vpc: vpc,
})

launchTemplate := ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	SecurityGroup: sg1,
})

launchTemplate.AddSecurityGroup(sg2)

To use AWS Systems Manager parameters instead of AMI IDs in launch templates and resolve the AMI IDs at instance launch time:

ts
const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  machineImage: ec2.MachineImage.resolveSsmParameterAtLaunch('parameterName'),
});
python
launch_template = ec2.LaunchTemplate(self, "LaunchTemplate",
    machine_image=ec2.MachineImage.resolve_ssm_parameter_at_launch("parameterName")
)
java
LaunchTemplate launchTemplate = LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .machineImage(MachineImage.resolveSsmParameterAtLaunch("parameterName"))
        .build();
csharp
var launchTemplate = new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    MachineImage = MachineImage.ResolveSsmParameterAtLaunch("parameterName")
});
go
launchTemplate := ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	MachineImage: ec2.MachineImage_ResolveSsmParameterAtLaunch(jsii.String("parameterName")),
})

To specify the EBS Provisioned Rate for Volume Initialization for a snapshot-backed EBS volume in a launch template, use the volumeInitializationRate property. The snapshot can be specified explicitly with BlockDeviceVolume.ebsFromSnapshot(...) or inherited from the AMI block device mapping when overriding an existing AMI device such as the root volume.

ts
const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  blockDevices: [
    {
      deviceName: 'deviceName',
      volume: ec2.BlockDeviceVolume.ebsFromSnapshot('snap-1234567890abcdef0', {
        volumeSize: 150,
        volumeInitializationRate: Size.mebibytes(200),
      }),
    },
  ],
});
python
launch_template = ec2.LaunchTemplate(self, "LaunchTemplate",
    block_devices=[ec2.BlockDevice(
        device_name="deviceName",
        volume=ec2.BlockDeviceVolume.ebs_from_snapshot("snap-1234567890abcdef0",
            volume_size=150,
            volume_initialization_rate=Size.mebibytes(200)
        )
    )
    ]
)
java
LaunchTemplate launchTemplate = LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .blockDevices(List.of(BlockDevice.builder()
                .deviceName("deviceName")
                .volume(BlockDeviceVolume.ebsFromSnapshot("snap-1234567890abcdef0", EbsDeviceSnapshotOptions.builder()
                        .volumeSize(150)
                        .volumeInitializationRate(Size.mebibytes(200))
                        .build()))
                .build()))
        .build();
csharp
var launchTemplate = new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    BlockDevices = new [] { new BlockDevice {
        DeviceName = "deviceName",
        Volume = BlockDeviceVolume.EbsFromSnapshot("snap-1234567890abcdef0", new EbsDeviceSnapshotOptions {
            VolumeSize = 150,
            VolumeInitializationRate = Size.Mebibytes(200)
        })
    } }
});
go
launchTemplate := ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("deviceName"),
			Volume: ec2.BlockDeviceVolume_EbsFromSnapshot(jsii.String("snap-1234567890abcdef0"), &EbsDeviceSnapshotOptions{
				VolumeSize: jsii.Number(150),
				VolumeInitializationRate: awscdk.Size_Mebibytes(jsii.Number(200)),
			}),
		},
	},
})

CPU Options ​

Specify cpuOptions to configure the CPU options for the instances launched with the template. This is useful, for example, to enable nested virtualization or to customize the number of CPU cores and threads per core:

ts
new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  cpuOptions: {
    coreCount: 4,
    threadsPerCore: 1,
    nestedVirtualization: true,
  },
});
python
ec2.LaunchTemplate(self, "LaunchTemplate",
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    cpu_options=ec2.LaunchTemplateCpuOptions(
        core_count=4,
        threads_per_core=1,
        nested_virtualization=True
    )
)
java
LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .machineImage(MachineImage.latestAmazonLinux2023())
        .cpuOptions(LaunchTemplateCpuOptions.builder()
                .coreCount(4)
                .threadsPerCore(1)
                .nestedVirtualization(true)
                .build())
        .build();
csharp
new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    CpuOptions = new LaunchTemplateCpuOptions {
        CoreCount = 4,
        ThreadsPerCore = 1,
        NestedVirtualization = true
    }
});
go
ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	CpuOptions: &LaunchTemplateCpuOptions{
		CoreCount: jsii.Number(4),
		ThreadsPerCore: jsii.Number(1),
		NestedVirtualization: jsii.Boolean(true),
	},
})

Placement Group ​

Specify placementGroup to enable the placement group support:

ts
declare const instanceType: ec2.InstanceType;

const pg = new ec2.PlacementGroup(this, 'test-pg', {
  strategy: ec2.PlacementGroupStrategy.SPREAD,
});

new ec2.LaunchTemplate(this, 'LaunchTemplate', {
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  placementGroup: pg,
});
python
# instance_type: ec2.InstanceType


pg = ec2.PlacementGroup(self, "test-pg",
    strategy=ec2.PlacementGroupStrategy.SPREAD
)

ec2.LaunchTemplate(self, "LaunchTemplate",
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    placement_group=pg
)
java
InstanceType instanceType;


PlacementGroup pg = PlacementGroup.Builder.create(this, "test-pg")
        .strategy(PlacementGroupStrategy.SPREAD)
        .build();

LaunchTemplate.Builder.create(this, "LaunchTemplate")
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        .placementGroup(pg)
        .build();
csharp
InstanceType instanceType;


var pg = new PlacementGroup(this, "test-pg", new PlacementGroupProps {
    Strategy = PlacementGroupStrategy.SPREAD
});

new LaunchTemplate(this, "LaunchTemplate", new LaunchTemplateProps {
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    PlacementGroup = pg
});
go
var instanceType InstanceType


pg := ec2.NewPlacementGroup(this, jsii.String("test-pg"), &PlacementGroupProps{
	Strategy: ec2.PlacementGroupStrategy_SPREAD,
})

ec2.NewLaunchTemplate(this, jsii.String("LaunchTemplate"), &LaunchTemplateProps{
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	PlacementGroup: pg,
})

Please note this feature does not support Launch Configurations.

Detailed Monitoring ​

The following demonstrates how to enable Detailed Monitoring for an EC2 instance. Keep in mind that Detailed Monitoring results in additional charges.

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;

new ec2.Instance(this, 'Instance1', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  detailedMonitoring: true,
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType


ec2.Instance(self, "Instance1",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    detailed_monitoring=True
)
java
Vpc vpc;
InstanceType instanceType;


Instance.Builder.create(this, "Instance1")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        .detailedMonitoring(true)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;


new Instance(this, "Instance1", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    DetailedMonitoring = true
});
go
var vpc Vpc
var instanceType InstanceType


ec2.NewInstance(this, jsii.String("Instance1"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	DetailedMonitoring: jsii.Boolean(true),
})

Connecting to your instances using SSM Session Manager ​

SSM Session Manager makes it possible to connect to your instances from the AWS Console, without preparing SSH keys.

To do so, you need to:

If these conditions are met, you can connect to the instance from the EC2 Console. Example:

ts
declare const vpc: ec2.Vpc;
declare const instanceType: ec2.InstanceType;

new ec2.Instance(this, 'Instance1', {
  vpc,
  instanceType,

  // Amazon Linux 2023 comes with SSM Agent by default
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),

  // Turn on SSM
  ssmSessionPermissions: true,
});
python
# vpc: ec2.Vpc
# instance_type: ec2.InstanceType


ec2.Instance(self, "Instance1",
    vpc=vpc,
    instance_type=instance_type,

    # Amazon Linux 2023 comes with SSM Agent by default
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),

    # Turn on SSM
    ssm_session_permissions=True
)
java
Vpc vpc;
InstanceType instanceType;


Instance.Builder.create(this, "Instance1")
        .vpc(vpc)
        .instanceType(instanceType)

        // Amazon Linux 2023 comes with SSM Agent by default
        .machineImage(MachineImage.latestAmazonLinux2023())

        // Turn on SSM
        .ssmSessionPermissions(true)
        .build();
csharp
Vpc vpc;
InstanceType instanceType;


new Instance(this, "Instance1", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,

    // Amazon Linux 2023 comes with SSM Agent by default
    MachineImage = MachineImage.LatestAmazonLinux2023(),

    // Turn on SSM
    SsmSessionPermissions = true
});
go
var vpc Vpc
var instanceType InstanceType


ec2.NewInstance(this, jsii.String("Instance1"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,

	// Amazon Linux 2023 comes with SSM Agent by default
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),

	// Turn on SSM
	SsmSessionPermissions: jsii.Boolean(true),
})

Managed Prefix Lists ​

Create and manage customer-managed prefix lists. If you don't specify anything in this construct, it will manage IPv4 addresses.

You can also create an empty Prefix List with only the maximum number of entries specified, as shown in the following code. If nothing is specified, maxEntries=1.

ts
new ec2.PrefixList(this, 'EmptyPrefixList', {
  maxEntries: 100,
});
python
ec2.PrefixList(self, "EmptyPrefixList",
    max_entries=100
)
java
PrefixList.Builder.create(this, "EmptyPrefixList")
        .maxEntries(100)
        .build();
csharp
new PrefixList(this, "EmptyPrefixList", new PrefixListProps {
    MaxEntries = 100
});
go
ec2.NewPrefixList(this, jsii.String("EmptyPrefixList"), &PrefixListProps{
	MaxEntries: jsii.Number(100),
})

maxEntries can also be omitted as follows. In this case maxEntries: 2, will be set.

ts
new ec2.PrefixList(this, 'PrefixList', {
  entries: [
    { cidr: '10.0.0.1/32' },
    { cidr: '10.0.0.2/32', description: 'sample1' },
  ],
});
python
ec2.PrefixList(self, "PrefixList",
    entries=[ec2.CfnPrefixList.EntryProperty(cidr="10.0.0.1/32"), ec2.CfnPrefixList.EntryProperty(cidr="10.0.0.2/32", description="sample1")
    ]
)
java
PrefixList.Builder.create(this, "PrefixList")
        .entries(List.of(EntryProperty.builder().cidr("10.0.0.1/32").build(), EntryProperty.builder().cidr("10.0.0.2/32").description("sample1").build()))
        .build();
csharp
new PrefixList(this, "PrefixList", new PrefixListProps {
    Entries = new [] { new EntryProperty { Cidr = "10.0.0.1/32" }, new EntryProperty { Cidr = "10.0.0.2/32", Description = "sample1" } }
});
go
ec2.NewPrefixList(this, jsii.String("PrefixList"), &PrefixListProps{
	Entries: []EntryProperty{
		&EntryProperty{
			Cidr: jsii.String("10.0.0.1/32"),
		},
		&EntryProperty{
			Cidr: jsii.String("10.0.0.2/32"),
			Description: jsii.String("sample1"),
		},
	},
})

To import AWS-managed prefix list, you can use PrefixList.fromLookup().

ts
ec2.PrefixList.fromLookup(this, 'PrefixListFromName', {
  prefixListName: 'com.amazonaws.global.cloudfront.origin-facing',
});
python
ec2.PrefixList.from_lookup(self, "PrefixListFromName",
    prefix_list_name="com.amazonaws.global.cloudfront.origin-facing"
)
java
PrefixList.fromLookup(this, "PrefixListFromName", PrefixListLookupOptions.builder()
        .prefixListName("com.amazonaws.global.cloudfront.origin-facing")
        .build());
csharp
PrefixList.FromLookup(this, "PrefixListFromName", new PrefixListLookupOptions {
    PrefixListName = "com.amazonaws.global.cloudfront.origin-facing"
});
go
ec2.PrefixList_FromLookup(this, jsii.String("PrefixListFromName"), &PrefixListLookupOptions{
	PrefixListName: jsii.String("com.amazonaws.global.cloudfront.origin-facing"),
})

For more information see Work with customer-managed prefix lists.

IAM instance profile ​

Use instanceProfile to apply specific IAM Instance Profile. Cannot be used with role

ts
declare const instanceType: ec2.InstanceType;
declare const vpc: ec2.Vpc;

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
});
const instanceProfile = new iam.InstanceProfile(this, 'InstanceProfile', {
  role,
});

new ec2.Instance(this, 'Instance', {
  vpc,
  instanceType,
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  instanceProfile,
});
python
# instance_type: ec2.InstanceType
# vpc: ec2.Vpc


role = iam.Role(self, "Role",
    assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")
)
instance_profile = iam.InstanceProfile(self, "InstanceProfile",
    role=role
)

ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=instance_type,
    machine_image=ec2.MachineImage.latest_amazon_linux2023(),
    instance_profile=instance_profile
)
java
InstanceType instanceType;
Vpc vpc;


Role role = Role.Builder.create(this, "Role")
        .assumedBy(new ServicePrincipal("ec2.amazonaws.com"))
        .build();
InstanceProfile instanceProfile = InstanceProfile.Builder.create(this, "InstanceProfile")
        .role(role)
        .build();

Instance.Builder.create(this, "Instance")
        .vpc(vpc)
        .instanceType(instanceType)
        .machineImage(MachineImage.latestAmazonLinux2023())
        .instanceProfile(instanceProfile)
        .build();
csharp
InstanceType instanceType;
Vpc vpc;


var role = new Role(this, "Role", new RoleProps {
    AssumedBy = new ServicePrincipal("ec2.amazonaws.com")
});
var instanceProfile = new InstanceProfile(this, "InstanceProfile", new InstanceProfileProps {
    Role = role
});

new Instance(this, "Instance", new InstanceProps {
    Vpc = vpc,
    InstanceType = instanceType,
    MachineImage = MachineImage.LatestAmazonLinux2023(),
    InstanceProfile = instanceProfile
});
go
var instanceType InstanceType
var vpc Vpc


role := iam.NewRole(this, jsii.String("Role"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("ec2.amazonaws.com")),
})
instanceProfile := iam.NewInstanceProfile(this, jsii.String("InstanceProfile"), &InstanceProfileProps{
	Role: Role,
})

ec2.NewInstance(this, jsii.String("Instance"), &InstanceProps{
	Vpc: Vpc,
	InstanceType: InstanceType,
	MachineImage: ec2.MachineImage_LatestAmazonLinux2023(),
	InstanceProfile: InstanceProfile,
})

Types ​

NameKindSummary
BastionHostLinuxConstruct (L2)This creates a linux bastion host you can use to connect to other instances or services in your VPC.
ClientVpnAuthorizationRuleConstruct (L2)A client VPN authorization rule.
ClientVpnEndpointConstruct (L2)A client VPN connection.
ClientVpnRouteConstruct (L2)A client VPN route.
FlowLogConstruct (L2)A VPC flow log.
GatewayVpcEndpointConstruct (L2)A gateway VPC endpoint.
InstanceConstruct (L2)This represents a single EC2 instance.
InterfaceVpcEndpointConstruct (L2)A interface VPC endpoint.
KeyPairConstruct (L2)An EC2 Key Pair.
LaunchTemplateConstruct (L2)This represents an EC2 LaunchTemplate.
NetworkAclConstruct (L2)Define a new custom network ACL.
NetworkAclEntryConstruct (L2)Define an entry in a Network ACL table.
PlacementGroupConstruct (L2)Defines a placement group.
PrefixListConstruct (L2)A managed prefix list.
PrivateSubnetConstruct (L2)Represents a private VPC subnet resource.
PublicSubnetConstruct (L2)Represents a public VPC subnet resource.
SecurityGroupConstruct (L2)Creates an Amazon EC2 security group within a VPC.
SubnetConstruct (L2)Represents a new VPC subnet resource.
SubnetNetworkAclAssociationConstruct (L2)
VolumeConstruct (L2)Creates a new EBS Volume in AWS EC2.
VpcConstruct (L2)Define an AWS Virtual Private Cloud.
VpcEndpointConstruct (L2)
VpcEndpointServiceConstruct (L2)A VPC endpoint service.
VpnConnectionConstruct (L2)Define a VPN Connection.
VpnConnectionBaseConstruct (L2)Base class for Vpn connections.
VpnGatewayConstruct (L2)The VPN Gateway that shall be added to the VPC.
CfnApplicationStatusCheckConstruct (L1)An application status check monitors an HTTP or HTTPS endpoint on Amazon EC2 instances and reports application-layer health.
CfnCapacityManagerDataExportConstruct (L1)Creates a new data export configuration for EC2 Capacity Manager.
CfnCapacityReservationConstruct (L1)Creates a new Capacity Reservation with the specified attributes.
CfnCapacityReservationFleetConstruct (L1)Creates a new Capacity Reservation Fleet with the specified attributes.
CfnCarrierGatewayConstruct (L1)Creates a carrier gateway.
CfnClientVpnAuthorizationRuleConstruct (L1)Specifies an ingress authorization rule to add to a Client VPN endpoint.
CfnClientVpnEndpointConstruct (L1)Specifies a Client VPN endpoint.
CfnClientVpnRouteConstruct (L1)Specifies a network route to add to a Client VPN endpoint.
CfnClientVpnTargetNetworkAssociationConstruct (L1)Specifies a target network to associate with a Client VPN endpoint.
CfnCustomerGatewayConstruct (L1)Specifies a customer gateway.
CfnDHCPOptionsConstruct (L1)Specifies a set of DHCP options for your VPC.
CfnEC2FleetConstruct (L1)Specifies the configuration information to launch a fleet--or group--of instances.
CfnEgressOnlyInternetGatewayConstruct (L1)[IPv6 only] Specifies an egress-only internet gateway for your VPC.
CfnEIPConstruct (L1)Specifies an Elastic IP (EIP) address and can, optionally, associate it with an Amazon EC2 instance.
CfnEIPAssociationConstruct (L1)Associates an Elastic IP address with an instance or a network interface.
CfnEnclaveCertificateIamRoleAssociationConstruct (L1)Associates an AWS Identity and Access Management (IAM) role with an Certificate Manager (ACM) certificate.
CfnFlowLogConstruct (L1)Specifies a VPC flow log that captures IP traffic for a specified network interface, subnet, or VPC.
CfnFpgaImageConstruct (L1)Creates and manages an Amazon FPGA Image (AFI) from a design checkpoint (DCP).
CfnGatewayRouteTableAssociationConstruct (L1)Associates a virtual private gateway or internet gateway with a route table.
CfnHostConstruct (L1)Allocates a fully dedicated physical server for launching EC2 instances.
CfnInstanceConstruct (L1)Specifies an EC2 instance.
CfnInstanceConnectEndpointConstruct (L1)Creates an EC2 Instance Connect Endpoint.
CfnInstanceEventWindowConstruct (L1)Resource type definition for AWS::EC2::InstanceEventWindow.
CfnInternetGatewayConstruct (L1)Allocates an internet gateway for use with a VPC.
CfnIPAMConstruct (L1)IPAM is a VPC feature that you can use to automate your IP address management workflows including assigning, tracking, troubleshooting, and auditing IP addresses across AWS Regions and accounts throughout your AWS Organization.
CfnIPAMAllocationConstruct (L1)In IPAM, an allocation is a CIDR assignment from an IPAM pool to another IPAM pool or to a resource.
CfnIpamExternalResourceVerificationTokenConstruct (L1)A verification token is an AWS-generated random value that you can use to prove ownership of an external resource.
CfnIPAMPoolConstruct (L1)In IPAM, a pool is a collection of contiguous IP addresses CIDRs.
CfnIPAMPoolCidrConstruct (L1)A CIDR provisioned to an IPAM pool.
CfnIPAMPrefixListResolverConstruct (L1)Resource Type definition for AWS::EC2::IPAMPrefixListResolver.
CfnIPAMPrefixListResolverTargetConstruct (L1)Resource Type definition for AWS::EC2::IPAMPrefixListResolverTarget.
CfnIPAMResourceDiscoveryConstruct (L1)A resource discovery is an IPAM component that enables IPAM to manage and monitor resources that belong to the owning account.
CfnIPAMResourceDiscoveryAssociationConstruct (L1)An IPAM resource discovery association.
CfnIPAMScopeConstruct (L1)In IPAM, a scope is the highest-level container within IPAM.
CfnIpPoolRouteTableAssociationConstruct (L1)A route server association is the connection established between a route server and a VPC.
CfnIPv4PoolConstruct (L1)Resource Type definition for AWS::EC2::IPv4Pool.
CfnKeyPairConstruct (L1)Specifies a key pair for use with an Amazon Elastic Compute Cloud instance as follows:.
CfnLaunchTemplateConstruct (L1)Specifies the properties for creating a launch template.
CfnLocalGatewayRouteConstruct (L1)Creates a static route for the specified local gateway route table. You must specify one of the following targets:.
CfnLocalGatewayRouteTableConstruct (L1)Describes a local gateway route table.
CfnLocalGatewayRouteTableVirtualInterfaceGroupAssociationConstruct (L1)Describes an association between a local gateway route table and a virtual interface group.
CfnLocalGatewayRouteTableVPCAssociationConstruct (L1)Associates the specified VPC with the specified local gateway route table.
CfnLocalGatewayVirtualInterfaceConstruct (L1)Describes a local gateway virtual interface.
CfnLocalGatewayVirtualInterfaceGroupConstruct (L1)Describes a local gateway virtual interface group.
CfnNatGatewayConstruct (L1)Specifies a network address translation (NAT) gateway in the specified subnet.
CfnNetworkAclConstruct (L1)Specifies a network ACL for your VPC.
CfnNetworkAclEntryConstruct (L1)Specifies an entry, known as a rule, in a network ACL with a rule number you specify.
CfnNetworkInsightsAccessScopeConstruct (L1)Describes a Network Access Scope.
CfnNetworkInsightsAccessScopeAnalysisConstruct (L1)Describes a Network Access Scope analysis.
CfnNetworkInsightsAnalysisConstruct (L1)Specifies a network insights analysis.
CfnNetworkInsightsPathConstruct (L1)Specifies a path to analyze for reachability.
CfnNetworkInterfaceConstruct (L1)Describes a network interface in an Amazon EC2 instance for AWS CloudFormation .
CfnNetworkInterfaceAttachmentConstruct (L1)Attaches an elastic network interface (ENI) to an Amazon EC2 instance.
CfnNetworkInterfacePermissionConstruct (L1)Specifies a permission for the network interface, For example, you can grant an AWS -authorized account permission to attach the network interface to an instance in their account.
CfnNetworkPerformanceMetricSubscriptionConstruct (L1)Describes Infrastructure Performance subscriptions.
CfnPlacementGroupConstruct (L1)Specifies a placement group in which to launch instances.
CfnPrefixListConstruct (L1)Specifies a managed prefix list.
CfnRouteConstruct (L1)Specifies a route in a route table. For more information, see Routes in the Amazon VPC User Guide .
CfnRouteServerConstruct (L1)Specifies a route server to manage dynamic routing in a VPC.
CfnRouteServerAssociationConstruct (L1)Specifies the association between a route server and a VPC.
CfnRouteServerEndpointConstruct (L1)Creates a new endpoint for a route server in a specified subnet.
CfnRouteServerPeerConstruct (L1)Specifies a BGP peer configuration for a route server endpoint.
CfnRouteServerPropagationConstruct (L1)Specifies route propagation from a route server to a route table.
CfnRouteTableConstruct (L1)Specifies a route table for the specified VPC.
CfnSecurityGroupConstruct (L1)Specifies a security group.
CfnSecurityGroupEgressConstruct (L1)Adds the specified outbound (egress) rule to a security group.
CfnSecurityGroupIngressConstruct (L1)Adds an inbound (ingress) rule to a security group.
CfnSecurityGroupVpcAssociationConstruct (L1)A security group association with a VPC.
CfnSnapshotBlockPublicAccessConstruct (L1)Specifies the state of the block public access for snapshots setting for the Region.
CfnSpotFleetConstruct (L1)Specifies a Spot Fleet request.
CfnSqlHaStandbyDetectedInstanceConstruct (L1)Resource Type definition for AWS::EC2::SqlHaStandbyDetectedInstance.
CfnSubnetConstruct (L1)Specifies a subnet for the specified VPC.
CfnSubnetCidrBlockConstruct (L1)Associates a CIDR block with your subnet.
CfnSubnetCidrReservationConstruct (L1)Resource Type definition for a CIDR range reserved inside an Amazon EC2 subnet.
CfnSubnetNetworkAclAssociationConstruct (L1)Associates a subnet with a network ACL. For more information, see ReplaceNetworkAclAssociation in the Amazon EC2 API Reference .
CfnSubnetRouteTableAssociationConstruct (L1)Associates a subnet with a route table.
CfnTrafficMirrorFilterConstruct (L1)Specifies a Traffic Mirror filter.
CfnTrafficMirrorFilterRuleConstruct (L1)Creates a Traffic Mirror filter rule.
CfnTrafficMirrorSessionConstruct (L1)Creates a Traffic Mirror session.
CfnTrafficMirrorTargetConstruct (L1)Specifies a target for your Traffic Mirror session.
CfnTransitGatewayConstruct (L1)Specifies a transit gateway.
CfnTransitGatewayAttachmentConstruct (L1)Attaches a VPC to a transit gateway.
CfnTransitGatewayConnectConstruct (L1)Creates a Connect attachment from a specified transit gateway attachment.
CfnTransitGatewayConnectPeerConstruct (L1)Describes a transit gateway Connect peer.
CfnTransitGatewayMeteringPolicyConstruct (L1)Describes a transit gateway metering policy.
CfnTransitGatewayMeteringPolicyEntryConstruct (L1)Creates an entry in a transit gateway metering policy to define traffic measurement rules.
CfnTransitGatewayMulticastDomainConstruct (L1)Creates a multicast domain using the specified transit gateway.
CfnTransitGatewayMulticastDomainAssociationConstruct (L1)Associates the specified subnets and transit gateway attachments with the specified transit gateway multicast domain.
CfnTransitGatewayMulticastGroupMemberConstruct (L1)Registers members (network interfaces) with the transit gateway multicast group.
CfnTransitGatewayMulticastGroupSourceConstruct (L1)Registers sources (network interfaces) with the specified transit gateway multicast domain.
CfnTransitGatewayPeeringAttachmentConstruct (L1)Requests a transit gateway peering attachment between the specified transit gateway (requester) and a peer transit gateway (accepter).
CfnTransitGatewayPolicyTableConstruct (L1)AWS::EC2::TransitGatewayPolicyTable Resource Definition.
CfnTransitGatewayPolicyTableAssociationConstruct (L1)AWS::EC2::TransitGatewayPolicyTableAssociation Resource Definition.
CfnTransitGatewayPolicyTableEntryConstruct (L1)AWS::EC2::TransitGatewayPolicyTableEntry Resource Definition.
CfnTransitGatewayRouteConstruct (L1)Specifies a static route for a transit gateway route table.
CfnTransitGatewayRouteTableConstruct (L1)Specifies a route table for a transit gateway.
CfnTransitGatewayRouteTableAssociationConstruct (L1)Associates the specified attachment with the specified transit gateway route table.
CfnTransitGatewayRouteTablePropagationConstruct (L1)Enables the specified attachment to propagate routes to the specified propagation route table.
CfnTransitGatewayVpcAttachmentConstruct (L1)Specifies a VPC attachment.
CfnVerifiedAccessEndpointConstruct (L1)An AWS Verified Access endpoint specifies the application that AWS Verified Access provides access to.
CfnVerifiedAccessGroupConstruct (L1)An AWS Verified Access group is a collection of AWS Verified Access endpoints who's associated applications have similar security requirements.
CfnVerifiedAccessInstanceConstruct (L1)An AWS Verified Access instance is a regional entity that evaluates application requests and grants access only when your security requirements are met.
CfnVerifiedAccessTrustProviderConstruct (L1)A trust provider is a third-party entity that creates, maintains, and manages identity information for users and devices.
CfnVolumeConstruct (L1)Specifies an Amazon Elastic Block Store (Amazon EBS) volume.
CfnVolumeAttachmentConstruct (L1)Attaches an Amazon EBS volume to a running instance and exposes it to the instance with the specified device name.
CfnVPCConstruct (L1)Specifies a virtual private cloud (VPC).
CfnVPCBlockPublicAccessExclusionConstruct (L1)Create a VPC Block Public Access (BPA) exclusion.
CfnVPCBlockPublicAccessOptionsConstruct (L1)VPC Block Public Access (BPA) enables you to block resources in VPCs and subnets that you own in a Region from reaching or being reached from the internet through internet gateways and egress-only internet gateways.
CfnVPCCidrBlockConstruct (L1)Associates a CIDR block with your VPC.
CfnVPCDHCPOptionsAssociationConstruct (L1)Associates a set of DHCP options with a VPC, or associates no DHCP options with the VPC.
CfnVPCEncryptionControlConstruct (L1)Describes the configuration and state of VPC encryption controls.
CfnVPCEndpointConstruct (L1)Specifies a VPC endpoint.
CfnVPCEndpointConnectionNotificationConstruct (L1)Specifies a connection notification for a VPC endpoint or VPC endpoint service.
CfnVPCEndpointServiceConstruct (L1)Creates a VPC endpoint service configuration to which service consumers ( AWS accounts, users, and IAM roles) can connect.
CfnVPCEndpointServicePermissionsConstruct (L1)Grant or revoke permissions for service consumers (users, IAM roles, and AWS accounts) to connect to a VPC endpoint service.
CfnVPCGatewayAttachmentConstruct (L1)Attaches an internet gateway, or a virtual private gateway to a VPC, enabling connectivity between the internet and the VPC.
CfnVPCPeeringConnectionConstruct (L1)Requests a VPC peering connection between two VPCs: a requester VPC that you own and an accepter VPC with which to create the connection.
CfnVPNConcentratorConstruct (L1)Describes a VPN concentrator.
CfnVPNConnectionConstruct (L1)Specifies a VPN connection between a virtual private gateway and a VPN customer gateway or a transit gateway and a VPN customer gateway.
CfnVPNConnectionRouteConstruct (L1)Specifies a static route for a VPN connection between an existing virtual private gateway and a VPN customer gateway.
CfnVPNGatewayConstruct (L1)Specifies a virtual private gateway.
CfnVPNGatewayRoutePropagationConstruct (L1)Enables a virtual private gateway (VGW) to propagate routes to the specified route table of a VPC.
AcceleratorManufacturerEnumSupported hardware accelerator manufacturers.
AcceleratorNameEnumSpecific hardware accelerator models supported by EC2.
AcceleratorTypeEnumHardware accelerator categories available for EC2 instances.
AclCidrClassEither an IPv4 or an IPv6 CIDR.
AclCidrConfigStructAcl Configuration for CIDR.
AclIcmpStructProperties to create Icmp.
AclPortRangeStructProperties to create PortRange.
AclTrafficClassThe traffic that is configured using a Network ACL entry.
AclTrafficConfigStructAcl Configuration for traffic.
ActionEnumWhat action to apply to traffic matching the ACL.
AddNatGatewayOptionsStructOptions for adding a NAT gateway to a public subnet.
AddressFamilyEnumThe IP address type.
AddRouteOptionsStructOptions for adding a new route to a subnet.
AllocateCidrRequestStructRequest for subnets CIDR to be allocated for a Vpc.
AllocatedSubnetStructCIDR Allocated Subnet.
AllocateIpv6CidrRequestStructRequest for subnet IPv6 CIDRs to be allocated for a VPC.
AllocateVpcIpv6CidrRequestStructRequest for allocation of the VPC IPv6 CIDR.
AmazonLinux2022ImageSsmParameterClassA SSM Parameter that contains the AMI ID for Amazon Linux 2023.
AmazonLinux2022ImageSsmParameterPropsStructProperties specific to al2022 images.
AmazonLinux2022KernelClassAmazon Linux 2022 kernel versions.
AmazonLinux2023ImageSsmParameterClassA SSM Parameter that contains the AMI ID for Amazon Linux 2023.
AmazonLinux2023ImageSsmParameterPropsStructProperties specific to al2023 images.
AmazonLinux2023KernelClassAmazon Linux 2023 kernel versions.
AmazonLinux2ImageSsmParameterClassA SSM Parameter that contains the AMI ID for Amazon Linux 2.
AmazonLinux2ImageSsmParameterPropsStructProperties specific to amzn2 images.
AmazonLinux2KernelClassAmazon Linux 2 kernel versions.
AmazonLinuxCpuTypeEnumCPU type.
AmazonLinuxEditionEnumAmazon Linux edition.
AmazonLinuxGenerationEnumWhat generation of Amazon Linux to use.
AmazonLinuxImageClassSelects the latest version of Amazon Linux.
AmazonLinuxImagePropsStructAmazon Linux image properties.
AmazonLinuxImageSsmParameterBaseClass
AmazonLinuxImageSsmParameterBaseOptionsStructBase options for amazon linux ssm parameters.
AmazonLinuxImageSsmParameterBasePropsStructBase properties for an Amazon Linux SSM Parameter.
AmazonLinuxImageSsmParameterCommonOptionsStructCommon options across all generations.
AmazonLinuxKernelEnumAmazon Linux Kernel.
AmazonLinuxStorageEnumAvailable storage options for Amazon Linux images Only applies to Amazon Linux & Amazon Linux 2.
AmazonLinuxVirtEnumVirtualization type for Amazon Linux.
ApplyCloudFormationInitOptionsStructOptions for applying CloudFormation init to an instance or instance group.
AttachInitOptionsStructOptions for attaching a CloudFormationInit to a resource.
AvailabilityZoneAddressStructConfiguration for a specific Availability Zone in a Regional NAT Gateway.
AwsIpamPropsStructConfiguration for AwsIpam.
BareMetalEnumBare metal support requirements for EC2 instances.
BastionHostLinuxPropsStructProperties of the bastion host.
BlockDeviceStructBlock device.
BlockDeviceVolumeClassDescribes a block device mapping for an EC2 instance or Auto Scaling group.
BurstablePerformanceEnumBurstable CPU performance requirements for EC2 instances.
CfnApplicationStatusCheck.HealthCheckPathDestinationPropertyStruct
CfnApplicationStatusCheck.HealthCheckPathPropertyStruct
CfnApplicationStatusCheck.HealthCheckPathSourcePropertyStruct
CfnApplicationStatusCheckPropsStructProperties for defining a CfnApplicationStatusCheck.
CfnCapacityManagerDataExportPropsStructProperties for defining a CfnCapacityManagerDataExport.
CfnCapacityReservation.CapacityAllocationPropertyStructInformation about instance capacity usage for a Capacity Reservation.
CfnCapacityReservation.CommitmentInfoPropertyStructInformation about your commitment for a future-dated Capacity Reservation.
CfnCapacityReservation.TagSpecificationPropertyStructAn array of key-value pairs to apply to this resource.
CfnCapacityReservationFleet.InstanceTypeSpecificationPropertyStructSpecifies information about an instance type to use in a Capacity Reservation Fleet.
CfnCapacityReservationFleet.TagSpecificationPropertyStructThe tags to apply to a resource when the resource is being created.
CfnCapacityReservationFleetPropsStructProperties for defining a CfnCapacityReservationFleet.
CfnCapacityReservationPropsStructProperties for defining a CfnCapacityReservation.
CfnCarrierGatewayPropsStructProperties for defining a CfnCarrierGateway.
CfnClientVpnAuthorizationRulePropsStructProperties for defining a CfnClientVpnAuthorizationRule.
CfnClientVpnEndpoint.CertificateAuthenticationRequestPropertyStructInformation about the client certificate to be used for authentication.
CfnClientVpnEndpoint.ClientAuthenticationRequestPropertyStructDescribes the authentication method to be used by a Client VPN endpoint.
CfnClientVpnEndpoint.ClientConnectOptionsPropertyStructIndicates whether client connect options are enabled.
CfnClientVpnEndpoint.ClientLoginBannerOptionsPropertyStructOptions for enabling a customizable text banner that will be displayed on AWS provided clients when a VPN session is established.
CfnClientVpnEndpoint.ClientRouteEnforcementOptionsPropertyStructClient Route Enforcement is a feature of Client VPN that helps enforce administrator defined routes on devices connected through the VPN.
CfnClientVpnEndpoint.ConnectionLogOptionsPropertyStructDescribes the client connection logging options for the Client VPN endpoint.
CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestPropertyStructDescribes the Active Directory to be used for client authentication.
CfnClientVpnEndpoint.FederatedAuthenticationRequestPropertyStructThe IAM SAML identity provider used for federated authentication.
CfnClientVpnEndpoint.TagSpecificationPropertyStructSpecifies the tags to apply to the Client VPN endpoint.
CfnClientVpnEndpoint.TransitGatewayConfigurationPropertyStruct
CfnClientVpnEndpointPropsStructProperties for defining a CfnClientVpnEndpoint.
CfnClientVpnRoutePropsStructProperties for defining a CfnClientVpnRoute.
CfnClientVpnTargetNetworkAssociationPropsStructProperties for defining a CfnClientVpnTargetNetworkAssociation.
CfnCustomerGatewayPropsStructProperties for defining a CfnCustomerGateway.
CfnDHCPOptionsPropsStructProperties for defining a CfnDHCPOptions.
CfnEC2Fleet.AcceleratorCountRequestPropertyStructThe minimum and maximum number of accelerators (GPUs, FPGAs, or AWS Inferentia chips) on an instance.
CfnEC2Fleet.AcceleratorTotalMemoryMiBRequestPropertyStructThe minimum and maximum amount of total accelerator memory, in MiB.
CfnEC2Fleet.BaselineEbsBandwidthMbpsRequestPropertyStructThe minimum and maximum baseline bandwidth to Amazon EBS, in Mbps.
CfnEC2Fleet.BaselinePerformanceFactorsRequestPropertyStructThe baseline performance to consider, using an instance family as a baseline reference.
CfnEC2Fleet.BlockDeviceMappingPropertyStructDescribes a block device mapping, which defines the EBS volumes and instance store volumes to attach to an instance at launch.
CfnEC2Fleet.CapacityRebalancePropertyStructThe Spot Instance replacement strategy to use when Amazon EC2 emits a rebalance notification signal that your Spot Instance is at an elevated risk of being interrupted.
CfnEC2Fleet.CapacityReservationOptionsRequestPropertyStructDescribes the strategy for using unused Capacity Reservations for fulfilling On-Demand capacity.
CfnEC2Fleet.CapacityReservationTargetRequestPropertyStruct
CfnEC2Fleet.CpuPerformanceFactorRequestPropertyStructThe CPU performance to consider, using an instance family as the baseline reference.
CfnEC2Fleet.EbsBlockDevicePropertyStructDescribes a block device for an EBS volume.
CfnEC2Fleet.FleetLaunchTemplateConfigRequestPropertyStructSpecifies a launch template and overrides for an EC2 Fleet.
CfnEC2Fleet.FleetLaunchTemplateOverridesRequestPropertyStructSpecifies overrides for a launch template for an EC2 Fleet.
CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestPropertyStructSpecifies the launch template to be used by the EC2 Fleet for configuring Amazon EC2 instances.
CfnEC2Fleet.IamInstanceProfileSpecificationPropertyStruct
CfnEC2Fleet.InstanceMetadataOptionsRequestPropertyStruct
CfnEC2Fleet.InstanceRequirementsRequestPropertyStructThe attributes for the instance types.
CfnEC2Fleet.Ipv6AddressRequestPropertyStruct
CfnEC2Fleet.MaintenanceStrategiesPropertyStructThe strategies for managing your Spot Instances that are at an elevated risk of being interrupted.
CfnEC2Fleet.MemoryGiBPerVCpuRequestPropertyStructThe minimum and maximum amount of memory per vCPU, in GiB.
CfnEC2Fleet.MemoryMiBRequestPropertyStructThe minimum and maximum amount of memory, in MiB.
CfnEC2Fleet.MultiAvailabilityZoneConfigurationPropertyStruct
CfnEC2Fleet.NetworkBandwidthGbpsRequestPropertyStructThe minimum and maximum amount of network bandwidth, in gigabits per second (Gbps).
CfnEC2Fleet.NetworkInterfaceCountRequestPropertyStructThe minimum and maximum number of network interfaces.
CfnEC2Fleet.NetworkInterfaceSpecificationRequestPropertyStruct
CfnEC2Fleet.OnDemandOptionsRequestPropertyStructSpecifies the allocation strategy of On-Demand Instances in an EC2 Fleet.
CfnEC2Fleet.PerformanceFactorReferenceRequestPropertyStructSpecify an instance family to use as the baseline reference for CPU performance.
CfnEC2Fleet.PlacementPropertyStructDescribes the placement of an instance.
CfnEC2Fleet.PrivateIpAddressSpecificationRequestPropertyStruct
CfnEC2Fleet.ReservedCapacityFallbackOptionsRequestPropertyStruct
CfnEC2Fleet.ReservedCapacityOptionsRequestPropertyStruct
CfnEC2Fleet.SpotOptionsRequestPropertyStructSpecifies the configuration of Spot Instances for an EC2 Fleet.
CfnEC2Fleet.StandbyAvailabilityZonePropertyStruct
CfnEC2Fleet.TagSpecificationPropertyStructSpecifies the tags to apply to a resource when the resource is being created for an EC2 Fleet.
CfnEC2Fleet.TargetCapacitySpecificationRequestPropertyStructSpecifies the number of units to request for an EC2 Fleet.
CfnEC2Fleet.TotalLocalStorageGBRequestPropertyStructThe minimum and maximum amount of total local storage, in GB.
CfnEC2Fleet.VCpuCountRangeRequestPropertyStructThe minimum and maximum number of vCPUs.
CfnEC2FleetPropsStructProperties for defining a CfnEC2Fleet.
CfnEgressOnlyInternetGatewayPropsStructProperties for defining a CfnEgressOnlyInternetGateway.
CfnEIPAssociationPropsStructProperties for defining a CfnEIPAssociation.
CfnEIPPropsStructProperties for defining a CfnEIP.
CfnEnclaveCertificateIamRoleAssociationPropsStructProperties for defining a CfnEnclaveCertificateIamRoleAssociation.
CfnFlowLog.DestinationOptionsPropertyStructDescribes the destination options for a flow log.
CfnFlowLog.TagFieldSpecificationPropertyStruct
CfnFlowLogPropsStructProperties for defining a CfnFlowLog.
CfnFpgaImage.StorageLocationPropertyStructDescribes a storage location in Amazon S3.
CfnFpgaImagePropsStructProperties for defining a CfnFpgaImage.
CfnGatewayRouteTableAssociationPropsStructProperties for defining a CfnGatewayRouteTableAssociation.
CfnHostPropsStructProperties for defining a CfnHost.
CfnInstance.AssociationParameterPropertyStructSpecifies input parameter values for an SSM document in AWS Systems Manager .
CfnInstance.BlockDeviceMappingPropertyStructSpecifies a block device mapping for an instance.
CfnInstance.CpuOptionsPropertyStructSpecifies the CPU options for the instance.
CfnInstance.CreditSpecificationPropertyStructSpecifies the credit option for CPU usage of a T instance.
CfnInstance.EbsPropertyStructSpecifies a block device for an EBS volume.
CfnInstance.ElasticGpuSpecificationPropertyStruct> Amazon Elastic Graphics reached end of life on January 8, 2024.
CfnInstance.ElasticInferenceAcceleratorPropertyStruct> Amazon Elastic Inference is no longer available.
CfnInstance.EnaSrdSpecificationPropertyStructENA Express uses AWS Scalable Reliable Datagram (SRD) technology to increase the maximum bandwidth used per stream and minimize tail latency of network traffic between EC2 instances.
CfnInstance.EnaSrdUdpSpecificationPropertyStructENA Express is compatible with both TCP and UDP transport protocols.
CfnInstance.EnclaveOptionsPropertyStructIndicates whether the instance is enabled for AWS Nitro Enclaves.
CfnInstance.HibernationOptionsPropertyStructSpecifies the hibernation options for the instance.
CfnInstance.InstanceIpv6AddressPropertyStructSpecifies the IPv6 address for the instance.
CfnInstance.LaunchTemplateSpecificationPropertyStructSpecifies a launch template to use when launching an Amazon EC2 instance.
CfnInstance.LicenseSpecificationPropertyStructSpecifies the license configuration to use.
CfnInstance.MetadataOptionsPropertyStructSpecifies the metadata options for the instance.
CfnInstance.NetworkInterfacePropertyStructSpecifies a network interface that is to be attached to an instance.
CfnInstance.NoDevicePropertyStruct
CfnInstance.PrivateDnsNameOptionsPropertyStructThe type of hostnames to assign to instances in the subnet at launch.
CfnInstance.PrivateIpAddressSpecificationPropertyStructSpecifies a secondary private IPv4 address for a network interface.
CfnInstance.SsmAssociationPropertyStructSpecifies the SSM document and parameter values in AWS Systems Manager to associate with an instance.
CfnInstance.StatePropertyStructDescribes the current state of an instance.
CfnInstance.VolumePropertyStructSpecifies a volume to attach to an instance.
CfnInstanceConnectEndpoint.InstanceConnectEndpointDnsNamesPropertyStructThe DNS names of the endpoint.
CfnInstanceConnectEndpoint.InstanceConnectEndpointPublicDnsNamesPropertyStructThe public DNS names of the endpoint, including IPv4-only and dualstack DNS names.
CfnInstanceConnectEndpointPropsStructProperties for defining a CfnInstanceConnectEndpoint.
CfnInstanceEventWindow.TimeRangePropertyStructA time range during which an AWS-initiated maintenance event may occur.
CfnInstanceEventWindowPropsStructProperties for defining a CfnInstanceEventWindow.
CfnInstancePropsStructProperties for defining a CfnInstance.
CfnInternetGatewayPropsStructProperties for defining a CfnInternetGateway.
CfnIPAM.IpamOperatingRegionPropertyStructThe operating Regions for an IPAM.
CfnIPAM.IpamOrganizationalUnitExclusionPropertyStructIf your IPAM is integrated with AWS Organizations, you can exclude an organizational unit (OU) from being managed by IPAM. When you exclude an OU, IPAM will not manage the IP addresses in accounts in that OU. For more information, see Exclude organizational units from IPAM in the Amazon Virtual Private Cloud IP Address Manager User Guide .
CfnIPAMAllocationPropsStructProperties for defining a CfnIPAMAllocation.
CfnIpamExternalResourceVerificationTokenPropsStructProperties for defining a CfnIpamExternalResourceVerificationToken.
CfnIPAMPool.ProvisionedCidrPropertyStructThe CIDR provisioned to the IPAM pool.
CfnIPAMPool.SourceResourcePropertyStructThe resource used to provision CIDRs to a resource planning pool.
CfnIPAMPoolCidrPropsStructProperties for defining a CfnIPAMPoolCidr.
CfnIPAMPoolPropsStructProperties for defining a CfnIPAMPool.
CfnIPAMPrefixListResolver.IpamPrefixListResolverRuleConditionPropertyStructTwo of the rule types allow you to add conditions to the rules.
CfnIPAMPrefixListResolver.IpamPrefixListResolverRulePropertyStructCIDR selection rules define the business logic for selecting CIDRs from IPAM.
CfnIPAMPrefixListResolverPropsStructProperties for defining a CfnIPAMPrefixListResolver.
CfnIPAMPrefixListResolverTargetPropsStructProperties for defining a CfnIPAMPrefixListResolverTarget.
CfnIPAMPropsStructProperties for defining a CfnIPAM.
CfnIPAMResourceDiscovery.IpamOperatingRegionPropertyStructThe operating Regions for an IPAM.
CfnIPAMResourceDiscovery.IpamResourceDiscoveryOrganizationalUnitExclusionPropertyStructIf your IPAM is integrated with AWS Organizations, you can exclude an organizational unit (OU) from being managed by IPAM. When you exclude an OU, IPAM will not manage the IP addresses in accounts in that OU. For more information, see Exclude organizational units from IPAM in the Amazon Virtual Private Cloud IP Address Manager User Guide .
CfnIPAMResourceDiscoveryAssociationPropsStructProperties for defining a CfnIPAMResourceDiscoveryAssociation.
CfnIPAMResourceDiscoveryPropsStructProperties for defining a CfnIPAMResourceDiscovery.
CfnIPAMScope.IpamScopeExternalAuthorityConfigurationPropertyStructThe configuration that links an Amazon VPC IPAM scope to an external authority system.
CfnIPAMScopePropsStructProperties for defining a CfnIPAMScope.
CfnIpPoolRouteTableAssociationPropsStructProperties for defining a CfnIpPoolRouteTableAssociation.
CfnIPv4PoolPropsStructProperties for defining a CfnIPv4Pool.
CfnKeyPairPropsStructProperties for defining a CfnKeyPair.
CfnLaunchTemplate.AcceleratorCountPropertyStructThe minimum and maximum number of accelerators (GPUs, FPGAs, or AWS Inferentia chips) on an instance.
CfnLaunchTemplate.AcceleratorTotalMemoryMiBPropertyStructThe minimum and maximum amount of total accelerator memory, in MiB.
CfnLaunchTemplate.BaselineEbsBandwidthMbpsPropertyStructThe minimum and maximum baseline bandwidth to Amazon EBS, in Mbps.
CfnLaunchTemplate.BaselinePerformanceFactorsPropertyStructThe baseline performance to consider, using an instance family as a baseline reference.
CfnLaunchTemplate.BlockDeviceMappingPropertyStructSpecifies a block device mapping for a launch template.
CfnLaunchTemplate.CapacityReservationSpecificationPropertyStructSpecifies an instance's Capacity Reservation targeting option. You can specify only one option at a time.
CfnLaunchTemplate.CapacityReservationTargetPropertyStructSpecifies a target Capacity Reservation.
CfnLaunchTemplate.ConnectionTrackingSpecificationPropertyStructA security group connection tracking specification that enables you to set the idle timeout for connection tracking on an Elastic network interface.
CfnLaunchTemplate.CpuOptionsPropertyStructSpecifies the CPU options for an instance.
CfnLaunchTemplate.CpuPropertyStructSpecifies the CPU performance to consider when using an instance family as the baseline reference.
CfnLaunchTemplate.CreditSpecificationPropertyStructSpecifies the credit option for CPU usage of a T2, T3, or T3a instance.
CfnLaunchTemplate.EbsPropertyStructParameters for a block device for an EBS volume in an Amazon EC2 launch template.
CfnLaunchTemplate.ElasticGpuSpecificationPropertyStruct
CfnLaunchTemplate.EnaSrdSpecificationPropertyStructENA Express uses AWS Scalable Reliable Datagram (SRD) technology to increase the maximum bandwidth used per stream and minimize tail latency of network traffic between EC2 instances.
CfnLaunchTemplate.EnaSrdUdpSpecificationPropertyStructENA Express is compatible with both TCP and UDP transport protocols.
CfnLaunchTemplate.EnclaveOptionsPropertyStructIndicates whether the instance is enabled for AWS Nitro Enclaves.
CfnLaunchTemplate.HibernationOptionsPropertyStructSpecifies whether your instance is configured for hibernation.
CfnLaunchTemplate.IamInstanceProfilePropertyStructSpecifies an IAM instance profile, which is a container for an IAM role for your instance.
CfnLaunchTemplate.InstanceMarketOptionsPropertyStructSpecifies the market (purchasing) option for an instance.
CfnLaunchTemplate.InstanceRequirementsPropertyStructThe attributes for the instance types.
CfnLaunchTemplate.Ipv4PrefixSpecificationPropertyStructSpecifies an IPv4 prefix for a network interface.
CfnLaunchTemplate.Ipv6AddPropertyStructSpecifies an IPv6 address in an Amazon EC2 launch template.
CfnLaunchTemplate.Ipv6PrefixSpecificationPropertyStructSpecifies an IPv6 prefix for a network interface.
CfnLaunchTemplate.LaunchTemplateDataPropertyStructThe information to include in the launch template.
CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorPropertyStruct
CfnLaunchTemplate.LaunchTemplateTagSpecificationPropertyStructSpecifies the tags to apply to the launch template during creation.
CfnLaunchTemplate.LicenseSpecificationPropertyStructSpecifies a license configuration for an instance.
CfnLaunchTemplate.MaintenanceOptionsPropertyStructThe maintenance options of your instance.
CfnLaunchTemplate.MemoryGiBPerVCpuPropertyStructThe minimum and maximum amount of memory per vCPU, in GiB.
CfnLaunchTemplate.MemoryMiBPropertyStructThe minimum and maximum amount of memory, in MiB.
CfnLaunchTemplate.MetadataOptionsPropertyStructThe metadata options for the instance.
CfnLaunchTemplate.MonitoringPropertyStructSpecifies whether detailed monitoring is enabled for an instance.
CfnLaunchTemplate.NetworkBandwidthGbpsPropertyStructThe minimum and maximum amount of network bandwidth, in gigabits per second (Gbps).
CfnLaunchTemplate.NetworkInterfaceCountPropertyStructThe minimum and maximum number of network interfaces.
CfnLaunchTemplate.NetworkInterfacePropertyStructSpecifies the parameters for a network interface.
CfnLaunchTemplate.NetworkPerformanceOptionsPropertyStructContains settings for the network performance options for the instance.
CfnLaunchTemplate.PlacementPropertyStructSpecifies the placement of an instance.
CfnLaunchTemplate.PrivateDnsNameOptionsPropertyStructThe hostname type for EC2 instances launched into this subnet and how DNS A and AAAA record queries should be handled.
CfnLaunchTemplate.PrivateIpAddPropertyStructSpecifies a secondary private IPv4 address for a network interface.
CfnLaunchTemplate.ReferencePropertyStructSpecifies an instance family to use as the baseline reference for CPU performance.
CfnLaunchTemplate.SpotOptionsPropertyStructSpecifies options for Spot Instances.
CfnLaunchTemplate.TagSpecificationPropertyStructSpecifies the tags to apply to resources that are created during instance launch.
CfnLaunchTemplate.TotalLocalStorageGBPropertyStructThe minimum and maximum amount of total local storage, in GB.
CfnLaunchTemplate.VCpuCountPropertyStructThe minimum and maximum number of vCPUs.
CfnLaunchTemplatePropsStructProperties for defining a CfnLaunchTemplate.
CfnLocalGatewayRoutePropsStructProperties for defining a CfnLocalGatewayRoute.
CfnLocalGatewayRouteTablePropsStructProperties for defining a CfnLocalGatewayRouteTable.
CfnLocalGatewayRouteTableVirtualInterfaceGroupAssociationPropsStructProperties for defining a CfnLocalGatewayRouteTableVirtualInterfaceGroupAssociation.
CfnLocalGatewayRouteTableVPCAssociationPropsStructProperties for defining a CfnLocalGatewayRouteTableVPCAssociation.
CfnLocalGatewayVirtualInterfaceGroupPropsStructProperties for defining a CfnLocalGatewayVirtualInterfaceGroup.
CfnLocalGatewayVirtualInterfacePropsStructProperties for defining a CfnLocalGatewayVirtualInterface.
CfnNatGateway.AvailabilityZoneAddressPropertyStructFor regional NAT gateways only: The configuration specifying which Elastic IP address (EIP) to use for handling outbound NAT traffic from a specific Availability Zone.
CfnNatGatewayPropsStructProperties for defining a CfnNatGateway.
CfnNetworkAclEntry.IcmpPropertyStructDescribes the ICMP type and code.
CfnNetworkAclEntry.PortRangePropertyStructDescribes a range of ports.
CfnNetworkAclEntryPropsStructProperties for defining a CfnNetworkAclEntry.
CfnNetworkAclPropsStructProperties for defining a CfnNetworkAcl.
CfnNetworkInsightsAccessScope.AccessScopePathRequestPropertyStructDescribes a path.
CfnNetworkInsightsAccessScope.PacketHeaderStatementRequestPropertyStructDescribes a packet header statement.
CfnNetworkInsightsAccessScope.PathStatementRequestPropertyStructDescribes a path statement.
CfnNetworkInsightsAccessScope.ResourceStatementRequestPropertyStructDescribes a resource statement.
CfnNetworkInsightsAccessScope.ThroughResourcesStatementRequestPropertyStructDescribes a through resource statement.
CfnNetworkInsightsAccessScopeAnalysisPropsStructProperties for defining a CfnNetworkInsightsAccessScopeAnalysis.
CfnNetworkInsightsAccessScopePropsStructProperties for defining a CfnNetworkInsightsAccessScope.
CfnNetworkInsightsAnalysis.AdditionalDetailPropertyStructDescribes an additional detail for a path analysis.
CfnNetworkInsightsAnalysis.AlternatePathHintPropertyStructDescribes an potential intermediate component of a feasible path.
CfnNetworkInsightsAnalysis.AnalysisAclRulePropertyStructDescribes a network access control (ACL) rule.
CfnNetworkInsightsAnalysis.AnalysisComponentPropertyStructDescribes a path component.
CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerPropertyStructDescribes a load balancer listener.
CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetPropertyStructDescribes a load balancer target.
CfnNetworkInsightsAnalysis.AnalysisPacketHeaderPropertyStructDescribes a header.
CfnNetworkInsightsAnalysis.AnalysisRouteTableRoutePropertyStructDescribes a route table route.
CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRulePropertyStructDescribes a security group rule.
CfnNetworkInsightsAnalysis.ExplanationPropertyStructDescribes an explanation code for an unreachable path.
CfnNetworkInsightsAnalysis.PathComponentPropertyStructDescribes a path component.
CfnNetworkInsightsAnalysis.PortRangePropertyStructDescribes a range of ports.
CfnNetworkInsightsAnalysis.TransitGatewayRouteTableRoutePropertyStructDescribes a route in a transit gateway route table.
CfnNetworkInsightsAnalysisPropsStructProperties for defining a CfnNetworkInsightsAnalysis.
CfnNetworkInsightsPath.FilterPortRangePropertyStructDescribes a port range.
CfnNetworkInsightsPath.PathFilterPropertyStructDescribes a set of filters for a path analysis.
CfnNetworkInsightsPathPropsStructProperties for defining a CfnNetworkInsightsPath.
CfnNetworkInterface.ConnectionTrackingSpecificationPropertyStructConfigurable options for connection tracking on a network interface.
CfnNetworkInterface.InstanceIpv6AddressPropertyStructDescribes the IPv6 addresses to associate with the network interface.
CfnNetworkInterface.Ipv4PrefixSpecificationPropertyStructDescribes an IPv4 prefix.
CfnNetworkInterface.Ipv6PrefixSpecificationPropertyStructDescribes the IPv6 prefix.
CfnNetworkInterface.PrivateIpAddressSpecificationPropertyStructDescribes a secondary private IPv4 address for a network interface.
CfnNetworkInterface.PublicIpDnsNameOptionsPropertyStructPublic hostname type options.
CfnNetworkInterfaceAttachment.EnaSrdSpecificationPropertyStructENA Express uses AWS Scalable Reliable Datagram (SRD) technology to increase the maximum bandwidth used per stream and minimize tail latency of network traffic between EC2 instances.
CfnNetworkInterfaceAttachment.EnaSrdUdpSpecificationPropertyStructENA Express is compatible with both TCP and UDP transport protocols.
CfnNetworkInterfaceAttachmentPropsStructProperties for defining a CfnNetworkInterfaceAttachment.
CfnNetworkInterfacePermissionPropsStructProperties for defining a CfnNetworkInterfacePermission.
CfnNetworkInterfacePropsStructProperties for defining a CfnNetworkInterface.
CfnNetworkPerformanceMetricSubscriptionPropsStructProperties for defining a CfnNetworkPerformanceMetricSubscription.
CfnPlacementGroupPropsStructProperties for defining a CfnPlacementGroup.
CfnPrefixList.EntryPropertyStructAn entry for a prefix list.
CfnPrefixListPropsStructProperties for defining a CfnPrefixList.
CfnRoutePropsStructProperties for defining a CfnRoute.
CfnRouteServerAssociationPropsStructProperties for defining a CfnRouteServerAssociation.
CfnRouteServerEndpointPropsStructProperties for defining a CfnRouteServerEndpoint.
CfnRouteServerPeer.BgpOptionsPropertyStructThe BGP configuration options for this peer, including ASN (Autonomous System Number) and BFD (Bidrectional Forwarding Detection) settings.
CfnRouteServerPeerPropsStructProperties for defining a CfnRouteServerPeer.
CfnRouteServerPropagationPropsStructProperties for defining a CfnRouteServerPropagation.
CfnRouteServerPropsStructProperties for defining a CfnRouteServer.
CfnRouteTablePropsStructProperties for defining a CfnRouteTable.
CfnSecurityGroup.EgressPropertyStructAdds the specified outbound (egress) rule to a security group.
CfnSecurityGroup.IngressPropertyStructAdds an inbound (ingress) rule to a security group.
CfnSecurityGroupEgressPropsStructProperties for defining a CfnSecurityGroupEgress.
CfnSecurityGroupIngressPropsStructProperties for defining a CfnSecurityGroupIngress.
CfnSecurityGroupPropsStructProperties for defining a CfnSecurityGroup.
CfnSecurityGroupVpcAssociationPropsStructProperties for defining a CfnSecurityGroupVpcAssociation.
CfnSnapshotBlockPublicAccessPropsStructProperties for defining a CfnSnapshotBlockPublicAccess.
CfnSpotFleet.AcceleratorCountRequestPropertyStructThe minimum and maximum number of accelerators (GPUs, FPGAs, or AWS Inferentia chips) on an instance.
CfnSpotFleet.AcceleratorTotalMemoryMiBRequestPropertyStructThe minimum and maximum amount of total accelerator memory, in MiB.
CfnSpotFleet.BaselineEbsBandwidthMbpsRequestPropertyStructThe minimum and maximum baseline bandwidth to Amazon EBS, in Mbps.
CfnSpotFleet.BaselinePerformanceFactorsRequestPropertyStructThe baseline performance to consider, using an instance family as a baseline reference.
CfnSpotFleet.BlockDeviceMappingPropertyStructSpecifies a block device mapping.
CfnSpotFleet.ClassicLoadBalancerPropertyStructSpecifies a Classic Load Balancer.
CfnSpotFleet.ClassicLoadBalancersConfigPropertyStructSpecifies the Classic Load Balancers to attach to a Spot Fleet.
CfnSpotFleet.CpuPerformanceFactorRequestPropertyStructThe CPU performance to consider, using an instance family as the baseline reference.
CfnSpotFleet.EbsBlockDevicePropertyStructDescribes a block device for an EBS volume.
CfnSpotFleet.FleetLaunchTemplateSpecificationPropertyStructSpecifies the launch template to be used by the Spot Fleet request for configuring Amazon EC2 instances.
CfnSpotFleet.GroupIdentifierPropertyStructDescribes a security group.
CfnSpotFleet.IamInstanceProfileSpecificationPropertyStructDescribes an IAM instance profile.
CfnSpotFleet.InstanceIpv6AddressPropertyStructDescribes an IPv6 address.
CfnSpotFleet.InstanceNetworkInterfaceSpecificationPropertyStructDescribes a network interface.
CfnSpotFleet.InstanceRequirementsRequestPropertyStructThe attributes for the instance types.
CfnSpotFleet.LaunchTemplateConfigPropertyStructSpecifies a launch template and overrides.
CfnSpotFleet.LaunchTemplateOverridesPropertyStructSpecifies overrides for a launch template.
CfnSpotFleet.LoadBalancersConfigPropertyStructSpecifies the Classic Load Balancers and target groups to attach to a Spot Fleet request.
CfnSpotFleet.MemoryGiBPerVCpuRequestPropertyStructThe minimum and maximum amount of memory per vCPU, in GiB.
CfnSpotFleet.MemoryMiBRequestPropertyStructThe minimum and maximum amount of memory, in MiB.
CfnSpotFleet.NetworkBandwidthGbpsRequestPropertyStructThe minimum and maximum amount of baseline network bandwidth, in gigabits per second (Gbps).
CfnSpotFleet.NetworkInterfaceCountRequestPropertyStructThe minimum and maximum number of network interfaces.
CfnSpotFleet.PerformanceFactorReferenceRequestPropertyStructSpecify an instance family to use as the baseline reference for CPU performance.
CfnSpotFleet.PrivateIpAddressSpecificationPropertyStructDescribes a secondary private IPv4 address for a network interface.
CfnSpotFleet.SpotCapacityRebalancePropertyStructThe Spot Instance replacement strategy to use when Amazon EC2 emits a signal that your Spot Instance is at an elevated risk of being interrupted.
CfnSpotFleet.SpotFleetLaunchSpecificationPropertyStructSpecifies the launch specification for one or more Spot Instances.
CfnSpotFleet.SpotFleetMonitoringPropertyStructDescribes whether monitoring is enabled.
CfnSpotFleet.SpotFleetRequestConfigDataPropertyStructSpecifies the configuration of a Spot Fleet request.
CfnSpotFleet.SpotFleetTagSpecificationPropertyStructThe tags for a Spot Fleet resource.
CfnSpotFleet.SpotMaintenanceStrategiesPropertyStructThe strategies for managing your Spot Instances that are at an elevated risk of being interrupted.
CfnSpotFleet.SpotPlacementPropertyStructDescribes Spot Instance placement.
CfnSpotFleet.TargetGroupPropertyStructDescribes a load balancer target group.
CfnSpotFleet.TargetGroupsConfigPropertyStructDescribes the target groups to attach to a Spot Fleet.
CfnSpotFleet.TotalLocalStorageGBRequestPropertyStructThe minimum and maximum amount of total local storage, in GB.
CfnSpotFleet.VCpuCountRangeRequestPropertyStructThe minimum and maximum number of vCPUs.
CfnSpotFleetPropsStructProperties for defining a CfnSpotFleet.
CfnSqlHaStandbyDetectedInstancePropsStructProperties for defining a CfnSqlHaStandbyDetectedInstance.
CfnSubnet.BlockPublicAccessStatesPropertyStructSpecifies the state of VPC Block Public Access (BPA).
CfnSubnet.PrivateDnsNameOptionsOnLaunchPropertyStructSpecifies the options for instance hostnames.
CfnSubnetCidrBlockPropsStructProperties for defining a CfnSubnetCidrBlock.
CfnSubnetCidrReservationPropsStructProperties for defining a CfnSubnetCidrReservation.
CfnSubnetNetworkAclAssociationPropsStructProperties for defining a CfnSubnetNetworkAclAssociation.
CfnSubnetPropsStructProperties for defining a CfnSubnet.
CfnSubnetRouteTableAssociationPropsStructProperties for defining a CfnSubnetRouteTableAssociation.
CfnTrafficMirrorFilterPropsStructProperties for defining a CfnTrafficMirrorFilter.
CfnTrafficMirrorFilterRule.TrafficMirrorPortRangePropertyStructDescribes the Traffic Mirror port range.
CfnTrafficMirrorFilterRulePropsStructProperties for defining a CfnTrafficMirrorFilterRule.
CfnTrafficMirrorSessionPropsStructProperties for defining a CfnTrafficMirrorSession.
CfnTrafficMirrorTargetPropsStructProperties for defining a CfnTrafficMirrorTarget.
CfnTransitGatewayAttachment.OptionsPropertyStructDescribes the VPC attachment options.
CfnTransitGatewayAttachmentPropsStructProperties for defining a CfnTransitGatewayAttachment.
CfnTransitGatewayConnect.TransitGatewayConnectOptionsPropertyStructDescribes the Connect attachment options.
CfnTransitGatewayConnectPeer.TransitGatewayAttachmentBgpConfigurationPropertyStructThe BGP configuration information.
CfnTransitGatewayConnectPeer.TransitGatewayConnectPeerConfigurationPropertyStructDescribes the Connect peer details.
CfnTransitGatewayConnectPeerPropsStructProperties for defining a CfnTransitGatewayConnectPeer.
CfnTransitGatewayConnectPropsStructProperties for defining a CfnTransitGatewayConnect.
CfnTransitGatewayMeteringPolicyEntryPropsStructProperties for defining a CfnTransitGatewayMeteringPolicyEntry.
CfnTransitGatewayMeteringPolicyPropsStructProperties for defining a CfnTransitGatewayMeteringPolicy.
CfnTransitGatewayMulticastDomain.OptionsPropertyStructThe options for the transit gateway multicast domain.
CfnTransitGatewayMulticastDomainAssociationPropsStructProperties for defining a CfnTransitGatewayMulticastDomainAssociation.
CfnTransitGatewayMulticastDomainPropsStructProperties for defining a CfnTransitGatewayMulticastDomain.
CfnTransitGatewayMulticastGroupMemberPropsStructProperties for defining a CfnTransitGatewayMulticastGroupMember.
CfnTransitGatewayMulticastGroupSourcePropsStructProperties for defining a CfnTransitGatewayMulticastGroupSource.
CfnTransitGatewayPeeringAttachment.PeeringAttachmentStatusPropertyStructThe status of the transit gateway peering attachment.
CfnTransitGatewayPeeringAttachmentPropsStructProperties for defining a CfnTransitGatewayPeeringAttachment.
CfnTransitGatewayPolicyTableAssociationPropsStructProperties for defining a CfnTransitGatewayPolicyTableAssociation.
CfnTransitGatewayPolicyTableEntry.TransitGatewayPolicyRulePropertyStruct
CfnTransitGatewayPolicyTableEntryPropsStructProperties for defining a CfnTransitGatewayPolicyTableEntry.
CfnTransitGatewayPolicyTablePropsStructProperties for defining a CfnTransitGatewayPolicyTable.
CfnTransitGatewayPropsStructProperties for defining a CfnTransitGateway.
CfnTransitGatewayRoutePropsStructProperties for defining a CfnTransitGatewayRoute.
CfnTransitGatewayRouteTableAssociationPropsStructProperties for defining a CfnTransitGatewayRouteTableAssociation.
CfnTransitGatewayRouteTablePropagationPropsStructProperties for defining a CfnTransitGatewayRouteTablePropagation.
CfnTransitGatewayRouteTablePropsStructProperties for defining a CfnTransitGatewayRouteTable.
CfnTransitGatewayVpcAttachment.OptionsPropertyStructDescribes the VPC attachment options.
CfnTransitGatewayVpcAttachmentPropsStructProperties for defining a CfnTransitGatewayVpcAttachment.
CfnVerifiedAccessEndpoint.CidrOptionsPropertyStructDescribes the CIDR options for a Verified Access endpoint.
CfnVerifiedAccessEndpoint.LoadBalancerOptionsPropertyStructDescribes the load balancer options when creating an AWS Verified Access endpoint using the load-balancer type.
CfnVerifiedAccessEndpoint.NetworkInterfaceOptionsPropertyStructDescribes the network interface options when creating an AWS Verified Access endpoint using the network-interface type.
CfnVerifiedAccessEndpoint.PortRangePropertyStructDescribes the port range for a Verified Access endpoint.
CfnVerifiedAccessEndpoint.RdsOptionsPropertyStructDescribes the RDS options for a Verified Access endpoint.
CfnVerifiedAccessEndpoint.SseSpecificationPropertyStructAWS Verified Access provides server side encryption by default to data at rest using AWS -owned KMS keys.
CfnVerifiedAccessEndpointPropsStructProperties for defining a CfnVerifiedAccessEndpoint.
CfnVerifiedAccessGroup.SseSpecificationPropertyStructAWS Verified Access provides server side encryption by default to data at rest using AWS -owned KMS keys.
CfnVerifiedAccessGroupPropsStructProperties for defining a CfnVerifiedAccessGroup.
CfnVerifiedAccessInstance.CloudWatchLogsPropertyStructOptions for CloudWatch Logs as a logging destination.
CfnVerifiedAccessInstance.KinesisDataFirehosePropertyStructOptions for Kinesis as a logging destination.
CfnVerifiedAccessInstance.S3PropertyStructOptions for Amazon S3 as a logging destination.
CfnVerifiedAccessInstance.VerifiedAccessLogsPropertyStructDescribes the options for Verified Access logs.
CfnVerifiedAccessInstance.VerifiedAccessTrustProviderPropertyStructA trust provider is a third-party entity that creates, maintains, and manages identity information for users and devices.
CfnVerifiedAccessInstancePropsStructProperties for defining a CfnVerifiedAccessInstance.
CfnVerifiedAccessTrustProvider.DeviceOptionsPropertyStructDescribes the options for an AWS Verified Access device-identity based trust provider.
CfnVerifiedAccessTrustProvider.NativeApplicationOidcOptionsPropertyStructDescribes the OpenID Connect (OIDC) options.
CfnVerifiedAccessTrustProvider.OidcOptionsPropertyStructDescribes the options for an OpenID Connect-compatible user-identity trust provider.
CfnVerifiedAccessTrustProvider.SseSpecificationPropertyStructAWS Verified Access provides server side encryption by default to data at rest using AWS -owned KMS keys.
CfnVerifiedAccessTrustProviderPropsStructProperties for defining a CfnVerifiedAccessTrustProvider.
CfnVolumeAttachmentPropsStructProperties for defining a CfnVolumeAttachment.
CfnVolumePropsStructProperties for defining a CfnVolume.
CfnVPC.VpcEncryptionControlExclusionPropertyStructDescribes an exclusion configuration for VPC Encryption Control.
CfnVPC.VpcEncryptionControlExclusionsPropertyStructDescribes the exclusion configurations for various resource types in VPC Encryption Control.
CfnVPC.VpcEncryptionControlPropertyStructDescribes the configuration and state of VPC encryption controls.
CfnVPCBlockPublicAccessExclusionPropsStructProperties for defining a CfnVPCBlockPublicAccessExclusion.
CfnVPCBlockPublicAccessOptionsPropsStructProperties for defining a CfnVPCBlockPublicAccessOptions.
CfnVPCCidrBlockPropsStructProperties for defining a CfnVPCCidrBlock.
CfnVPCDHCPOptionsAssociationPropsStructProperties for defining a CfnVPCDHCPOptionsAssociation.
CfnVPCEncryptionControl.ResourceExclusionsPropertyStructInformation about resource exclusions for the VPC Encryption Control configuration.
CfnVPCEncryptionControl.VpcEncryptionControlExclusionPropertyStructDescribes an exclusion configuration for VPC Encryption Control.
CfnVPCEncryptionControlPropsStructProperties for defining a CfnVPCEncryptionControl.
CfnVPCEndpoint.DnsOptionsSpecificationPropertyStructDescribes the DNS options for an endpoint.
CfnVPCEndpointConnectionNotificationPropsStructProperties for defining a CfnVPCEndpointConnectionNotification.
CfnVPCEndpointPropsStructProperties for defining a CfnVPCEndpoint.
CfnVPCEndpointService.PrivateDnsNameConfigurationPropertyStruct
CfnVPCEndpointServicePermissionsPropsStructProperties for defining a CfnVPCEndpointServicePermissions.
CfnVPCEndpointServicePropsStructProperties for defining a CfnVPCEndpointService.
CfnVPCGatewayAttachmentPropsStructProperties for defining a CfnVPCGatewayAttachment.
CfnVPCPeeringConnectionPropsStructProperties for defining a CfnVPCPeeringConnection.
CfnVPCPropsStructProperties for defining a CfnVPC.
CfnVPNConcentratorPropsStructProperties for defining a CfnVPNConcentrator.
CfnVPNConnection.CloudwatchLogOptionsSpecificationPropertyStructOptions for sending VPN tunnel logs to CloudWatch.
CfnVPNConnection.IKEVersionsRequestListValuePropertyStructThe IKE version that is permitted for the VPN tunnel.
CfnVPNConnection.Phase1DHGroupNumbersRequestListValuePropertyStructSpecifies a Diffie-Hellman group number for the VPN tunnel for phase 1 IKE negotiations.
CfnVPNConnection.Phase1EncryptionAlgorithmsRequestListValuePropertyStructSpecifies the encryption algorithm for the VPN tunnel for phase 1 IKE negotiations.
CfnVPNConnection.Phase1IntegrityAlgorithmsRequestListValuePropertyStructSpecifies the integrity algorithm for the VPN tunnel for phase 1 IKE negotiations.
CfnVPNConnection.Phase2DHGroupNumbersRequestListValuePropertyStructSpecifies a Diffie-Hellman group number for the VPN tunnel for phase 2 IKE negotiations.
CfnVPNConnection.Phase2EncryptionAlgorithmsRequestListValuePropertyStructSpecifies the encryption algorithm for the VPN tunnel for phase 2 IKE negotiations.
CfnVPNConnection.Phase2IntegrityAlgorithmsRequestListValuePropertyStructSpecifies the integrity algorithm for the VPN tunnel for phase 2 IKE negotiations.
CfnVPNConnection.VpnTunnelLogOptionsSpecificationPropertyStructOptions for logging VPN tunnel activity.
CfnVPNConnection.VpnTunnelOptionsSpecificationPropertyStructThe tunnel options for a single VPN tunnel.
CfnVPNConnectionPropsStructProperties for defining a CfnVPNConnection.
CfnVPNConnectionRoutePropsStructProperties for defining a CfnVPNConnectionRoute.
CfnVPNGatewayPropsStructProperties for defining a CfnVPNGateway.
CfnVPNGatewayRoutePropagationPropsStructProperties for defining a CfnVPNGatewayRoutePropagation.
ClientRouteEnforcementOptionsStructOptions for Client Route Enforcement.
ClientVpnAuthorizationRuleOptionsStructOptions for a ClientVpnAuthorizationRule.
ClientVpnAuthorizationRulePropsStructProperties for a ClientVpnAuthorizationRule.
ClientVpnEndpointAttributesStructAttributes when importing an existing client VPN endpoint.
ClientVpnEndpointOptionsStructOptions for a client VPN endpoint.
ClientVpnEndpointPropsStructProperties for a client VPN endpoint.
ClientVpnRouteOptionsStructOptions for a ClientVpnRoute.
ClientVpnRoutePropsStructProperties for a ClientVpnRoute.
ClientVpnRouteTargetClassTarget for a client VPN route.
ClientVpnSessionTimeoutEnumMaximum VPN session duration time.
ClientVpnUserBasedAuthenticationClassUser-based authentication for a client VPN endpoint.
CloudFormationInitClassA CloudFormation-init configuration.
CommonNetworkAclEntryOptionsStructBasic NetworkACL entry props.
ConfigSetPropsStructOptions for CloudFormationInit.withConfigSets.
ConfigureNatOptionsStructOptions passed by the VPC when NAT needs to be configured.
ConnectionRuleStruct
ConnectionsClassManage the allowed network connections for constructs with Security Groups.
ConnectionsPropsStructProperties to intialize a new Connections object.
CpuCreditsEnumProvides the options for specifying the CPU credit type for burstable EC2 instance types (T2, T3, T3a, etc).
CpuManufacturerEnumCPU manufacturers supported by EC2 instances.
CreateIpv6CidrBlocksRequestStructRequest for IPv6 CIDR block to be split up.
DefaultInstanceTenancyEnumThe default tenancy of instances launched into the VPC.
DestinationOptionsStructOptions for writing logs to a destination.
EbsDeviceOptionsStructBlock device options for an EBS volume.
EbsDeviceOptionsBaseStructBase block device options for an EBS volume.
EbsDevicePropsStructProperties of an EBS block device.
EbsDeviceSnapshotOptionsStructBlock device options for an EBS volume created from a snapshot.
EbsDeviceVolumeTypeEnumSupported EBS volume types for blockDevices.
EgressRuleConfigStructConfiguration for an egress security group rule.
EnableVpnGatewayOptionsStructOptions for the Vpc.enableVpnGateway() method.
ExecuteFileOptionsStructOptions when executing a file.
FlowLogDestinationClassThe destination type for the flow log.
FlowLogDestinationConfigStructFlow Log Destination configuration.
FlowLogDestinationTypeEnumThe available destination types for Flow Logs.
FlowLogFileFormatEnumThe file format for flow logs written to an S3 bucket destination.
FlowLogMaxAggregationIntervalEnumThe maximum interval of time during which a flow of packets is captured and aggregated into a flow log record.
FlowLogOptionsStructOptions to add a flow log to a VPC.
FlowLogPropsStructProperties of a VPC Flow Log.
FlowLogResourceTypeClassThe type of resource to create the flow log for.
FlowLogTrafficTypeEnumThe type of VPC traffic to log.
GatewayConfigStructPair represents a gateway created by NAT Provider.
GatewayVpcEndpointAwsServiceClassAn AWS service for a gateway VPC endpoint.
GatewayVpcEndpointOptionsStructOptions to add a gateway endpoint to a VPC.
GatewayVpcEndpointPropsStructConstruction properties for a GatewayVpcEndpoint.
GenericLinuxImageClassConstruct a Linux machine image from an AMI map.
GenericLinuxImagePropsStructConfiguration options for GenericLinuxImage.
GenericSSMParameterImageClassSelect the image based on a given SSM parameter at deployment time of the CloudFormation Stack.
GenericWindowsImageClassConstruct a Windows machine image from an AMI map.
GenericWindowsImagePropsStructConfiguration options for GenericWindowsImage.
HttpTokensEnumThe state of token usage for your instance metadata requests.
IClientVpnConnectionHandlerInterfaceA connection handler for client VPN endpoints.
IClientVpnEndpointInterfaceA client VPN endpoint.
IConnectableInterfaceAn object that has a Connections object.
IFlowLogInterfaceA FlowLog.
IGatewayVpcEndpointInterfaceA gateway VPC endpoint.
IGatewayVpcEndpointServiceInterfaceA service for a gateway VPC endpoint.
IInstanceInterface
IInterfaceVpcEndpointInterfaceAn interface VPC endpoint.
IInterfaceVpcEndpointServiceInterfaceA service for an interface VPC endpoint.
IIpAddressesInterfaceImplementations for ip address management.
IIpv6AddressesInterfaceImplementations for IPv6 address management.
IKeyPairInterfaceAn EC2 Key Pair.
ILaunchTemplateInterfaceInterface for LaunchTemplate-like objects.
IMachineImageInterfaceInterface for classes that can select an appropriate machine image to use.
INetworkAclInterfaceA NetworkAcl.
INetworkAclEntryInterfaceA NetworkAclEntry.
IngressRuleConfigStructConfiguration for an ingress security group rule.
InitCommandClassCommand to execute on the instance.
InitCommandOptionsStructOptions for InitCommand.
InitCommandWaitDurationClassRepresents a duration to wait after a command has finished, in case of a reboot (Windows only).
InitConfigClassA collection of configuration elements.
InitElementClassBase class for all CloudFormation Init elements.
InitFileClassCreate files on the EC2 instance.
InitFileAssetOptionsStructAdditional options for creating an InitFile from an asset.
InitFileOptionsStructOptions for InitFile.
InitGroupClassCreate Linux/UNIX groups and assign group IDs.
InitPackageClassA package to be installed during cfn-init time.
InitServiceClassA services that be enabled, disabled or restarted when the instance is launched.
InitServiceOptionsStructOptions for an InitService.
InitServiceRestartHandleClassAn object that represents reasons to restart an InitService.
InitSourceClassExtract an archive into a directory.
InitSourceAssetOptionsStructAdditional options for an InitSource that builds an asset from local files.
InitSourceOptionsStructAdditional options for an InitSource.
InitUserClassCreate Linux/UNIX users and to assign user IDs.
InitUserOptionsStructOptional parameters used when creating a user.
InstanceArchitectureEnumIdentifies an instance's CPU architecture.
InstanceClassEnumWhat class and generation of instance to use.
InstanceGenerationEnumInstance generation categories for EC2.
InstanceInitiatedShutdownBehaviorEnumProvides the options for specifying the instance initiated shutdown behavior.
InstancePropsStructProperties of an EC2 Instance.
InstanceRequireImdsv2AspectClassAspect that applies IMDS configuration on EC2 Instance constructs.
InstanceRequireImdsv2AspectPropsStructProperties for InstanceRequireImdsv2Aspect.
InstanceRequirementsConfigStructThe attributes for the instance types for a mixed instances policy.
InstanceSizeEnumWhat size of instance to use.
InstanceTypeClassInstance type for EC2 instances.
InterfaceVpcEndpointAttributesStructConstruction properties for an ImportedInterfaceVpcEndpoint.
InterfaceVpcEndpointAwsServiceClassAn AWS service for an interface VPC endpoint.
InterfaceVpcEndpointAwsServicePropsStructOptional properties for the InterfaceVpcEndpointAwsService class.
InterfaceVpcEndpointOptionsStructOptions to add an interface endpoint to a VPC.
InterfaceVpcEndpointPropsStructConstruction properties for an InterfaceVpcEndpoint.
InterfaceVpcEndpointServiceClassA custom-hosted service for an interface VPC endpoint.
IpAddressesClassAn abstract Provider of IpAddresses.
IpAddressTypeEnumIP address types supported for VPC endpoint service.
IPeerInterfaceInterface for classes that provide the peer-specification parts of a security group rule.
IPlacementGroupInterfaceDetermines where your instances are placed on the underlying hardware according to the specified PlacementGroupStrategy.
IpProtocolEnumThe types of IP addresses provisioned in the VPC.
IPrefixListInterfaceA prefix list.
IPrivateSubnetInterface
IPublicSubnetInterface
Ipv6AddressesClassAn abstract Provider of Ipv6Addresses.
IRouteTableInterfaceAn abstract route table.
ISecurityGroupInterfaceInterface for security group-like objects.
ISubnetInterface
ISubnetNetworkAclAssociationInterfaceA SubnetNetworkAclAssociation.
IVolumeInterfaceAn EBS Volume in AWS EC2.
IVpcInterface
IVpcEndpointInterfaceA VPC endpoint.
IVpcEndpointServiceInterfaceA VPC endpoint service.
IVpcEndpointServiceLoadBalancerInterfaceA load balancer that can host a VPC Endpoint Service.
IVpnConnectionInterface
IVpnGatewayInterfaceThe virtual private gateway interface.
KeyPairAttributesStructAttributes of a Key Pair.
KeyPairFormatEnumThe format of the Key Pair.
KeyPairPropsStructThe properties of a Key Pair.
KeyPairTypeEnumThe type of the key pair.
LaunchTemplateAttributesStructAttributes for an imported LaunchTemplate.
LaunchTemplateCpuOptionsStructThe CPU options for the instance.
LaunchTemplateHttpTokensEnumThe state of token usage for your instance metadata requests.
LaunchTemplatePropsStructProperties of a LaunchTemplate.
LaunchTemplateRequireImdsv2AspectClassAspect that applies IMDS configuration on EC2 Launch Template constructs.
LaunchTemplateRequireImdsv2AspectPropsStructProperties for LaunchTemplateRequireImdsv2Aspect.
LaunchTemplateSpecialVersionsClassA class that provides convenient access to special version tokens for LaunchTemplate versions.
LaunchTemplateSpotOptionsStructInterface for the Spot market instance options provided in a LaunchTemplate.
LinuxUserDataOptionsStructOptions when constructing UserData for Linux.
LocalStorageEnumLocal storage support requirements for EC2 instances.
LocalStorageTypeEnumTypes of local storage available for EC2 instances.
LocationPackageOptionsStructOptions for InitPackage.rpm/InitPackage.msi.
LogFormatClassThe following table describes all of the available fields for a flow log record.
LookupMachineImageClassA machine image whose AMI ID will be searched using DescribeImages.
LookupMachineImagePropsStructProperties for looking up an image.
MachineImageClassFactory functions for standard Amazon Machine Image objects.
MachineImageConfigStructConfiguration for a machine image.
MultipartBodyClassThe base class for all classes which can be used as MultipartUserData.
MultipartBodyOptionsStructOptions when creating MultipartBody.
MultipartUserDataClassMime multipart user data.
MultipartUserDataOptionsStructOptions for creating MultipartUserData.
NamedPackageOptionsStructOptions for InitPackage.yum/apt/rubyGem/python.
NatGatewayPropsStructProperties for a NAT gateway.
NatGatewayProviderClassProvider for NAT Gateways.
NatInstanceImageClassMachine image representing the latest NAT instance image.
NatInstancePropsStructProperties for a NAT instance.
NatInstanceProviderClassNAT provider which uses NAT Instances.
NatInstanceProviderV2ClassModern NAT provider which uses NAT Instances.
NatProviderClassNAT providers.
NatTrafficDirectionEnumDirection of traffic to allow all by default.
NetworkAclEntryPropsStructProperties to create NetworkAclEntry.
NetworkAclPropsStructProperties to create NetworkAcl.
OperatingSystemTypeEnumThe OS type of a particular image.
PeerClassPeer object factories (to be used in Security Group management).
PlacementGroupPropsStructProps for a PlacementGroup.
PlacementGroupSpreadLevelEnumDetermines how this placement group spreads instances.
PlacementGroupStrategyEnumWhich strategy to use when launching instances.
PortClassInterface for classes that provide the connection-specification parts of a security group rule.
PortPropsStructProperties to create a port range.
PrefixListLookupOptionsStructProperties for looking up an existing managed prefix list.
PrefixListOptionsStructOptions to add a prefix list.
PrefixListPropsStructProperties for creating a prefix list.
PrivateSubnetAttributesStruct
PrivateSubnetPropsStruct
ProtocolEnumProtocol for use in Connection Rules.
PublicSubnetAttributesStruct
PublicSubnetPropsStruct
RegionalNatGatewayProviderClassProvider for Regional NAT Gateways.
RegionalNatGatewayProviderPropsStructProperties for a Regional NAT Gateway Provider.
RequestedSubnetStructSubnet requested for allocation.
ResolveSsmParameterAtLaunchImageClassSelect the image based on a given SSM parameter at instance launch time.
RouterTypeEnumType of router used in route.
RuleConfigStructCommon configuration properties shared by ingress and egress security group rules.
RuleScopeStructThe scope and id in which a given SecurityGroup rule should be defined.
S3DestinationOptionsStructOptions for writing logs to a S3 destination.
S3DownloadOptionsStructOptions when downloading files from S3.
SecurityGroupImportOptionsStructAdditional options for imported security groups.
SecurityGroupPropsStruct
SelectedSubnetsStructResult of selecting a subset of subnets from a VPC.
ServiceManagerEnumThe service manager that will be used by InitServices.
SpotInstanceInterruptionEnumProvides the options for the types of interruption for spot instances.
SpotRequestTypeEnumThe Spot Instance request type.
SsmParameterImageOptionsStructProperties for GenericSsmParameterImage.
SubnetAttributesStruct
SubnetConfigurationStructSpecify configuration parameters for a single subnet group in a VPC.
SubnetFilterClassContains logic which chooses a set of subnets from a larger list, in conjunction with SubnetSelection, to determine where to place AWS resources such as VPC endpoints, EC2 instances, etc.
SubnetIpamOptionsStructCIDR Allocated Subnets.
SubnetNetworkAclAssociationPropsStructProperties to create a SubnetNetworkAclAssociation.
SubnetPropsStructSpecify configuration parameters for a VPC subnet.
SubnetSelectionStructCustomize subnets that are selected for placement of ENIs.
SubnetTypeEnumThe type of Subnet.
SystemdConfigFileOptionsStructOptions for creating a SystemD configuration file.
TrafficDirectionEnumDirection of traffic the AclEntry applies to.
TransportProtocolEnumTransport protocol for client VPN.
UserDataClassInstance User Data.
VolumeAttributesStructAttributes required to import an existing EBS Volume into the Stack.
VolumePropsStructProperties of an EBS Volume.
VpcAttributesStructProperties that reference an external Vpc.
VpcEndpointDnsRecordIpTypeEnumEnums for all Dns Record IP Address types.
VpcEndpointIpAddressTypeEnumIP address type for the endpoint.
VpcEndpointPrivateDnsOnlyForInboundResolverEndpointEnumIndicates whether to enable private DNS only for inbound endpoints.
VpcEndpointServicePropsStructConstruction properties for a VpcEndpointService.
VpcEndpointTypeEnumThe type of VPC endpoint.
VpcIpamOptionsStructCIDR Allocated Vpc.
VpcLookupOptionsStructProperties for looking up an existing VPC.
VpcPropsStructConfiguration for Vpc.
VpnConnectionAttributesStructAttributes of an imported VpnConnection.
VpnConnectionOptionsStruct
VpnConnectionPropsStruct
VpnConnectionTypeEnumThe VPN connection type.
VpnGatewayPropsStructThe VpnGateway Properties.
VpnPortEnumPort for client VPN.
VpnTunnelOptionStruct
WindowsImageClassSelect the latest version of the indicated Windows version.
WindowsImagePropsStructConfiguration options for WindowsImage.
WindowsUserDataOptionsStructOptions when constructing UserData for Windows.
WindowsVersionEnumThe Windows version to use for the WindowsImage.