Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ec2: Unable to use imported interface VPC endpoint in another stack #30507

Closed
vhryshchenko-source opened this issue Jun 10, 2024 · 5 comments
Closed
Labels
@aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud bug This issue is a bug. closing-soon This issue will automatically close in 4 days unless further comments are made. effort/small Small work item – less than a day of effort p3 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@vhryshchenko-source
Copy link

vhryshchenko-source commented Jun 10, 2024

Describe the bug

I am using two stacks. In one of them, I import the VPC endpoint if it already exists, and if not, I create a new one. Then I create a new stack in which I want to deploy a Private API Gateway, which needs to be provided with the VPC endpoint.

vps-stack.ts

    export class VpcStack extends Stack {

    public readonly vpc: aws_ec2.IVpc;
    public readonly executeApiEndpoint: aws_ec2.IVpcEndpoint;
    public readonly subnets: aws_ec2.ISubnet[];

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

        // Lookup an existing VPC using its VPC ID from the configuration.
        this.vpc = aws_ec2.Vpc.fromLookup(this, 'vpc', {
            vpcId: additionalProps.VpcId
        })

        let executeApiEndpoint: aws_ec2.IVpcEndpoint;

        if (buildconfig.ExecuteApiEndpointId) {
        executeApiEndpoint = aws_ec2.InterfaceVpcEndpoint.fromInterfaceVpcEndpointAttributes(this, `vpc`, {
            vpcEndpointId: additionalProps.ExecuteApiEndpointId,
            port: 443
        });
        } else {
            ///Create VPC endpoint
        }

        this.executeApiEndpoint = executeApiEndpoint;

bin/app.ts

 const stack1 = new VpcStack(app, 'Stack-1', {
    description: 'Stack-1',
  },
  additionalProps
 );

 const stack2 = new ApplicationStack(app, 'Stack-2', {
    description: "Satck-2",
    vpc: stack1.vpc,
    subnets: stack1.subnets,
    executeApiEndpoint: stack1.executeApiEndpoint,
  }
  additionalProps
 );

application-stack.ts (api gateway part)

        this.restApiGateway = new apigateway.RestApi(this, 'RestApi', {
            restApiName: props.apiGatewayName,
            policy: policyDocument,
            endpointConfiguration: {
                types: [apigateway.EndpointType.PRIVATE],
                vpcEndpoints: [props.executeApiEndpoint]
            }

The problem is that if I import the resource from the same stack where the API Gateway is created, everything works, but if these are different stacks, I get an error.
Error:

./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1
"use strict";var _a,_b,_c;Object.defineProperty(exports,"__esModule",{value:!0}),exports.EndpointType=exports.ApiKeySourceType=exports.RestApi=exports.SpecRestApi=exports.RestApiBase=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var api_key_1=()=>{var tmp=require("./api-key");return api_key_1=()=>tmp,tmp},apigateway_canned_metrics_generated_1=()=>{var tmp=require("./apigateway ...........
**TypeError: Cannot read properties of undefined (reading 'vpcEndpointId')**
    at ./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1:9674
    at Array.map (<anonymous>)
    at RestApi._configureEndpoints (./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1:9645)

CDK synth fine If i will import VPC endpoint in the same stack, like in this the way:

 let executeApiEndpoint: aws_ec2.IVpcEndpoint;

  if (buildconfig.ExecuteApiEndpointId) {
  executeApiEndpoint = aws_ec2.InterfaceVpcEndpoint.fromInterfaceVpcEndpointAttributes(this, `vpc`, {
      vpcEndpointId: additionalProps.ExecuteApiEndpointId,
      port: 443
  });
  } else {
      ///Create VPC endpoint
  }
    this.restApiGateway = new apigateway.RestApi(this, 'RestApi', {
        restApiName: props.apiGatewayName,
        policy: policyDocument,
        endpointConfiguration: {
            types: [apigateway.EndpointType.PRIVATE],
            vpcEndpoints: [executeApiEndpoint]
        }

Expected Behavior

Import interface VPC endpoint in one Stack and use it for Private API Gateway in another stack should work.

Current Behavior

The problem is that if I import the resource from the same stack where the API Gateway is created, everything works, but if these are different stacks, I get an error.
Error:

./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1
"use strict";var _a,_b,_c;Object.defineProperty(exports,"__esModule",{value:!0}),exports.EndpointType=exports.ApiKeySourceType=exports.RestApi=exports.SpecRestApi=exports.RestApiBase=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var api_key_1=()=>{var tmp=require("./api-key");return api_key_1=()=>tmp,tmp},apigateway_canned_metrics_generated_1=()=>{var tmp=require("./apigateway ...........
**TypeError: Cannot read properties of undefined (reading 'vpcEndpointId')**
    at ./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1:9674
    at Array.map (<anonymous>)
    at RestApi._configureEndpoints (./node_modules/aws-cdk-lib/aws-apigateway/lib/restapi.js:1:9645)

Reproduction Steps

Create two stacks.
First contain

executeApiEndpoint = aws_ec2.InterfaceVpcEndpoint.fromInterfaceVpcEndpointAttributes(this, `vpc`, {
            vpcEndpointId: additionalProps.ExecuteApiEndpointId,
            port: 443
        });

Second contain

        this.restApiGateway = new apigateway.RestApi(this, 'RestApi', {
            restApiName: props.apiGatewayName,
            policy: policyDocument,
            endpointConfiguration: {
                types: [apigateway.EndpointType.PRIVATE],
                vpcEndpoints: [props.executeApiEndpoint]
            }

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.145.0

Framework Version

No response

Node.js Version

v22.2.0

OS

Mac

Language

TypeScript

Language Version

No response

Other information

No response

@vhryshchenko-source vhryshchenko-source added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jun 10, 2024
@github-actions github-actions bot added the @aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud label Jun 10, 2024
@pahud
Copy link
Contributor

pahud commented Jun 13, 2024

I tried to simplify your provided code snippet and this works for me

stack.ts

export class Stack1 extends Stack {
  public readonly executeApiEndpoint: ec2.IInterfaceVpcEndpoint;
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    this.executeApiEndpoint = ec2.InterfaceVpcEndpoint.fromInterfaceVpcEndpointAttributes(this, `vpc`, {
      vpcEndpointId: 'dummy-id',
      port: 443
    });

  }
}

export interface Stack2Props extends StackProps {
  readonly executeApiEndpoint: ec2.IInterfaceVpcEndpoint;
}

export class Stack2 extends Stack {
  constructor(scope: Construct, id: string, props: Stack2Props) {
    super(scope, id, props);

    const api = new apigateway.RestApi(this, 'RestApi', {
      restApiName: 'dummy-name',
      endpointConfiguration: {
          types: [apigateway.EndpointType.PRIVATE],
          vpcEndpoints: [props.executeApiEndpoint]
      },
    });

    api.root.addMethod('GET');
  }
}

app.ts

const stack1 = new Stack1(app, 'stack1');
new Stack2(app, 'stack2', {
    executeApiEndpoint: stack1.executeApiEndpoint,
});

cdk diff

Resources
[+] AWS::ApiGateway::RestApi RestApi RestApi0C43BF4B 
[+] AWS::ApiGateway::Deployment RestApi/Deployment RestApiDeployment180EC5031e179fa89b23406b04ad2558c7819850 
[+] AWS::ApiGateway::Stage RestApi/DeploymentStage.prod RestApiDeploymentStageprod3855DE66 
[+] AWS::ApiGateway::Method RestApi/Default/GET RestApiGET0F59260B 

@pahud pahud added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p3 effort/small Small work item – less than a day of effort and removed needs-triage This issue or PR still needs to be triaged. labels Jun 13, 2024
Copy link

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added the closing-soon This issue will automatically close in 4 days unless further comments are made. label Jun 15, 2024
@vhryshchenko-source
Copy link
Author

I created stacks from scratch and it seems that everything really works, maybe I missed something somewhere. I'm closing the issue.

Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@aws-cdk-automation
Copy link
Collaborator

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

@aws aws locked as resolved and limited conversation to collaborators Jul 25, 2024
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
@aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud bug This issue is a bug. closing-soon This issue will automatically close in 4 days unless further comments are made. effort/small Small work item – less than a day of effort p3 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

3 participants