yitzih
yitzih

Reputation: 3118

Set EndpointConfiguration in AWS Lambda serverless.template file

AWS API Gateway (relatively) recently allowed the endpoint configuration to be set as Regional instead of Edge Optimized. I am creating serverless lambda functions using .NET.

From what I understand I need to add the following value to set the endpoint type:

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

Does the serverless.template accept this key-value pair and where would I put it?

Edit: I am not using the serverless framework. I'm using the AWS Toolkit in Visual Studio 2017

Upvotes: 1

Views: 1993

Answers (2)

Stefan Charsley
Stefan Charsley

Reputation: 1406

When you say you are using the AWS Toolkit in Visual Studio 2017 I am assuming that you are using AWS SAM and building CloudFormation templates (as inferred by your mention of serverless.template).

Currently AWS SAM does not support setting up API Gateways with Regional Endpoints. Here is the GitHub issue currently tracking it


However, if you are using custom domains there is a reasonable workaround.

You are able to create a AWS::ApiGateway::DomainName resource with the Endpoint set to Regional even though your API Gateway was created with the Endpoint set to Edge Optimized.


Below is an example of how I have achieved this in my AWS SAM templates (I use YAML instead of JSON because it's easier to do multiline values).

NOTE: the AWS::ApiGateway::DomainName currently does not give out information about Regional Endpoints so I have included a Custom Resource that is able to retrieve the information we need.

  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

Upvotes: 3

Adi H
Adi H

Reputation: 738

See the Serverless Framework documentation

Basically it's endpointType: REGIONAL

Upvotes: 0

Related Questions