如何在 Cloudformation 中获取区域 AWS API 网关的自定义域的目标域名?

Posted

技术标签:

【中文标题】如何在 Cloudformation 中获取区域 AWS API 网关的自定义域的目标域名?【英文标题】:How to get the target domain name of a custom domain for Regional AWS API Gateway in Cloudformation? 【发布时间】:2018-07-10 00:18:17 【问题描述】:

我正在尝试在 AWS 上创建一个多区域无服务器应用程序。我已按照here 给出的说明进行操作。我正在使用无服务器框架,它使用 Cloudformation 脚本在 AWS 上创建所有资源。

我想为 API 网关创建一个自定义域作为区域端点。当它创建一个区域端点时,它会生成一个目标域。我想知道如何在我的 Cloudformation 脚本中获取目标域的值?

创建边缘优化终端节点时,我使用 DistributionDomainName 属性获取 CloudFront 部署的值。但是在创建区域端点时,我没有看到目标域名的任何属性。我尝试将DistributionDomainName 属性用于区域端点,但它会抛出一个错误,提示没有DistributionDomainName

以下是我的脚本的一部分 -

# Creates a custom domain for the ApiGateway
customDomain:
  Type: 'AWS::ApiGateway::DomainName'
  Properties:
    DomainName: $self:custom.domain
    EndpointConfiguration:
      Types:
        - REGIONAL
    RegionalCertificateArn: $self:custom.certificateArn

# Insert a DNS record in route53 hosted zone to redirect from the custom domain to CF distribution
dnsRecord:
  Type: AWS::Route53::RecordSet
  Properties:
    Region: $self:provider.region
    SetIdentifier: $self:provider.region
    HostedZoneId: $self:custom.hostedZoneId
    Name: $self:custom.domain
    Type: CNAME
    TTL: 60
    ResourceRecords:
      - "Fn::GetAtt": [customDomain, DistributionDomainName]

请帮忙。谢谢!

更新

Cloudformation 现在通过RegionalDomainName 属性返回区域域名。它可以用作Fn:GetAtt : [customDomain, RegionalDomainName]

【问题讨论】:

区域域名 【参考方案1】:

目前这是不可能的。

正如您所提到的,唯一公开的参数是 DistributionDomainName,这仅适用于边缘优化端点。

作为一种解决方法(直到它将在 CloudFormation 中实现),您可以使用由您自己的 Lambda 函数支持的 CustomResource 来返回 regionalDomainName 属性。

以下是执行此操作的示例 CloudFormation YAML 代码:

Resources:
  # The workaround Lambda that returns the regionalDomainName property
  RegionalDomainLambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python2.7
      Handler: index.handler
      Role:
        'Fn::GetAtt': [YOUR_ROLE_GOES_HERE, Arn] # make sure you include apigateway:GET
      Timeout: 50
      Code:
        ZipFile: |
          import cfnresponse
          import json
          import boto3

          client = boto3.client('apigateway')
          def handler(event, context):
              response_data = 
              try:
                  domainName = event['ResourceProperties']['DomainName']
                  regional_domain_name = client.get_domain_name(domainName=domainName)['regionalDomainName']
                  response_data['value'] = regional_domain_name

                  cfnresponse.send(event, context, cfnresponse.SUCCESS,response_data, "RegionalDomainNameString")
              except Exception as e:
                  response_data['exception'] = e
                  cfnresponse.send(event, context, cfnresponse.FAILED, response_data, "RegionalDomainNameString")

  # The resource that serves as a placeholder
  RegionalDomain:
    Type: Custom::CustomResource
    Properties:
      ServiceToken:
        'Fn::GetAtt': [RegionalDomainLambda, Arn]
      DomainName: Ref: YOUR_API_GATEWAY_DOMAIN_NAME_GOES_HERE

  # And here's how to use it
  SomeOtherResource:
    SomeOtherProperty: 'Fn::GetAtt': [RegionalDomain, value]

【讨论】:

区域 API Gateway REST API 的域基于 API id 和区域:restapi-id.execute-api.region.amazonaws.com 参见 docs.aws.amazon.com/apigateway/latest/developerguide/…跨度> 【参考方案2】:

我在 Cloud Formation 中编写脚本时遇到了同样的问题。当我阅读有关它的更多信息时,根据我的研究,截至目前,区域端点没有受支持的返回值。

您可以使用它来读取区域端点,使用 Python 脚本创建使用 AWS Lambda 的自定义资源,这样您的自动化就不会因返回值不可用而中断。

client = boto3.client('apigateway') response = client.get_domain_name( domainName='api.example.com' ) print(response['regionalDomainName'])

【讨论】:

以上是关于如何在 Cloudformation 中获取区域 AWS API 网关的自定义域的目标域名?的主要内容,如果未能解决你的问题,请参考以下文章

Cloudformation 找不到区域性 Opsworks 堆栈

如何在 cloudformation 中获取 Elastic Beanstalk EC2 实例的 instanceId?

如何在 cloudformation yml 中获取最新的 lambda 版本?

在多个区域启动 AWS cloudformation 堆栈

CloudFormation 跨区域参考

如何在 AWS Cloudformation 模板文件中获取用户名?