在AWS Lambda serverless.template文件中设置EndpointConfiguration

时间:2018-01-18 16:30:26

标签: c# .net amazon-web-services aws-lambda aws-api-gateway

AWS API Gateway(相对)最近允许将端点配置设置为区域而不是Edge Optimized。我正在使用.NET创建无服务器的lambda函数。

根据我的理解,我需要添加以下值来设置端点类型:

"EndpointConfiguration": { "Types" : [ "REGIONAL" ] }

serverless.template是否接受此键值对以及我将它放在哪里?

编辑:我没有使用无服务器框架。我在Visual Studio 2017中使用AWS Toolkit

2 个答案:

答案 0 :(得分:1)

当您说您在Visual Studio 2017中使用AWS Toolkit时,我假设您正在使用AWS SAM并构建CloudFormation模板(如您提到serverless.template所推断的那样)。

目前AWS SAM不支持使用区域端点设置API网关。这是GitHub issue目前正在追踪它


但是,如果您使用自定义域,则有一个合理的解决方法。

即使您的API网关是在端点设置为边缘优化的情况下创建的,也可以创建一个端点设置为区域的AWS::ApiGateway::DomainName资源。


以下是我在AWS SAM模板中实现此目标的示例(我使用YAML代替JSON,因为它更容易执行多行值)。

注意:AWS::ApiGateway::DomainName目前没有提供有关区域端点的信息,因此我添加了一个能够检索所需信息的自定义资源。

  MyApiGateway:
    Type: 'AWS::Serverless::Api'
    Properties:
      StageName: 'prod'

  ApiCertificate:
    Type: 'AWS::CertificateManager::Certificate'
    Properties:
      DomainName: 'api.example.com'
      DomainValidationOptions:
      - DomainName: 'api.example.com'
        ValidationDomain: 'example.com'

  CustomResourceLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Action: 'sts:AssumeRole'
          Effect: Allow
          Principal:
            Service: 'lambda.amazonaws.com'
      Path: /
      ManagedPolicyArns:
      - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies:
      - PolicyName: ApiGateway
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Action:
            - 'apigateway:*'
            Effect: Allow
            Resource: '*'

  DomainNameInfoCustomResourceFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Handler: index.handler
      Role: !GetAtt CustomResourceLambdaExecutionRole.Arn
      Runtime: 'nodejs6.10'
      Timeout: 300
      Code:
        ZipFile: |
          const AWS = require('aws-sdk');
          const response = require('cfn-response');

          exports.handler = function(event, context) {
              const ApiGateway = new AWS.APIGateway();
              ApiGateway.getDomainName({
                  domainName: event.ResourceProperties.DomainName
              }, (err, data) => {
                  if (err != null) {
                      response.send(event, context, response.FAILED, undefined);
                  } else {
                      response.send(event, context, response.SUCCESS, {
                          DomainName: data.domainName,
                          RegionalDomainName: data.regionalDomainName,
                          RegionalHostedZoneId: data.regionalHostedZoneId,
                          DistributionDomainName: data.distributionDomainName,
                          DistributionHostedZoneId: data.distributionHostedZoneId
                      });
                  }
              });
          }

  ApiDomainName:
    Type: 'AWS::ApiGateway::DomainName'
    Properties:
      DomainName: 'api.example.com'
      EndpointConfiguration:
        Types:
        - REGIONAL
      RegionalCertificateArn: !Ref ApiCertificate

  ApiBasePathMapping:
    Type: 'AWS::ApiGateway::BasePathMapping'
    DependsOn: [MyApiGatewayprodStage, ApiDomainName]
    Properties:
      DomainName: 'api.example.com'
      RestApiId: !Ref MyApiGateway
      Stage: 'prod'

  ApiDomainNameInfo:
    Type: 'Custom::DomainNameInfo'
    DependsOn: [ApiDomainName, ApiBasePathMapping]
    Properties:
      ServiceToken: !GetAtt DomainNameInfoCustomResourceFunction.Arn
      DomainName: !Ref ApiDomainName

  ApiRecordSet:
    Type: 'AWS::Route53::RecordSet'
    DependsOn: [ApiDomainNameInfo]
    Properties:
      HostedZoneId: '0123456789' # ENTER YOUR DOMAINS HOSTED ZONE ID
      Name: 'api.example.com'
      ResourceRecords:
      - !GetAtt ApiDomainNameInfo.RegionalDomainName
      Type: CNAME
      TTL: 60

答案 1 :(得分:0)

请参阅无服务器框架documentation

基本上是endpointType: REGIONAL