先日 yamllintのconfig という記事を書きましたが、CloudFormation のテンプレートをチェクしたいなら、cfn-python-lint (https://github.com/awslabs/cfn-python-lint) をおすすめします。
CloudFormation テンプレートの文法チェックだけでなく、セマンティック・チェックもしてくれます。
cfn-lint という npm モジュールがあるため、名前の衝突をさけてか、cfn-python-lint となっていますが、パッケージ名、実行コマンドは、ともに cfn-lint
になります。
インストール
$ pip install cfn-lint
ヘルプ
usage: cfn-lint [-h] [-t TEMPLATE [TEMPLATE ...]] [-b] [-d]
[-f {quiet,parseable,json}] [-l] [-r REGIONS [REGIONS ...]]
[-a APPEND_RULES [APPEND_RULES ...]]
[-i IGNORE_CHECKS [IGNORE_CHECKS ...]]
[-c INCLUDE_CHECKS [INCLUDE_CHECKS ...]] [-o OVERRIDE_SPEC]
[-v] [-u]
[TEMPLATE [TEMPLATE ...]]
CloudFormation Linter
optional arguments:
-h, --help show this help message and exit
Standard:
TEMPLATE The CloudFormation template to be linted
-t TEMPLATE [TEMPLATE ...], --template TEMPLATE [TEMPLATE ...]
The CloudFormation template to be linted
-b, --ignore-bad-template
Ignore failures with Bad template
-f {quiet,parseable,json}, --format {quiet,parseable,json}
Output Format
-l, --list-rules list all the rules
-r REGIONS [REGIONS ...], --regions REGIONS [REGIONS ...]
list the regions to validate against.
-i IGNORE_CHECKS [IGNORE_CHECKS ...], --ignore-checks IGNORE_CHECKS [IGNORE_CHECKS ...]
only check rules whose id do not match these values
-c INCLUDE_CHECKS [INCLUDE_CHECKS ...], --include-checks INCLUDE_CHECKS [INCLUDE_CHECKS ...]
include rules whose id match these values
-v, --version Version of cfn-lint
Advanced / Debugging:
-d, --debug Enable debug logging
-a APPEND_RULES [APPEND_RULES ...], --append-rules APPEND_RULES [APPEND_RULES ...]
specify one or more rules directories using one or
more --append-rules arguments.
-o OVERRIDE_SPEC, --override-spec OVERRIDE_SPEC
A CloudFormation Spec override file that allows
customization
-u, --update-specs Update the CloudFormation Specs
つかいかた
テストに使ったテンプレートはこのようなものです。
sample.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: |
API Gateway Custom Integration Template
Globals:
Function:
Timeout: 30
Parameters:
LambdaFuncArn:
Type: String
LambdaApiId:
Type: String
LambdaAPIRootResourceId:
Type: String
Resources:
LambdaAPIRootPost:
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
ResourceId: !Sub ${LambdaAPIRootResourceId}
RestApiId: !Sub ${LambdaApiId}
HttpMethod: POST
Integration:
Type: AWS
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFuncArn}/invocations'
IntegrationHttpMethod: POST
IntegrationResponses:
- StatusCode: 200
ResponseTemplates:
application/json: ""
ContentHandling: CONVERT_TO_TEXT
PassthroughBehavior: WHEN_NO_TEMPLATES
RequestTemplates:
application/x-www-form-urlencoded: |
{
"headers": {
#foreach($key in $input.params().header.keySet())
"$key": "$input.params().header.get($key)"#if($foreach.hasNext),#end
#end
},
"body": $input.json("$")
}
MethodResponses:
- StatusCode: 200
$ cfn-lint sample.yaml
E3012 Property Resources/LambdaAPIRootPost/Properties/Integration/IntegrationResponses/0/StatusCode should be of type String
sample.yaml:28:13
E3012 Property Resources/LambdaAPIRootPost/Properties/MethodResponses/0/StatusCode should be of type String
sample.yaml:44:11
StatusCode の値は文字列であるべきと指摘されています。yamllint では文法チェックしてかできないのに対し、cfn-lint ではこのようなセマンティックのチェックもしてくれます。
--- sample.yaml 2018-10-24 15:55:32.000000000 +0900
+++ sample.yaml 2018-10-24 16:03:47.000000000 +0900
@@ -25,7 +25,7 @@
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFuncArn}/invocations'
IntegrationHttpMethod: POST
IntegrationResponses:
- - StatusCode: 200
+ - StatusCode: '200'
ResponseTemplates:
application/json: ""
ContentHandling: CONVERT_TO_TEXT
@@ -41,4 +41,4 @@
"body": $input.json("$")
}
MethodResponses:
- - StatusCode: 200
+ - StatusCode: '200'
指摘されたところを修正すると警告は出なくなりました。
$ yamllint sample.yaml
$