Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

Closed
vhryshchenko-source opened this issue Jun 10, 2024 · 4 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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

2 participants