简体   繁体   English

AWS CDK 部署失败:指定的 API 标识符无效

[英]AWS CDK Deployment fails: Invalid API identifier specified

I am trying to add a new Route and Integration to my existing REST API in AWS API Gateway.我正在尝试在 AWS API 网关中向我现有的 REST API 添加新的路由和集成。 I am using the below code snippet to make it happen:我正在使用下面的代码片段来实现它:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export interface IApiGatewayIntegrationProps extends cdk.StackProps {
  /**
   * Application Name. Will be used to name all the resources
   */
  appName: string;

  /**
   * Route name to add the API Gateway Integration onto.
   * For example: setting `admin` for admin-api, the invocation url will be `${apiGatewayInvocationUrl}/admin`
   */
  apiPath: string;

  /**
   * REST API ID for an existing API
   */
  restApiId: string;

  /**
   * ID for the root resource in the API
   */
  restApiRootResourceId: string;

  /**
   * VPC Link ID
   */
  VpcLink: string;

  /**
   * URL for the Network Load Balancer (NLB)
   */
  NLBDns: string;

  /**
   * Listener port on the NLB
   */
  NLBPort: number;
}

export class CustomApiGatewayIntegration extends Construct {
  constructor(scope: Construct, id: string, props: IApiGatewayIntegrationProps) {
    super(scope, id);

    const api = cdk.aws_apigateway.RestApi.fromRestApiAttributes(scope, 'api', {
      restApiId: props.restApiId,
      rootResourceId: props.restApiRootResourceId,
    });

    const proxyIntegration = new cdk.aws_apigatewayv2.CfnIntegration(this, 'gateway-integration', {
      apiId: api.restApiId,
      connectionId: props.VpcLink,
      connectionType: 'VPC_LINK',
      description: 'API Integration',
      integrationMethod: 'ANY',
      integrationType: 'HTTP_PROXY',
      integrationUri: `http://${props.NLBDns}:${props.NLBPort}/${props.apiPath}/{proxy}`,
    });

    new cdk.aws_apigatewayv2.CfnRoute(this, 'gateway-route', {
      apiId: api.restApiId,
      routeKey: 'ANY somepath/{proxy+}',
      target: `integrations/${proxyIntegration.ref}`,
    });
  }
}

After deploying the CDK Stack, I get the following error in the terminal:部署 CDK 堆栈后,我在终端中收到以下错误:

failed: Error: The stack named $STACK_NAME failed to deploy: UPDATE_ROLLBACK_COMPLETE: Invalid API identifier specified $AWS_ACCOUNT_ID:$REST_API_ID

终端中的错误消息

This is how the error looks in the Cloudformation console:这是错误在 Cloudformation 控制台中的外观:

Cloudformation 控制台中的错误消息

The interesting bit here is that the error message shows the AWS Account ID in addition to the Actual API ID.这里有趣的是,除了实际的 API ID 之外,错误消息还显示了 AWS 账户 ID。 How do I resolve this?我该如何解决这个问题?

Appreciate any help on this!感谢您对此的任何帮助! Thanks in advance提前致谢

Edit 1: apigateway import means how the API Gateway class methods are imported.编辑 1: apigateway import表示如何导入 API 网关 class 方法。 AWS Cloudformation has two Resource Groups: AWS Cloudformation 有两个资源组:

  • AWS::APIGateway AWS::API网关
  • AWS::APIGatewayV2 AWS::APIGatewayV2

Both of them have different capabilities.两者都有不同的能力。 In older versions of the AWS CDK (v1.x), you had to import both the resource groups separately:在旧版本的 AWS CDK (v1.x) 中,您必须分别导入两个资源组:

Old: import * as apigateway from '@aws-cdk/aws-api-gateway';旧: import * as apigateway from '@aws-cdk/aws-api-gateway';

New: import * as apigatewayv2 from '@aws-cdk/aws-api-gatewayv2';新: import * as apigatewayv2 from '@aws-cdk/aws-api-gatewayv2';

The newer CDK has brought everything together and can be written simply as:较新的 CDK 将所有内容整合在一起,可以简单地写成:

import * as cdk from 'aws-cdk-lib';

// Call to v1 Resource Group:
const api = new cdk.aws_apigateway.RestApi(...);

// Call to v2 Resources:
const apiv2 = new cdk.aws_apigatewayv2.CfnRestApi(...);

I checked the cloudformation UI Console to trace the stack update and found that the Cfn Template generated by the ApiGatewayV2 Module was appending the Account Id in front of the API Id.我检查了 cloudformation UI Console 以跟踪堆栈更新,发现 ApiGatewayV2 模块生成的 Cfn 模板在 API Id 前面附加了 Account Id。

So I stopped using it and continued using the main CDK Import for API Gateway.所以我停止使用它并继续使用 API 网关的主 CDK 导入。 Below is the code snippet that worked.下面是有效的代码片段。 I also had to manipulate a private variable for API Gateway Stage Deployment.我还必须为 API 网关阶段部署操作一个私有变量。

// ...

export class CustomApiGatewayIntegration extends constructs.Construct {
  constructor(scope: constructs.Construct, id: string, props: IApiGatewayIntegrationProps) {
    super(scope, id);

    const api = cdk.aws_apigateway.RestApi.fromRestApiAttributes(scope, 'api', {
      restApiId: props.restApiId,
      rootResourceId: props.restApiRootResourceId,
    });

    const vpcLink = cdk.aws_apigateway.VpcLink.fromVpcLinkId(this, 'vpc-link', props.VpcLink);

    const gatewayResource = api.root.addResource(props.apiPath);

    const endpoint = `http://${props.NLBDns}:${props.NLBPort}/${props.apiPath}`;

    const proxyResource = gatewayResource.addProxy({
      anyMethod: true,
      defaultIntegration: new cdk.aws_apigateway.Integration({
        type: cdk.aws_apigateway.IntegrationType.HTTP_PROXY,
        integrationHttpMethod: 'ANY',
        uri: `${endpoint}/{proxy}`,
        options: {
          vpcLink,
          connectionType: cdk.aws_apigateway.ConnectionType.VPC_LINK,
        },
      })
    });

    const deployment = new cdk.aws_apigateway.Deployment(this, 'api-deployment-' + new Date().toISOString(), { api });
    
    // Private member manipulation
    (deployment as any).resource.stageName = 'api';

    // Forcing dependency of deployment on the `proxyResource`
    // for sequential deployment in cloudformation
    deployment.node.addDependency(proxyResource);

    new CfnOutput(this, 'ServiceEndpoint', {
      value: endpoint,
      description: `Endpoint for ${props.appName} microservice`,
      exportName: `${props.org}-${props.environment}-service-endpoint`
    });
  }
}

// ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM