amazon-web-servicesamazon-vpcvpc-endpoint

How can I lookup an existing VPC Endpoint Service in CDK?


I know there is a way to lookup an existing VPC or VPC Endpoint

But, is there a way to look up a VPC Endpoint Service in CDK?

I need to find out the availability zones of an existing VPC Endpoint Service.


Solution

  • I couldn't find a way to do it, so I had to rely on AwsCustomResources to

        import * as ec2 from 'aws-cdk-lib/aws-ec2'
        import * as custom_resources from 'aws-cdk-lib/custom-resources'
    
        // Custom resource is needed to call the AWS DescribeVpcEndpointServices API in order to retrieve the
        // public availability zones associated with the VPC Endpoint
        //
        // "Sometimes a single API call can fill the gap in the CloudFormation coverage. In this case you can use the AwsCustomResource construct. 
        // This construct creates a custom resource that can be customized to make specific API calls for the CREATE, UPDATE and DELETE events. 
        // Additionally, data returned by the API call can be extracted and used in other constructs/resources (creating a real CloudFormation 
        // dependency using Fn::GetAtt under the hood)."
        // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html#custom-resources-for-aws-apis
        const vpcEndpointAvailabilityZonesApi: custom_resources.AwsCustomResource = new custom_resources.AwsCustomResource(
          this,
          "DescribeVpcEndpointServices",
          {
            onCreate: {
              service: "EC2",
              action: "describeVpcEndpointServices",
              parameters: {
                ServiceNames: ["com.amazonaws.vpce.us-east-1.vpce-svc-yourIDhere"]
              },
              physicalResourceId: custom_resources.PhysicalResourceId.of(Date.now().toString()),
            },
            onUpdate: {
              service: "EC2",
              action: "describeVpcEndpointServices",
              parameters: {
                ServiceNames: ["com.amazonaws.vpce.us-east-1.vpce-svc-yourIDhere"]
              },
              physicalResourceId: custom_resources.PhysicalResourceId.of(Date.now().toString()),
            },
            policy: {
              statements: [
                new iam.PolicyStatement({
                  actions: ["ec2:DescribeVpcEndpointServices"],
                  resources: ["*"],
                }),
              ],
            },
            functionName: "DescribeVpcEndpointServices"
          }
        );
    
        // "By default, a VPC will spread over at most 3 Availability Zones available to it."
        // https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2-readme.html#control-over-availability-zones
        const vpcEndpointServiceAZs :string[] = [];
        for (let i = 0; i < 3; i++) {
          vpcEndpointServiceAZs.push(vpcEndpointAvailabilityZonesApi.getResponseField(`ServiceDetails.0.AvailabilityZones.${i}`))    
        }
    

    I couldn't lookup an existing Endpoint Service, so I had to create two AwsCustomResource calls, put one in each stack, and then create resources there.

    I ended up having to split my CDK into two stacks, one with the VPC and one passing the VPC object to a secondary dependent stack. Note, this is the VPC object reference (ec2.Vpc), not the VPC ID. Using fromLookup will not work, since the ID is not determined until deploy-time, not build time.

    As for the DescribeVpcEndpointServices call, you had to fix the number of AZs, since it is not possible to pre-determine the number from a variable. For most VPCs though, it's going to be three by default.