From 95c49abdfa4ad77a0c0fcb82a230778dcc2ea59a Mon Sep 17 00:00:00 2001 From: Shikha Aggarwal Date: Mon, 16 Sep 2024 17:09:48 -0700 Subject: [PATCH] fix(ec2): fixing vpc endpoint pattern for ecr and ecr docker (#31434) ### Issue # (if applicable) Closes #. Internal Tracking ticket P150271569 ### Reason for this change Expected Endpoints for ECR in some isolated regions are as below gov.ic.hci.csp.us-isof-name.ecr.api, gov.ic.hci.csp.us-isof-name.ecr.dkr, uk.adc-e.cloud.eu-isoe-name.ecr.api, uk.adc-e.cloud.eu-isoe-name.ecr.dkr, ### Description of changes As discussed with the ECR Service team, endpoints for the service are being generated in reverse order of the domain suffix. Since some of the endpoints for other services are still using `com.amazonaws` , added fix only for the partitions and service(ECR) flagged. Cannot do for cn regions on the basis of suffix as both regions have different services under exceptions. ### Description of how you validated changes Added unit test for validation of endpoint, keeping the region names as `us-isoe-test-1` as the regions are in build stage and could be confidential. No changes to integration test as the fix is for isolated regions. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts | 16 +++++++++- .../aws-ec2/test/vpc-endpoint.test.ts | 31 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts index d186d00987317..7e3cedf219e09 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts @@ -9,6 +9,7 @@ import { ISubnet, IVpc, SubnetSelection } from './vpc'; import * as iam from '../../aws-iam'; import * as cxschema from '../../cloud-assembly-schema'; import { Aws, ContextProvider, IResource, Lazy, Resource, Stack, Token } from '../../core'; +import { PARTITION_MAP } from '../../region-info/build-tools/fact-tables'; /** * A VPC endpoint. @@ -666,8 +667,21 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ 'redshift', 'redshift-data', 's3', 'sagemaker.api', 'sagemaker.featurestore-runtime', 'sagemaker.runtime', 'securityhub', 'servicecatalog', 'sms', 'sqs', 'states', 'sts', 'sync-states', 'synthetics', 'transcribe', 'transcribestreaming', 'transfer', 'workspaces', 'xray'], + 'us-isof-': ['ecr.api', 'ecr.dkr'], + 'eu-isoe-': ['ecr.api', 'ecr.dkr'], }; - if (VPC_ENDPOINT_SERVICE_EXCEPTIONS[region]?.includes(name)) { + + const regionPartition = region.split('-').slice(0, 2).join('-'); + const partitionDetails = PARTITION_MAP[`${regionPartition}-`]; + + // Check for specific service name under isolated region prefix + const serviceInExceptions = VPC_ENDPOINT_SERVICE_EXCEPTIONS[`${regionPartition}-`]?.includes(name); + + if (serviceInExceptions) { + // Endpoints generated in reverse of domain suffix for the services mentioned in map + const reverseString = partitionDetails.domainSuffix.split('.').reverse().join('.'); + return reverseString; + } else if (VPC_ENDPOINT_SERVICE_EXCEPTIONS[region]?.includes(name)) { return 'cn.com.amazonaws'; } else { return 'com.amazonaws'; diff --git a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts index 3c1c05ba8dfa8..2e9ae880d7147 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts @@ -694,6 +694,37 @@ describe('vpc endpoint', () => { }); }); + + test.each([ + ['us-isof-test-1', 'gov.ic.hci.csp'], + ['eu-isoe-test-1', 'uk.adc-e.cloud'], + ['us-east-1', 'com.amazonaws'], + ['us-gov-west-1', 'com.amazonaws'], + ['cn-northwest-1', 'cn.com.amazonaws'], + ['cn-north-1', 'cn.com.amazonaws'], + ])('test vpc interface endpoint for ECR can be created correctly in all regions', (region : string, domain: string) => { + //GIVEN + const stack = new Stack(undefined, 'TestStack', { env: { account: '123456789012', region: region } }); + const vpc = new Vpc(stack, 'VPC'); + + //WHEN + vpc.addInterfaceEndpoint('ECR Endpoint', { + service: InterfaceVpcEndpointAwsService.ECR, + }); + + vpc.addInterfaceEndpoint('ECR Docker Endpoint', { + service: InterfaceVpcEndpointAwsService.ECR_DOCKER, + }); + + //THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { + ServiceName: `${domain}.${region}.ecr.api`, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { + ServiceName: `${domain}.${region}.ecr.dkr`, + }); + }); + test.each([ ['transcribe', InterfaceVpcEndpointAwsService.TRANSCRIBE], ])('test vpc interface endpoint with .cn suffix for %s can be created correctly in China regions', (name: string, given: InterfaceVpcEndpointAwsService) => {