Amazon API Gateway Deployment with CloudFormation

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

Resource Types

AWS::ApiGateway::RestApi

AWS::ApiGateway::RestApi
Resources:
  Api:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: 'experimental-api'
      Description: 'An experimental API, deployed programmatically'
      FailOnWarnings: true
      BodyS3Location:
        Bucket: 'ovidiu-experiments'
        Key: 'openapi-aws.json'

AWS::ApiGateway::Deployment

AWS::ApiGateway::Deployment
Resources:
 ApiDeployment:
   Type: AWS::ApiGateway::Deployment
   DependsOn: Api
   Properties:
     RestApiId: !Ref Api
     Description: 'something'

If StageName: is specified and the stage does not exist, it will be created.

AWS::ApiGateway::Stage

REST API Reference - Stage
AWS::ApiGateway::Stage
Resources:
  Stage:
    Type: AWS::ApiGateway::Stage
    DependsOn:
      - Api
      - ApiDeployment
    Properties:
      StageName: 'dev'
      RestApiId: !Ref Api
      DeploymentId: !Ref ApiDeployment

Execution Logging Configuration

Resources:
  Stage:
    Type: AWS::ApiGateway::Stage
    ...
    Properties:
      ...
      MethodSettings:
        - ResourcePath: '/*'
          HttpMethod: '*'
          LoggingLevel: 'INFO'

The above configuration turns on execution logging for all resource paths and all http methods. Individual configuration can be specified, for details see Stage Reference - methodSettings.

For more details on API Gateway execution logging see:

API Gateway CloudWatch Execution Logging

Access Logging Configuration

Resources:
  AccessLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: ...

  ...

  Stage:
    Type: AWS::ApiGateway::Stage
    ...
    Properties:
      ...
      AccessLogSetting:
        DestinationArn: !GetAtt AccessLogGroup.Arn
        Format: >-
          {"requestId":"$context.requestId", "ip": "$context.identity.sourceIp",
          "caller":"$context.identity.caller",
          "user":"$context.identity.user","requestTime":"$context.requestTime",
          "eventType":"$context.eventType","routeKey":"$context.routeKey",
          "status":"$context.status","connectionId":"$context.connectionId"}

For more details about access logging, see:

API Gateway CloudWatch Access Logging

AWS::ApiGateway::VpcLink

AWS::ApiGateway::VpcLink
Resources:
  VpcLink:
     Type: AWS::ApiGateway::VpcLink
     Properties:
       Name: 'blue'
       Description: 'Some description'
       TargetArns:
         - !Ref LoadBalancerArn

Idiosyncrasy

As per March 2019, an attempt to re-deploy a new version of an API, as expressed in a version of an Open API file, with CloudFormation, does not work as expected. CloudFormation AWS::ApiGateway::RestApi resource update, as described above, works fine: the new API content is deployed and visible in the console. One would expect that the AWS::ApiGateway::Deployment resource, declared above, would detect that the API changed and re-snapshot it. However, that does not happens. No new deployment is created. As consequence, the stage points to a stale deployment. Changing the description of a Deployment does not work either, the description will be updated on the current deployment, but the content of the API snapshot won't change.

On the same subject:

Possible solutions:

Add Deployments and Stages to the Template

Add a new AWS::ApiGateway::Deployment, with a different logical name, irrespective of whether we keep the old one or now:

Resources:
  Api:
    ...

  ApiDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn: Api
    Properties:
      RestApiId: !Ref Api

  Stage:
    Type: AWS::ApiGateway::Stage
    DependsOn:
      - Api
      - ApiDeployment
    Properties:
      StageName: !Sub 'v0'
      RestApiId: !Ref Api
      DeploymentId: !Ref ApiDeployment

  ApiDeployment2:
    Type: AWS::ApiGateway::Deployment
    DependsOn: Api
    Properties:
      RestApiId: !Ref Api

  Stage2:
    Type: AWS::ApiGateway::Stage
    DependsOn:
      - Api
      - ApiDeployment2
    Properties:
      StageName: 'v2'
      RestApiId: !Ref Api
      DeploymentId: !Ref ApiDeployment2

Dynamically Change The Stack Template and Modify the API Deployment and Stage Logical IDs

Use timestamp or a counter.

Deploy API via CLI

Do not deploy the API and create the Stage with CloudFormation, but programmatically via CLI, from a follow up action.

Nested Stacks

Nested stacks, that describe new Deployment and stage.

Lambda-Backed Custom Resource

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html

Examples