diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json index a2959b87dace7..2921e274cb47f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json @@ -15,7 +15,7 @@ } } }, - "49f55568b1de8f0ec44db71fc2e7c08688d282144bc748c1c765eef1e15c6587": { + "7a1854851df3529c0aedf5714ba9cb2bf3309619b0b6e7a5ae6d1b7449e89594": { "displayName": "aws-cdk-ec2-lt-metadata-1 Template", "source": { "path": "aws-cdk-ec2-lt-metadata-1.template.json", @@ -24,7 +24,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "49f55568b1de8f0ec44db71fc2e7c08688d282144bc748c1c765eef1e15c6587.json", + "objectKey": "7a1854851df3529c0aedf5714ba9cb2bf3309619b0b6e7a5ae6d1b7449e89594.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json index 4e7e651ce158c..dc09805c95890 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json @@ -336,6 +336,56 @@ } ] } + }, + "LTWithNetworkInterfacesC793C8F4": { + "Type": "AWS::EC2::LaunchTemplate", + "Properties": { + "LaunchTemplateData": { + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": false, + "DeleteOnTermination": true, + "DeviceIndex": 0 + }, + { + "AssociatePublicIpAddress": false, + "DeleteOnTermination": true, + "DeviceIndex": 1 + } + ], + "TagSpecifications": [ + { + "ResourceType": "instance", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces" + } + ] + }, + { + "ResourceType": "volume", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces" + } + ] + } + ] + }, + "TagSpecifications": [ + { + "ResourceType": "launch-template", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces" + } + ] + } + ] + } } }, "Mappings": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json index 6fd682c8e9c9a..af2b3b94d7a00 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/49f55568b1de8f0ec44db71fc2e7c08688d282144bc748c1c765eef1e15c6587.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7a1854851df3529c0aedf5714ba9cb2bf3309619b0b6e7a5ae6d1b7449e89594.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -193,6 +193,18 @@ "data": "LTWithPlacementGroup4B40027C" } ], + "/aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces": [ + { + "type": "aws:cdk:analytics:construct", + "data": {} + } + ], + "/aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LTWithNetworkInterfacesC793C8F4" + } + ], "/aws-cdk-ec2-lt-metadata-1/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json index 965e427424314..d13b19536192f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json @@ -1 +1 @@ -{"version":"tree-0.1","tree":{"id":"App","path":"","children":{"aws-cdk-ec2-lt-metadata-1":{"id":"aws-cdk-ec2-lt-metadata-1","path":"aws-cdk-ec2-lt-metadata-1","children":{"MyVpc":{"id":"MyVpc","path":"aws-cdk-ec2-lt-metadata-1/MyVpc","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::VPC","aws:cdk:cloudformation:props":{"cidrBlock":"10.0.0.0/16","enableDnsHostnames":true,"enableDnsSupport":true,"instanceTenancy":"default","tags":[{"key":"Name","value":"MyVpc"}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnVPC","version":"0.0.0"}},"RestrictDefaultSecurityGroupCustomResource":{"id":"RestrictDefaultSecurityGroupCustomResource","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource","children":{"Default":{"id":"Default","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource/Default","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.CustomResource","version":"0.0.0","metadata":["*"]}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.Vpc","version":"0.0.0","metadata":[{"vpcName":"*","subnetConfiguration":[]}]}},"LatestNodeRuntimeMap":{"id":"LatestNodeRuntimeMap","path":"aws-cdk-ec2-lt-metadata-1/LatestNodeRuntimeMap","constructInfo":{"fqn":"aws-cdk-lib.CfnMapping","version":"0.0.0"}},"Custom::VpcRestrictDefaultSGCustomResourceProvider":{"id":"Custom::VpcRestrictDefaultSGCustomResourceProvider","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider","children":{"Staging":{"id":"Staging","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"Role":{"id":"Role","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Handler":{"id":"Handler","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.CustomResourceProviderBase","version":"0.0.0"}},"sg1":{"id":"sg1","path":"aws-cdk-ec2-lt-metadata-1/sg1","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/sg1/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::SecurityGroup","aws:cdk:cloudformation:props":{"groupDescription":"aws-cdk-ec2-lt-metadata-1/sg1","securityGroupEgress":[{"cidrIp":"0.0.0.0/0","description":"Allow all outbound traffic by default","ipProtocol":"-1"}],"vpcId":{"Ref":"MyVpcF9F0CA6F"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnSecurityGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.SecurityGroup","version":"0.0.0","metadata":[{"vpc":"*"}]}},"LT":{"id":"LT","path":"aws-cdk-ec2-lt-metadata-1/LT","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LT/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"blockDeviceMappings":[{"deviceName":"/dev/xvda","ebs":{"volumeSize":15,"throughput":250,"volumeType":"gp3"}}],"securityGroupIds":[{"Fn::GetAtt":["sg15CEFF4E3","GroupId"]},{"Fn::GetAtt":["sg2860DD91F","GroupId"]}],"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]}],"metadataOptions":{"httpEndpoint":"enabled","httpProtocolIpv6":"enabled","httpPutResponseHopLimit":2,"httpTokens":"required","instanceMetadataTags":"enabled"}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]}],"versionDescription":"test template v1"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"versionDescription":"*","httpEndpoint":true,"httpProtocolIpv6":true,"httpPutResponseHopLimit":"*","httpTokens":"required","instanceMetadataTags":true,"securityGroup":"*","blockDevices":[{"deviceName":"*","volume":"*"}]},{"addSecurityGroup":["*"]}]}},"sg2":{"id":"sg2","path":"aws-cdk-ec2-lt-metadata-1/sg2","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/sg2/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::SecurityGroup","aws:cdk:cloudformation:props":{"groupDescription":"aws-cdk-ec2-lt-metadata-1/sg2","securityGroupEgress":[{"cidrIp":"0.0.0.0/0","description":"Allow all outbound traffic by default","ipProtocol":"-1"}],"vpcId":{"Ref":"MyVpcF9F0CA6F"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnSecurityGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.SecurityGroup","version":"0.0.0","metadata":[{"vpc":"*"}]}},"LTWithMachineImage":{"id":"LTWithMachineImage","path":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"imageId":{"Ref":"SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter"},"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]}],"userData":{"Fn::Base64":"#!/bin/bash"}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"machineImage":"*"}]}},"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter":{"id":"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter","path":"aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118":{"id":"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118","path":"aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":[]}},"pg":{"id":"pg","path":"aws-cdk-ec2-lt-metadata-1/pg","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/pg/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::PlacementGroup","aws:cdk:cloudformation:props":{"strategy":"spread"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnPlacementGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.PlacementGroup","version":"0.0.0","metadata":[{}]}},"LTWithPlacementGroup":{"id":"LTWithPlacementGroup","path":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]}],"placement":{"groupName":{"Fn::GetAtt":["pg749EE6ED","GroupName"]}}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"placementGroup":"*"}]}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-ec2-lt-metadata-1/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-ec2-lt-metadata-1/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"}},"LambdaTest":{"id":"LambdaTest","path":"LambdaTest","children":{"DefaultTest":{"id":"DefaultTest","path":"LambdaTest/DefaultTest","children":{"Default":{"id":"Default","path":"LambdaTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"LambdaTest/DefaultTest/DeployAssert","children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"LambdaTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"}}} \ No newline at end of file +{"version":"tree-0.1","tree":{"id":"App","path":"","children":{"aws-cdk-ec2-lt-metadata-1":{"id":"aws-cdk-ec2-lt-metadata-1","path":"aws-cdk-ec2-lt-metadata-1","children":{"MyVpc":{"id":"MyVpc","path":"aws-cdk-ec2-lt-metadata-1/MyVpc","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::VPC","aws:cdk:cloudformation:props":{"cidrBlock":"10.0.0.0/16","enableDnsHostnames":true,"enableDnsSupport":true,"instanceTenancy":"default","tags":[{"key":"Name","value":"MyVpc"}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnVPC","version":"0.0.0"}},"RestrictDefaultSecurityGroupCustomResource":{"id":"RestrictDefaultSecurityGroupCustomResource","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource","children":{"Default":{"id":"Default","path":"aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource/Default","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.CustomResource","version":"0.0.0","metadata":["*"]}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.Vpc","version":"0.0.0","metadata":[{"vpcName":"*","subnetConfiguration":[]}]}},"LatestNodeRuntimeMap":{"id":"LatestNodeRuntimeMap","path":"aws-cdk-ec2-lt-metadata-1/LatestNodeRuntimeMap","constructInfo":{"fqn":"aws-cdk-lib.CfnMapping","version":"0.0.0"}},"Custom::VpcRestrictDefaultSGCustomResourceProvider":{"id":"Custom::VpcRestrictDefaultSGCustomResourceProvider","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider","children":{"Staging":{"id":"Staging","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging","constructInfo":{"fqn":"aws-cdk-lib.AssetStaging","version":"0.0.0"}},"Role":{"id":"Role","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}},"Handler":{"id":"Handler","path":"aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.CustomResourceProviderBase","version":"0.0.0"}},"sg1":{"id":"sg1","path":"aws-cdk-ec2-lt-metadata-1/sg1","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/sg1/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::SecurityGroup","aws:cdk:cloudformation:props":{"groupDescription":"aws-cdk-ec2-lt-metadata-1/sg1","securityGroupEgress":[{"cidrIp":"0.0.0.0/0","description":"Allow all outbound traffic by default","ipProtocol":"-1"}],"vpcId":{"Ref":"MyVpcF9F0CA6F"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnSecurityGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.SecurityGroup","version":"0.0.0","metadata":[{"vpc":"*"}]}},"LT":{"id":"LT","path":"aws-cdk-ec2-lt-metadata-1/LT","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LT/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"blockDeviceMappings":[{"deviceName":"/dev/xvda","ebs":{"volumeSize":15,"throughput":250,"volumeType":"gp3"}}],"securityGroupIds":[{"Fn::GetAtt":["sg15CEFF4E3","GroupId"]},{"Fn::GetAtt":["sg2860DD91F","GroupId"]}],"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]}],"metadataOptions":{"httpEndpoint":"enabled","httpProtocolIpv6":"enabled","httpPutResponseHopLimit":2,"httpTokens":"required","instanceMetadataTags":"enabled"}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LT"}]}],"versionDescription":"test template v1"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"versionDescription":"*","httpEndpoint":true,"httpProtocolIpv6":true,"httpPutResponseHopLimit":"*","httpTokens":"required","instanceMetadataTags":true,"securityGroup":"*","blockDevices":[{"deviceName":"*","volume":"*"}]},{"addSecurityGroup":["*"]}]}},"sg2":{"id":"sg2","path":"aws-cdk-ec2-lt-metadata-1/sg2","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/sg2/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::SecurityGroup","aws:cdk:cloudformation:props":{"groupDescription":"aws-cdk-ec2-lt-metadata-1/sg2","securityGroupEgress":[{"cidrIp":"0.0.0.0/0","description":"Allow all outbound traffic by default","ipProtocol":"-1"}],"vpcId":{"Ref":"MyVpcF9F0CA6F"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnSecurityGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.SecurityGroup","version":"0.0.0","metadata":[{"vpc":"*"}]}},"LTWithMachineImage":{"id":"LTWithMachineImage","path":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"imageId":{"Ref":"SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter"},"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]}],"userData":{"Fn::Base64":"#!/bin/bash"}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithMachineImage"}]}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"machineImage":"*"}]}},"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter":{"id":"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter","path":"aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118":{"id":"SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118","path":"aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118","constructInfo":{"fqn":"aws-cdk-lib.Resource","version":"0.0.0","metadata":[]}},"pg":{"id":"pg","path":"aws-cdk-ec2-lt-metadata-1/pg","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/pg/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::PlacementGroup","aws:cdk:cloudformation:props":{"strategy":"spread"}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnPlacementGroup","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.PlacementGroup","version":"0.0.0","metadata":[{}]}},"LTWithPlacementGroup":{"id":"LTWithPlacementGroup","path":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]}],"placement":{"groupName":{"Fn::GetAtt":["pg749EE6ED","GroupName"]}}},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithPlacementGroup"}]}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{"placementGroup":"*"}]}},"LTWithNetworkInterfaces":{"id":"LTWithNetworkInterfaces","path":"aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces","children":{"Resource":{"id":"Resource","path":"aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces/Resource","attributes":{"aws:cdk:cloudformation:type":"AWS::EC2::LaunchTemplate","aws:cdk:cloudformation:props":{"launchTemplateData":{"tagSpecifications":[{"resourceType":"instance","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces"}]},{"resourceType":"volume","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces"}]}],"networkInterfaces":[{"associatePublicIpAddress":false,"deviceIndex":0,"deleteOnTermination":true},{"associatePublicIpAddress":false,"deviceIndex":1,"deleteOnTermination":true}]},"tagSpecifications":[{"resourceType":"launch-template","tags":[{"key":"Name","value":"aws-cdk-ec2-lt-metadata-1/LTWithNetworkInterfaces"}]}]}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.CfnLaunchTemplate","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.aws_ec2.LaunchTemplate","version":"0.0.0","metadata":[{}]}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-ec2-lt-metadata-1/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-ec2-lt-metadata-1/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"}},"LambdaTest":{"id":"LambdaTest","path":"LambdaTest","children":{"DefaultTest":{"id":"DefaultTest","path":"LambdaTest/DefaultTest","children":{"Default":{"id":"Default","path":"LambdaTest/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"LambdaTest/DefaultTest/DeployAssert","children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"LambdaTest/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"}}},"constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts index 0a42c7d9f6ed5..63dfb4af13dbb 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts @@ -52,6 +52,13 @@ new ec2.LaunchTemplate(stack, 'LTWithPlacementGroup', { placementGroup: pg, }); +new ec2.LaunchTemplate(stack, 'LTWithNetworkInterfaces', { + networkInterfaces: [ + { associatePublicIpAddress: false, deviceIndex: 0, deleteOnTermination: true }, + { associatePublicIpAddress: false, deviceIndex: 1, deleteOnTermination: true }, + ], +}); + new integ.IntegTest(app, 'LambdaTest', { testCases: [stack], diffAssets: true, diff --git a/packages/aws-cdk-lib/aws-ec2/README.md b/packages/aws-cdk-lib/aws-ec2/README.md index 114c1f38731b8..83368898ef643 100644 --- a/packages/aws-cdk-lib/aws-ec2/README.md +++ b/packages/aws-cdk-lib/aws-ec2/README.md @@ -2479,6 +2479,35 @@ const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplate', { }); ``` +Following demonstrates how to add multiple network interface cards 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, +}); + +new ec2.LaunchTemplate(this, 'LaunchTemplate', { + machineImage: ec2.MachineImage.latestAmazonLinux2023(), + networkInterfaces: [ + { + associatePublicIpAddress: false, + deviceIndex: 0, + groups: [sg1], + }, + { + associatePublicIpAddress: false, + deviceIndex: 1, + groups: [sg2], + }, + ], +}); +``` + ### Placement Group Specify `placementGroup` to enable the placement group support: diff --git a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts index 3545d734c731a..1cbd51bf9b404 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts @@ -9,6 +9,7 @@ import { launchTemplateBlockDeviceMappings } from './private/ebs-util'; import { ISecurityGroup } from './security-group'; import { UserData } from './user-data'; import { BlockDevice } from './volume'; +import { ISubnet } from './vpc'; import * as iam from '../../aws-iam'; import { Annotations, @@ -71,6 +72,207 @@ export enum InstanceInitiatedShutdownBehavior { TERMINATE = 'terminate', } +/** + * InterfaceType + */ +export enum InterfaceType { + /** + * efa + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html + */ + EFA = 'efa', + + /** + * interface + */ + INTERFACE = 'interface', +} + +/** + * A security group connection tracking specification that enables you to set the idle timeout for connection tracking on an Elastic network interface. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html#connection-tracking-timeouts + */ +export interface ConnectionTrackingSpecification extends CfnLaunchTemplate.ConnectionTrackingSpecificationProperty {} + +/** + * ENA 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. + * + * With ENA Express, you can communicate between two EC2 instances in the same subnet within the same account, or in different accounts. Both sending and receiving instances must have ENA Express enabled. + * + * To improve the reliability of network packet delivery, ENA Express reorders network packets on the receiving end by default. However, some UDP-based applications are designed to handle network packets that are out of order to reduce the overhead for packet delivery at the network layer. When ENA Express is enabled, you can specify whether UDP network traffic uses it. + */ +export interface EnaSrdSpecification + extends CfnLaunchTemplate.EnaSrdSpecificationProperty { } + +/** + * Specifies an IPv6 address in an Amazon EC2 launch template. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html + */ +export interface Ipv6Add extends CfnLaunchTemplate.Ipv6AddProperty { } + +/** + * Specifies a secondary private IPv4 address for a network interface. + */ +export interface PrivateIpAdd extends CfnLaunchTemplate.PrivateIpAddProperty { } + +/** + * Specifies the parameters for a Launch Template network interface definition. + */ +export interface NetworkInterface { + /** + * Associates a Carrier IP address with eth0 for a new network interface. + * + * Use this option when you launch an instance in a Wavelength Zone and want to associate a Carrier IP address with the network interface. For more information about Carrier IP addresses, see Carrier IP addresses in the AWS Wavelength Developer Guide. + * + * @default No carrier IP address is assigned + */ + readonly associateCarrierIpAddress?: boolean; + + /** + * Associates a public IPv4 address with eth0 for a new network interface. Note that when multiple network interface cards are defined, this value must be `false` on all of them. + * + * @default No public IPv4 address is assigned + */ + readonly associatePublicIpAddress?: boolean; + + /** + * A connection tracking specification for the network interface. + * + * @default Default connection tracking timeouts are used. + * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html#connection-tracking-timeouts + */ + readonly connectionTrackingSpecification?: ConnectionTrackingSpecification; + + /** + * Indicates whether the network interface is deleted when the instance is terminated. + * + * @default The network interface is deleted when the instance is terminated. + */ + readonly deleteOnTermination?: boolean; + + /** + * A description for the network interface. + * + * @default An empty string. + */ + readonly description?: string; + + /** + * The device index for the network interface attachment. + * + * @default Index is `0` + */ + readonly deviceIndex: number; + + /** + * The ENA Express configuration for the network interface. + * + * @default EnaSrd is not enabled + */ + readonly enaSrdSpecification?: EnaSrdSpecification; + + /** + * One or more security groups to attach to the interface. + * + * @default No security groups are attached to the interface. + */ + readonly groups?: ISecurityGroup[]; + + /** + * The type of network interface. To create an Elastic Fabric Adapter (EFA), specify `InterfaceType.efa`. For more information, see Elastic Fabric Adapter in the Amazon Elastic Compute Cloud User Guide. + * + * @default Interface type is `InterfaceType.INTERFACE`. + */ + readonly interfaceType?: InterfaceType; + + /** + * The number of IPv4 prefixes to be automatically assigned to the network interface. You cannot use this option if you use the Ipv4Prefix option. + * + * @default One prefix is assigned + */ + readonly ipv4PrefixCount?: number; + + /** + * One or more IPv4 prefixes to be assigned to the network interface. You cannot use this option if you use the Ipv4PrefixCount option. + * + * @default A single prefix is assigned via `ipv4PrefixCount` + */ + readonly ipv4Prefixes?: string[]; + + /** + * The number of IPv6 addresses to assign to a network interface. Amazon EC2 automatically selects the IPv6 addresses from the subnet range. You can't use this option if specifying specific IPv6 addresses. + * + * @default No IPv6 addresses are assigned. + */ + readonly ipv6AddressCount?: number; + + /** + * One or more specific IPv6 addresses from the IPv6 CIDR block range of your subnet. You can't use this option if you're specifying a number of IPv6 addresses. + * + * @default No IPv6 addresses are assigned. + */ + readonly ipv6Addresses?: Ipv6Add[]; + + /** + * The number of IPv6 prefixes to be automatically assigned to the network interface. You cannot use this option if you use the Ipv6Prefix option. + * + * @default No prefixes are assigned. + */ + readonly ipv6PrefixCount?: number; + + /** + * One or more IPv6 prefixes to be assigned to the network interface. You cannot use this option if you use the Ipv6PrefixCount option. + * + * @default No prefixes are assigned. + */ + readonly ipv6Prefixes?: string[]; + + /** + * The index of the network card. Some instance types support multiple network cards. The primary network interface must be assigned to network card index 0. The default is network card index 0. + * + * @default First network interface card gets assigned index `0`. + */ + readonly networkCardIndex?: number; + + /** + * The primary IPv6 address of the network interface. When you enable an IPv6 GUA address to be a primary IPv6, the first IPv6 GUA will be made the primary IPv6 address until the instance is terminated or the network interface is detached. For more information about primary IPv6 addresses, see RunInstances. + * + * @default First IPv6 address is made primary. + */ + readonly primaryIpv6?: boolean; + + /** + * The primary private IPv4 address of the network interface. + * + * @default An IP address is automatically assigned from one of the subnets. + */ + readonly privateIpAddress?: string; + + /** + * One or more private IPv4 addresses. + * + * @default An IP address is automatically assigned from one of the subnets. + */ + readonly privateIpAddresses?: PrivateIpAdd[]; + + /** + * The number of secondary private IPv4 addresses to assign to a network interface. + * + * @default No secondary addresses are assigned + */ + readonly secondaryPrivateIpAddressCount?: number; + + /** + * List of subnets to which to place the interface in + * + * @default No subnets are defined. + */ + readonly subnet?: ISubnet; +} + /** * Interface for LaunchTemplate-like objects. */ @@ -450,6 +652,15 @@ export interface LaunchTemplateProps { * @default - no placement group will be used for this launch template. */ readonly placementGroup?: IPlacementGroup; + + /** + * Network interface definitions for the EC2 instances. + * + * Note: If defined, overrides settings `associatePublicIpAddress` and `securityGroup`. + * + * @default: A single network interface using `associatePublicIpAddress` and `securityGroup`is created + */ + readonly networkInterfaces?: NetworkInterface[]; } /** @@ -623,6 +834,13 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr Annotations.of(this).addError('HttpPutResponseHopLimit must between 1 and 64'); } + // Basic validation of the provided network interface cards + if (props.networkInterfaces && props.networkInterfaces.length > 1) { + if (!props.networkInterfaces.every((nic) => !nic.associatePublicIpAddress)) { + Annotations.of(this).addError('associatePublicIpAddress must be `false` or `undefined` when defining multiple network interfaces'); + } + } + if (props.instanceProfile && props.role) { throw new ValidationError('You cannot provide both an instanceProfile and a role', this); } @@ -701,7 +919,7 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr }, }; // Remove SpotOptions if there are none. - if (Object.keys(marketOptions.spotOptions).filter(k => marketOptions.spotOptions[k]).length == 0) { + if (Object.keys(marketOptions.spotOptions).filter((k) => marketOptions.spotOptions[k]).length == 0) { marketOptions.spotOptions = undefined; } } @@ -712,7 +930,7 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr produce: () => { if (this.tags.hasTags()) { const renderedTags = this.tags.renderTags(); - const lowerCaseRenderedTags = renderedTags.map( (tag: { [key: string]: string}) => { + const lowerCaseRenderedTags = renderedTags.map((tag: { [key: string]: string }) => { return { key: tag.Key, value: tag.Value, @@ -737,7 +955,7 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr produce: () => { if (this.tags.hasTags()) { const renderedTags = this.tags.renderTags(); - const lowerCaseRenderedTags = renderedTags.map( (tag: { [key: string]: string}) => { + const lowerCaseRenderedTags = renderedTags.map((tag: { [key: string]: string }) => { return { key: tag.Key, value: tag.Value, @@ -754,9 +972,27 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr }, }); - const networkInterfaces = props.associatePublicIpAddress !== undefined - ? [{ deviceIndex: 0, associatePublicIpAddress: props.associatePublicIpAddress, groups: securityGroupsToken }] - : undefined; + const networkInterfaces = props.networkInterfaces ?? ( + props.associatePublicIpAddress !== undefined + ? [{ + deviceIndex: 0, + associatePublicIpAddress: props.associatePublicIpAddress, + groups: props.securityGroup ? [props.securityGroup] : undefined, + }] + : undefined + ); + + if ( props.versionDescription && !Token.isUnresolved(props.versionDescription) && props.versionDescription.length > 255) { + throw new ValidationError(`versionDescription must be less than or equal to 255 characters, got ${props.versionDescription.length}`, this ); + } + + if ( + props.versionDescription && + !Token.isUnresolved(props.versionDescription) && + props.versionDescription.length > 255 + ) { + throw new ValidationError(`versionDescription must be less than or equal to 255 characters, got ${props.versionDescription.length}`, this ); + } if (props.versionDescription && !Token.isUnresolved(props.versionDescription) && props.versionDescription.length > 255) { throw new ValidationError(`versionDescription must be less than or equal to 255 characters, got ${props.versionDescription.length}`, this); @@ -791,7 +1027,7 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr tagSpecifications: tagsToken, userData: userDataToken, metadataOptions: this.renderMetadataOptions(props), - networkInterfaces, + networkInterfaces: networkInterfaces ? this.synthesizeNetworkInterfaces(networkInterfaces) : undefined, placement: props.placementGroup ? { groupName: props.placementGroup.placementGroupName, } : undefined, @@ -826,7 +1062,6 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr // CDK only has placement groups, not placement. // Specifiying options other than placementGroup is not supported yet. // placement: undefined, - }, tagSpecifications: ltTagsToken, }); @@ -845,6 +1080,20 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr this.versionNumber = Token.asString(resource.getAtt('LatestVersionNumber')); } + private synthesizeNetworkInterfaces( + networkInterfaces: NetworkInterface[], + ): CfnLaunchTemplate.NetworkInterfaceProperty[] { + return networkInterfaces.map((networkInterface) => { + return { + ...networkInterface, + ipv4Prefixes: networkInterface.ipv4Prefixes?.map(p => ({ ipv4Prefix: p })), + ipv6Prefixes: networkInterface.ipv6Prefixes?.map(p => ({ ipv6Prefix: p })), + groups: networkInterface.groups?.map((sg) => sg.securityGroupId), + subnetId: networkInterface.subnet?.subnetId, + }; + }); + } + private renderMetadataOptions(props: LaunchTemplateProps) { let requireMetadataOptions = false; // if requireImdsv2 is true, httpTokens must be required.