理解 Apigateway 和 AWS cloudformation 上的嵌套堆栈时出错

Error understanding Apigateway and nested stack on AWS cloudformation

我正在努力将一个大模板与使用 api 网关 AWS 的 lambda 分离。我解决了有关嵌套堆栈过程的多个错误,但目前错误尚不清楚。你能检查定义中的问题是什么吗?

主堆栈显示来自 api 子堆栈创建的一般错误,但 api-子堆栈显示下一个错误:

Template error: instance of Fn::Sub references invalid resource attribute CreateCatalogFunctionDev.Arn

接下来展示一段模板代码:

主模板

  SubStackAPIDev:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      TemplateURL: https://s3.awsroute.com/substack-api.yaml
      TimeoutInMinutes: 5      
      Parameters:
        CreateCatalogFunctionDev: !GetAtt CreateCatalogFunctionDev.Outputs.CreateCatalogFunctionDev
      
      
  SubStackCreateCatalogDev:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      TemplateURL: https://s3.awsroute.com/substack-create-catalog.yaml
      TimeoutInMinutes: 5
      Parameters:
        APIDev: !GetAtt SubStackAPIDev.Outputs.APIGateway

SubStackCreateCatalogDev

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Description: >
  SAM template for create catalog


Parameters:
  SecretsManagerName:
    Type: String
    Description: "Secrets Manager Name"
  SnsTopicArn:
    Type: String
    Default: arn:aws:sns:us-west-2:XXXXXX:SNS-errorNotification
    Description: "Sns topic error handler email notification"
  APIDev:
    Type: AWS::Serverless::Api
    
Resources:
  LayerDev:
    Type: 'AWS::Serverless::LayerVersion'
    Properties:
      ContentUri: ../../layer
      CompatibleRuntimes:
        - python3.6
        - python3.7
        - python3.8
      RetentionPolicy: Delete
  CreateCatalogFunctionDev:
    Type: AWS::Serverless::Function
    Properties:
      Description: Recieve api request and and process data.
      CodeUri: ../../src/catalog/create_catalog/
      Handler: create_catalog.lambda_handler
      Runtime: python3.8
      FunctionName: CreateCatalogFunctionDev
      Role: arn:aws:iam::XXXXXXXX:role/lambda-essential-role
      Timeout: 480
      Environment:
        Variables:
          CREATE_CATALOG_SECRET_NAME: !Sub '${SecretsManagerName}'
          SNS_ARN: !Sub '${SnsTopicArn}'
      Layers:
        - arn:aws:lambda:us-west-2:XXXXXXX:layer:requests:1
        - arn:aws:lambda:us-west-2:XXXXXXX:layer:requests-oauthlib:1
        - !Ref LayerDev
      Events:
        CreateCatalogApiEvent:
          Type: Api
          Properties:
            Path: /api-channel/products/catalog
            Method: POST
            RestApiId: !Ref APIDev

子堆栈API

AWSTemplateFormatVersion: "2010-09-09"

Transform: AWS::Serverless-2016-10-31

Description: >
  sub_channels_appi
   SAM template for API

Parameters:
  SwaggerFile:
    Type: String
    # TODO dejar URL de S3 de gitla-cicd
    Default: "s3://cf-templates-1hurrmgzyzoz3-ap-northeast-1/swagger_dev.yaml"
    Description: "This swagger file Amazon S3 path"
  SecretsManagerName:
    Type: String
    Default: "/channels/Dev"
    Description: "Secrets Manager Name"
  StageName:
    Type: String
    Default: "${stageVariables.alias}"
    Description: "This is the alias to the swagger file"
  UsaSupplyApiUrlDev:
    Type: String
    Default: "https://thecornercloud.com/developers/index.php/"
    Description: "Corner Cloud Staging"
  SnsTopicArn:
    Type: String
    Default: arn:aws:sns:us-west-2:000365055762:channels-errorNotification
    Description: "Sns topic error handler email notification"
  CreateCatalogFunctionDev:
    Type: String

Resources:
  #######################################
  # Serverless LayerVersion
  #######################################
  LayerDev:
    Type: 'AWS::Serverless::LayerVersion'
    Properties:
      ContentUri: ../../layer
      CompatibleRuntimes:
        - python3.6
        - python3.7
        - python3.8
      RetentionPolicy: Delete

  #######################################
  # Serverless API
  #######################################
  APIDev:
    Type: AWS::Serverless::Api
    Properties:
      Auth:
        ApiKeyRequired: true
      StageName: dev
      EndpointConfiguration: REGIONAL
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: !Ref SwaggerFile
      Variables:
        alias: dev

  #######################################
  # ApiGateway ApiKey
  #######################################
  APIKeyDev:
    Type: AWS::ApiGateway::ApiKey
    Properties:
      Name: "APIKeyDev"
      Description: "API Key Dev"
      Enabled: true
      GenerateDistinctId: false
      StageKeys:
        - RestApiId: !Ref APIDev
          StageName: !Ref APIDev.Stage

  #######################################
  # ApiGateway UsagePlan
  #######################################
  APIUsagePlanDev:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn: APIDev
    Properties:
      ApiStages:
        - ApiId: !Ref APIDev
          Stage: !Ref APIDev.Stage
      Quota:
        Limit: 5000
        Period: MONTH
      Throttle:
        BurstLimit: 200
        RateLimit: 100
      UsagePlanName: APIUsagePlanDev
  #######################################
  # ApiGateway UsagePlanKey
  #######################################
  APIUsagePlanKeyDev:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref APIKeyDev
      KeyType: API_KEY
      UsagePlanId: !Ref APIUsagePlanDev

  #######################################
  # ApiGateway Deployment
  #######################################
  DeploymentApiIdDev:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId: !Ref APIDev 
Outputs:

  APIGateway:
    Description: "API Gateway Reference"
    Value: !Ref APIDev
    Export:
      Name: !Join [":", [!Ref "AWS::StackName", "APIDev"]]

最后是 swagger 文件(老实说,我没有用这种方法定义 api 并且认为如果可能的话我想删除 swagger)。 swagger-dev

swagger: "2.0"
info:
  version: "1.0.0"
  title: "APIDev"
tags:
  - name: "Channels"
    description: "Manage Channels process."
schemes:
  - "https"
x-amazon-apigateway-api-key-source: "HEADER"
securityDefinitions:
  APIKey:
    type: apiKey
    name: X-Api-Key
    in: header 
paths:
  /channels/products/catalog:
    post:
      tags:
        - "Channels"
      summary: " products catalog post."
      operationId: "ProductsCatalogPostDev"
      produces:
        - "application/json"
      responses:
        201:
          description: "Successful Operation"
        400:
          description: "Invalid parameters"
        401:
          description: "Unauthorized"
        405:
          description: "Validation exception"
      security:
        - APIKey: []
      x-amazon-apigateway-integration:
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CreateCatalogFunctionDev.Arn}/invocations
        responses:
          default:
            statusCode: "200"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
        contentHandling: "CONVERT_TO_TEXT"
        type: "aws_proxy"

您的 CreateCatalogFunctionDevAPIDev 不同的子堆栈中 。您不能直接跨堆栈引用资源。您要么必须 export/import 他们的输出,要么将引用作为输入参数传递。