3

My goal is allow several independent lambda resources (microservices) to share a common custom domain for test environment. Using the below template, deploying microservice #1 went off without issue. However, when deploying microservice #2, CloudFormation fails and rolls back because the domain name is assigned to microservice #1.

Surely it must be possible to share a common custom domain among several microservices with unique paths?

Service #1 template.yaml

Resources:
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Sub ${apiGatewayStageName}
      DefinitionBody:
        swagger: "2.0"
        info:
          title: !Sub ${functionName}
        paths:
          "/service_one":
            post:
              responses: {}
              x-amazon-apigateway-integration:
                uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${functionName}:live/invocations"
                httpMethod: POST
                type: aws_proxy

  ApiGatewayCustomDomainName:
    Type: AWS::ApiGateway::DomainName
    Properties:
      CertificateArn: !Sub "arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/${apiGatewayCDNCertificateId}"
      DomainName: !Sub "${envName}.${apiGatewayCustomDomainNameSuffix}"
    DependsOn:
      - "LogsSubscriptionFilter"
      - "ApiGatewayApi"

  ApiGatewayBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref ApiGatewayCustomDomainName
      RestApiId: !Ref ApiGatewayApi
      Stage: !Ref apiGatewayStageName
    DependsOn: "ApiGatewayCustomDomainName"

The Service #2 template is the same, except with a different path (.e.g. /service_two.

Kwhitejr
  • 2,206
  • 5
  • 29
  • 49

1 Answers1

3

Worked with AWS support to get to the bottom of this one. In its current form (May 2018), if you want separate SAM templates for each lambda for deployment reasons, but have a shared API Gateway resource for those lambdas, then you must have a separate dedicated API Gateway SAM template. Additionally, the Events parameter in AWS::Serverless::Function must be excluded in favor of paths definitions in AWS::Serverless::Api.

Lastly, the AWS::Serverless::Function(s) must be exported under Output and then imported by the AWS::Serverless::Api resource.

Kwhitejr
  • 2,206
  • 5
  • 29
  • 49
  • Question: Let's say you have each Lambda in its own repo for CI/CD purposes. You have multiple Lambda repos, all that share a common API Gateway. What's the best CI/CD repo setup here? A separate repo for the APIGW SAM? The point of truth for the entire API....included as a git submodule for the individual lambda repos? This is the best I can think of right now. Interested in how you went about this. – sudo soul Jul 18 '18 at 01:54
  • If you're using CloudFormation to create full stacks (as we are), it is not possible to separate the resources as you describe. Where we are as of now is that each Lambda repo produces a full AWS stack via CloudFormation (including static endpoint in CloudFront). Thus we have a proliferation of static urls, used for test; we do not yet have a solution for prod. – Kwhitejr Jul 20 '18 at 22:07
  • I have a similar question for a side project: https://stackoverflow.com/questions/51353076/recommended-project-structure-for-multi-function-sam-template – Kwhitejr Jul 20 '18 at 22:09
  • China currently don't support cross stack resource reference. I must combine all microservices in one template, in one git repo to deploy under the same api gateway domain... Do you guys have solutions more flexible? I wanna spearate microservices' CI/CD pipelines. – yayayahei Mar 03 '20 at 03:00
  • @yayayahei I've since migrated to Terraform. Much easier to cross-reference resources without stacks and outputs. – Kwhitejr Mar 03 '20 at 04:01