@@ -10,12 +10,20 @@ import {
1010import {
1111 CfnSubnet ,
1212 FlowLogDestination ,
13+ GatewayVpcEndpoint ,
14+ InterfaceVpcEndpoint ,
15+ InterfaceVpcEndpointAwsService ,
1316 IpAddresses ,
17+ IVpcEndpoint ,
18+ Peer ,
1419 Vpc
1520} from "aws-cdk-lib/aws-ec2"
1621import { Role , ServicePrincipal } from "aws-cdk-lib/aws-iam"
1722import { Key } from "aws-cdk-lib/aws-kms"
1823import { LogGroup } from "aws-cdk-lib/aws-logs"
24+ import { AwsCustomResource , AwsCustomResourcePolicy , PhysicalResourceId } from "aws-cdk-lib/custom-resources"
25+
26+ import { nagSuppressions } from "../nagSuppressions"
1927
2028export interface VpcResourcesStackProps extends StackProps {
2129 readonly version : string
@@ -28,6 +36,7 @@ export interface VpcResourcesStackProps extends StackProps{
2836 */
2937
3038export class VpcResourcesStack extends Stack {
39+ readonly vpc : Vpc
3140 public constructor ( scope : App , id : string , props : VpcResourcesStackProps ) {
3241 super ( scope , id , props )
3342
@@ -87,6 +96,19 @@ export class VpcResourcesStack extends Stack {
8796 }
8897 }
8998
99+ this . vpc = vpc
100+
101+ // add vpc private endpoints - needed to run ECS in private subnet
102+ // copied from https://stackoverflow.com/a/69578964/9294145
103+ this . addInterfaceEndpoint ( "ECRDockerEndpoint" , InterfaceVpcEndpointAwsService . ECR_DOCKER )
104+ this . addInterfaceEndpoint ( "ECREndpoint" , InterfaceVpcEndpointAwsService . ECR )
105+ this . addInterfaceEndpoint ( "SecretManagerEndpoint" , InterfaceVpcEndpointAwsService . SECRETS_MANAGER )
106+ this . addInterfaceEndpoint ( "CloudWatchEndpoint" , InterfaceVpcEndpointAwsService . CLOUDWATCH_MONITORING )
107+ this . addInterfaceEndpoint ( "CloudWatchLogsEndpoint" , InterfaceVpcEndpointAwsService . CLOUDWATCH_LOGS )
108+ this . addInterfaceEndpoint ( "CloudWatchEventsEndpoint" , InterfaceVpcEndpointAwsService . EVENTBRIDGE )
109+ this . addInterfaceEndpoint ( "SSMEndpoint" , InterfaceVpcEndpointAwsService . SSM )
110+ this . addGatewayEndpoint ( "S3Endpoint" , InterfaceVpcEndpointAwsService . S3 )
111+
90112 //Outputs
91113
92114 //Exports
@@ -106,7 +128,7 @@ export class VpcResourcesStack extends Stack {
106128 }
107129
108130 let privateSubnetIds = [ ]
109- for ( const [ i , subnet ] of vpc . publicSubnets . entries ( ) ) {
131+ for ( const [ i , subnet ] of vpc . privateSubnets . entries ( ) ) {
110132 const subnetIdentifier = String . fromCharCode ( "A" . charCodeAt ( 0 ) + i )
111133 new CfnOutput ( this , `PrivateSubnet${ subnetIdentifier } ` , {
112134 value : subnet . subnetId ,
@@ -125,5 +147,52 @@ export class VpcResourcesStack extends Stack {
125147 exportName : `${ props . stackName } :PrivateSubnets`
126148 } )
127149
150+ nagSuppressions ( this )
151+
152+ }
153+
154+ private addInterfaceEndpoint ( name : string , awsService : InterfaceVpcEndpointAwsService ) : void {
155+ const endpoint : InterfaceVpcEndpoint = this . vpc . addInterfaceEndpoint ( name , {
156+ service : awsService
157+ } )
158+ this . addEndpointTag ( name , endpoint )
159+
160+ endpoint . connections . allowFrom ( Peer . ipv4 ( this . vpc . vpcCidrBlock ) , endpoint . connections . defaultPort ! )
128161 }
162+
163+ private addGatewayEndpoint ( name : string , awsService : InterfaceVpcEndpointAwsService ) : void {
164+ const endpoint : GatewayVpcEndpoint = this . vpc . addGatewayEndpoint ( name , {
165+ service : awsService
166+ } )
167+ this . addEndpointTag ( name , endpoint )
168+ }
169+
170+ private addEndpointTag ( name : string , endpoint : IVpcEndpoint ) {
171+ // vpc endpoints do not support tagging from cdk/cloudformation
172+ // so use a custom resource to add them in
173+ new AwsCustomResource ( this , `${ name } -tags` , {
174+ installLatestAwsSdk : false ,
175+ onUpdate : {
176+ action : "createTags" ,
177+ parameters : {
178+ Resources : [
179+ endpoint . vpcEndpointId
180+ ] ,
181+ Tags : [
182+ {
183+ Key : "Name" ,
184+ Value : `${ this . stackName } -${ name } `
185+ }
186+ ]
187+ } ,
188+ physicalResourceId : PhysicalResourceId . of ( Date . now ( ) . toString ( ) ) ,
189+ service : "EC2"
190+ } ,
191+ policy : AwsCustomResourcePolicy . fromSdkCalls ( {
192+ resources : AwsCustomResourcePolicy . ANY_RESOURCE
193+ } )
194+ } )
195+
196+ }
197+
129198}
0 commit comments