Serverless-application-model: Feature Request: ACM integration - apiGateway

Created on 10 Mar 2017  路  16Comments  路  Source: aws/serverless-application-model

Looks like ACM can be integrated with API Gateway. Are there any folks out there integrating this at this point? Any examples in the pipeline?

Most helpful comment

@jolexa @dinvlad There are plenty of work arounds for the interim, lambdas that would generate the versions correctly, lambdas for aliasing etc....

I would imagine that this is imminent w.r.t. this functionality. I would hope that there is a full example included shortly that encompasses a CI/CD pipeline with Lambda (w/ versions/aliases), APIGateway (w/Staging that is pointing to lambda versions/aliases) , ACM (w/ basepath mapping) and Routing.

I am pulling this together in CodePipeline/CodeBuild so it would be nice if SAM did this sort of thing (or most of it) in one template.

I'll reopen this and see if they can label it a feature request - although there are a lot of features in this thread that are missing.

All 16 comments

This integration was just released: https://aws.amazon.com/ru/about-aws/whats-new/2017/03/amazon-api-gateway-integrates-with-aws-certificate-manager-acm/

But I am also interested to know when SAM will support this fuctionality

I had originally meant 'can be' not 'can not be'. I was pointed to this update this AM, and would really like to get this into the bigger picture. How does this become a feature request? @sanathkr - via you possibly?

Ideally this should support ACM integration/custom domain.

@balldarrens hi there, just following up on this since it was closed without comment and I was following to watch for updates. Did you hear about the timeline for this feature request via another means?

@jolexa This can be done by mixing SAM and CFN together. It is not pretty, but definitely doable. I've just done it. Custom domains and ACM certs are not readily automated in CFN, but they are one time actions for most.

To point a gateway at a custom domain, the domain and the acm cert have to be identical (i.e. yourdomain.example.com (custom domain) must have a matching cert that is matching this domain (yourdomain.example.com). You will need a route for this as well - pointing your domain to the cloudfront distribution.

Then by using a resource for AWS::ApiGateway::BasePathMapping, you can map your gateway to this domain.

I've choosen to abandon the SAM infrastructure for API and implemented AWS::ApiGateway::RestApi, AWS::ApiGateway::Deployment, AWS::ApiGateway::Stage and AWS::ApiGateway::BasePathMapping independently to work around some issues.

Note: there are other issues I've encountered with versioning/alias (Lambdas/APIGateway) that are affecting 'keeping' historical aliases in the currently changeset logic.

Ping me if you need more details/help than above and I will lend a hand if need be.

The biggest problem at the moment is to create a 'Api DomainName' resource for Api Gateway through CFN. You'd have to create it as a custom resource, but even that is not possible at the moment if you'd like to stay within Node.js 4.3 runtime, because it hasn't been updated to a newer version that supports the new API calls yet. You may be able to do it with Python though.

AWS::ApiGateway::BasePathMapping is created easily, but it has to have an explicit DependsOn for the 'Api DomainName' resource created above.

Another problem is that AWS::Serverless::Api does not 'export' its implicitly created AWS::ApiGateway::Stage resource, so you'd either have to use AWS::ApiGateway::RestApi directly (together with explicit AWS::ApiGateway::Stage and AWS::ApiGateway::Deployment), or rely on the undocumented Stage naming scheme and add DependsOn to AWS::ApiGateway::BasePathMapping for that, as described in #32.

All of the other resources are easily created through CFN, namely AWS::CertificateManager::Certificate and AWS::Route53::RecordSet.

So everything will soon be able to be done entirely through CFN, we mostly just need to wait for the Lambda runtime to be updated to the latest version. Watch https://aws.amazon.com/releasenotes/ for updates on Lambda runtime version >=2.26.0.

There is a problem with AWS::CertificateManager::Certificate, in that it requests ACM certificate in the region in which the CFN executes and it also waits until the certificate is approved (manual process). The integration of ACM into API Gateway currently is us-east-1 only - another problem.

That's interesting, indeed I was setting everything up in us-east-1 - so had fewer problems. In general though, isn't it best practice to create one stack per region anyway? I've always thought of that as integral to using ${AWS::Region} and other features to (somewhat ironically) make CloudFormation templates more "portable". Also, a lot of APIs assume/require same region to work properly anyway.

Of course, the uneven rollout of features between regions by AWS breaks that benefit, but I've heard it's somewhat intentional - they make sure everything works smoothly in one region, then can move to the others (beside purely business factors, of course). And then even if one region goes dark (like we've seen recently), others are completely independent and so continue to work as if nothing happened.

Thanks for your help @balldarrens! -- I wanted to figure it out further so I wrote my own reference https://github.com/jolexa/aws-apigw-acm

@jolexa @dinvlad There are plenty of work arounds for the interim, lambdas that would generate the versions correctly, lambdas for aliasing etc....

I would imagine that this is imminent w.r.t. this functionality. I would hope that there is a full example included shortly that encompasses a CI/CD pipeline with Lambda (w/ versions/aliases), APIGateway (w/Staging that is pointing to lambda versions/aliases) , ACM (w/ basepath mapping) and Routing.

I am pulling this together in CodePipeline/CodeBuild so it would be nice if SAM did this sort of thing (or most of it) in one template.

I'll reopen this and see if they can label it a feature request - although there are a lot of features in this thread that are missing.

Agreed, our org puts it all into a deployment pipeline as well because the end-to-end solution is not there.

+1, it's be awesome if they supported versioning natively (i.e. keeping multiple deployments of the same API without creating a stack for each one, etc.)

Reg ACM integration, this can be implemented by hacking together SAM & Customer Lambda resources but it is not neat. I'd rather wait for a native API Gateway/CFN solution.

Reg Lambda versioning in SAM, yes this is another important feature we are working on. Taking a bit longer than expected to get the dev experience ironed out. Will keep you guys posted.

Let's use #41 to track function verisions & aliases support.

AWS::ApiGateway::DomainName has been released almost 2 weeks ago, however currently it seems to be experiencing Internal Failure when trying to reference its DistributionDomainProperty. Hopefully we'll be able to use it once the team fixes that.

EDIT: it's working now, after I've put the API into another stack as an AWS::ApiGateway::RestApi resource (not Serverless). Not sure if the error was triggered by a permissions problem on our part, SAM, or on AWS side (and was fixed today). Either way, having an informative message would help a lot.

Its happening! #248

Its happening! #248

(For reference, #248 is a 'Parent Tracking Issue' for a bunch of unrelated work items. The item related to this issue 'Custom Domains & ACM' is still unchecked, implying it still hasn't been complted yet, so I'll continue discussion here rather than pollute that parent issue with mixed conversation.)

Here's an example template that integrates a SAM stack with a custom HTTPS domain using ACM and Route53. It adds DomainName, BasePathMapping and RecordSetGroup resources, hooking up the default Prod stage of the ServerlessRestApi implicit API, referencing CertificateArn (e.g., arn:aws:acm:us-east-1:[account]:certificate/[id], DomainName (e.g., api.example.com) and HostedZoneName (e.g., example.com.) as input Parameters.

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
  CertificateArn:
    Type: String
  DomainName:
    Type: String
  HostedZoneName:
    Type: String
    AllowedPattern: '.*\.$'
    ConstraintDescription: Must end with trailing dot `.`
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Events:
        API:
          Type: Api
          [...etc...]
  APIDomainName:
    Type: AWS::ApiGateway::DomainName
    Properties:
      CertificateArn: !Ref CertificateArn
      DomainName: !Ref DomainName
  APIBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref APIDomainName
      RestApiId: !Ref ServerlessRestApi
      Stage: Prod
  APIDomain:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: !Ref HostedZoneName
      RecordSets:
      - Name: !Ref DomainName
        Type: A
        AliasTarget:
          DNSName: !GetAtt APIDomainName.DistributionDomainName
          HostedZoneId: Z2FDTNDATAQYW2 # static ID for CloudFront aliases
Outputs:
  ApiUrl:
    Value: !Sub "https://${DomainName}"

For future SAM support, for the simple use-case it might be possible to wrap up these resources into a more user-friendly CustomDomain object appended to Serverless::Function or Serverless::Api resources, e.g.:

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CustomDomain: # Creates implicit DomainName, BasePathMapping and RecordSetGroup resources
        CertificateArn: !Ref CertificateArn # Required
        DomainName: !Ref DomainName # Required
        # HostedZoneName not required; can be derived from provided DomainName

Of course, this makes lots of simplifying assumptions (the API is mapped to the root path of the subdomain, no other RestApis share the same DomainName, the Route53 Hosted Zone and ACM certificate both exist, etc etc..), but I think it could still be interesting for the simple use-case.

Was this page helpful?
0 / 5 - 0 ratings