AWS:为什么我无法将自定义域分配给嵌套堆栈? [英] AWS: Why I am unable to assign a custom domain to the nested stack?

查看:21
本文介绍了AWS:为什么我无法将自定义域分配给嵌套堆栈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将自定义域集成到 HTTP API 我正在使用 AWS API GatewayAWS Lambda 进行开发.我正在使用 AWS SAM 模板.我有一个根堆栈和嵌套堆栈.

I am trying to integrate a custom domain to the HTTP API I am developing with AWS API Gateway and AWS Lambda. I m using the AWS SAM template. There I have a root stack and nested stacks.

对于这个问题,我将使用一个嵌套堆栈的代码片段.在那里,这就是我希望 URL 端点的样子

For this question I will use a code piece with a one nested stack. There, this is how I want the URL end points to be

  1. 根堆栈 - api.example.com
  2. 嵌套堆栈 - api.example.com/nested

下面是我的代码

根堆栈

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  aws-restapi

  Sample SAM Template for aws-restapi
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5
    VpcConfig:
        SecurityGroupIds:
          - sg-041f24xxxx921e8e
        SubnetIds:
          - subnet-0xxxxx2d


Parameters:
  FirebaseProjectId:
    Type: String
  
  #Dont create this domain in the AWS Console manually, so it will fail here
  DomainName:
    Type: String
    Default: api.example.com

Resources:
  AuthGatewayHttpApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      Domain:
        DomainName: !Ref DomainName
        EndpointConfiguration: REGIONAL
        CertificateArn: arn:aws:acm:us-east-1:xxxx:certificate/xxxx-420d-xxxx-b40d-xxxx
        Route53:
          HostedZoneId: xxxxxxxxxxx
      Auth:
        Authorizers:
          FirebaseAuthorizer:
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - !Ref FirebaseProjectId
              issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
        DefaultAuthorizer: FirebaseAuthorizer

 
  AuthFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: aws-restapi/
      Handler: source/testfile.lambdaHandler
      Runtime: nodejs14.x
      Events:
        Gateway:
          Type: HttpApi
          Properties:
            ApiId: !Ref AuthGatewayHttpApi
            Path: /hello
            Method: get

  NestedStackTwo:
    DependsOn: AuthGatewayHttpApi
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: nested_stack.yaml
      Parameters:
        FirebaseProjectId: !Ref FirebaseProjectId
        DomainName: !Ref DomainName

嵌套堆栈

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  aws-restapi

  Sample SAM Template for aws-restapi

Globals:
  Function:
    Timeout: 5
    VpcConfig:
        SecurityGroupIds:
          - sg-xxxxxxxxxxxx
        SubnetIds:
          - subnet-xxxxxxxxxxx

Parameters:
  FirebaseProjectId:
    Type: String
  
  DomainName:
    Type: String

Resources:

  AuthGatewayHttpApi2:
    Type: AWS::Serverless::HttpApi
    Properties:
      Domain:
        DomainName: !Ref DomainName
        BasePath: two
        EndpointConfiguration: REGIONAL
        CertificateArn: arn:aws:acm:us-east-1:xxxxx:certificate/xxxxx-xxxx-xxxx-xxxx-xxxx
        Route53:
          HostedZoneId: xxxxxxxxxxxxx
      Auth:
        Authorizers:
          FirebaseAuthorizer:
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - !Ref FirebaseProjectId
              issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
        DefaultAuthorizer: FirebaseAuthorizer

  GetAllPromotionsFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: aws-restapi/
      Handler: source/promotions/promotions-getall.getAllPromotions
      Runtime: nodejs14.x
      Events:
        GetAllPromotionsAPIEvent:
          Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /promotions/getall
            Method: get
            ApiId: !Ref AuthGatewayHttpApi2
  

但是我无法让它工作,因为嵌套堆栈无法创建.以下是错误

However I cant get this to work because the nested stack fails to create. Below is the error

CREATE_FAILED                      AWS::CloudFormation::Stack         NestedStackTwo
                                                    

Embedded stack arn:aws:cloudformation:us-east-1 xxxxx:stack/aws-restapi-NestedStackTwo-8KBISZRAVYBX/a3fcc010-0ce4-11ec-9c90-0e8a861a6983 was not successfully created:

 The following resource(s) failed to create: [ApiGatewayDomainNameV234ac706a57] 

我相信这是因为根堆栈创建了域,而嵌套堆栈试图重新创建它而不是重复使用它.

I believe this is happening because the root stack creates the domain and the nested stack is trying to re-create it instead of reusing the same.

但是,有趣的事实是;如果我使用 AWS API GATEWAY Web 控制台,我可以立即执行此操作.

But, here is the fun fact; if i use the AWS API GATEWAY web console, I can do this in no time.

我怎样才能让它在 aws-sam 中工作?

How can I get this to work in aws-sam ?

更新

根据用户 LRutten 的建议,我为嵌套堆栈想出了以下代码.

Following the advice from the user LRutten, I came up with the following code for the nested stack.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  aws-restapi

  Sample SAM Template for aws-restapi

Globals:
  Function:
    Timeout: 5
    VpcConfig:
        SecurityGroupIds:
          - sg-xxxxxx
        SubnetIds:
          - subnet-xxxxx

Parameters:
  FirebaseProjectId:
    Type: String
  
  DomainName:
    Type: String

Resources:

  AuthGatewayHttpApi2:
    Type: AWS::Serverless::HttpApi
    Properties:
      Auth:
        Authorizers:
          FirebaseAuthorizer:
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - !Ref FirebaseProjectId
              issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
        DefaultAuthorizer: FirebaseAuthorizer
  
  MyApiMapping:
    Type: 'AWS::ApiGatewayV2::ApiMapping'
    Properties:
      DomainName: !Ref DomainName
      ApiId: !Ref AuthGatewayHttpApi2
      Stage: prod
  
  MyDomainName:
    Type: 'AWS::ApiGatewayV2::DomainName'
    Properties:
      DomainName: !Ref DomainName
      DomainNameConfigurations:
        - EndpointType: REGIONAL
          CertificateArn: arn:aws:acm:us-east-1:716460586643:certificate/bac44716-420d-431b-b40d-01378f20432d


  GetAllPromotionsFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: aws-restapi/
      Handler: source/promotions/promotions-getall.getAllPromotions
      Runtime: nodejs14.x
      Events:
        GetAllPromotionsAPIEvent:
          Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /promotions/getall
            Method: get
            ApiId: !Ref AuthGatewayHttpApi2

这最终导致以下错误

Embedded stack arn:aws:cloudformation:us-east-1:716460586643:stack/aws-restapi-NestedStackTwo-14SAYLRO1WD1D/62336020-xx-xx-a04e-x was not successfully created:

The following resource(s) failed to create: [MyDomainName, MyApiMapping]. 

推荐答案

确实,当您在此处指定域名称时,SAM 总是会创建域.它也在文档中说明.

Indeed SAM always creates the domain when you specify it's name there. It stated in the docs as well.

要解决这个问题,您可以省略 AWS::Serverless::HttpApi 资源中的整个域配置,并编写由 SAM 自己创建的资源.所以添加一个带有

To get around this, you can omit the whole domain configuration in the AWS::Serverless::HttpApi resource and write the resources created by SAM yourself. So add a section with

Type: AWS::ApiGatewayV2::ApiMapping
Properties: 
  ApiId: String
  ApiMappingKey: String
  DomainName: String
  Stage: String

文档

确保 ApiMapping 中的 Stage 属性也存在于 API 的 StageName 属性中.

Make sure the Stage property in the ApiMapping is also present in the StageName property of the API.

还有一个

And a

Type: AWS::ApiGatewayV2::DomainName
Properties: 
  DomainName: String
  DomainNameConfigurations: 
    - DomainNameConfiguration
  MutualTlsAuthentication: 
    MutualTlsAuthentication
  Tags: Json

文档

在不定义域本身两次的情况下手动添加这些应该可以解决问题.

Manually adding these without having the domain itself defined twice should do the trick.

woops 并没有真正考虑清楚.你当然应该只有映射,而不是域名本身:P.

woops wasn't really thinking straight. You should of course only have the mapping, not the domain name itself again :P.

这篇关于AWS:为什么我无法将自定义域分配给嵌套堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆