Amazon API Gateway Deployment with CloudFormation
External
- https://currentlyunnamed-theclassic.blogspot.com/2018/12/mastering-cloudformation-for-api.html
- https://stackoverflow.com/questions/41423439/cloudformation-doesnt-deploy-to-api-gateway-stages-on-update
- Amazon API Gateway Resource Types Reference
Internal
Overview
Resource Types
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
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
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:
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:
AWS::ApiGateway::VpcLink
Parameters: NetworkLoadBalancerArn: Type: String Default: arn:aws:elasticloadbalancing:us-west-2:777777777777:loadbalancer/net/some-nlb/1a49bf234253e5a0 Resources: VpcLink: Type: AWS::ApiGateway::VpcLink Properties: Name: 'blue' Description: 'Some description' TargetArns: - !Ref NetworkLoadBalancerArn
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:
- https://medium.com/@ngchiwang/aws-apigateway-deployment-not-update-3e04fcffe85b. This one did not work, the template modified as described triggered a validation error: "An error occurred (ValidationError) when calling the CreateStack operation: Template format error: Resource name ApiDeployment$timestamp is non alphanumeric."
- https://stackoverflow.com/questions/41423439/cloudformation-doesnt-deploy-to-api-gateway-stages-on-update
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