Linterを使ってCloudFormationの間違いに爆速で気づく
CloudFormation、使ってますか?
私はAWSの環境を手早く構築するために、CloudFormationをむちゃくちゃ使います。
CFnテンプレートを書いてCFnスタックを作る際に、こんな経験はありませんか?
「我ながら完璧なテンプレートができてしまった…。CFnスタック作ったろ。」ポチ
「うわー恥ずかしい。Cdirだってよ。スペルミスしてるじゃん…。」
こういった簡単な間違いはCFnテンプレート書きながらLinterでさっさと見つけましょう。というお話です。
Linterとは
ざっくりいうと、記述しているソースコード(CFnテンプレート)が妥当かどうかチェックしてくれるツールです。
例えば、「パラメーターが無い」なんて問題がエディタ上で一瞬でわかります。
CloudFormationのLinter
CloudFormationのLinterは2つあります。
1つ目が cfn-python-lint
です。pythonで書かれたCloudFormationテンプレートのLinterです。
https://github.com/aws-cloudformation/cfn-python-lint
2つ目が cfn-lint
です。jsで書かれたLinterです。
https://github.com/martysweet/cfn-lint
この2つのLinterは、同じ cfn-lint
コマンドで動きますが、全く別の物です。注意してください。
今回はエディタプラグインが豊富に開発されているので、cfn-python-lintを使用します。
cfn-python-lintのインストール
pipを使ってインストールできます。
$ pip install cfn-lint
cfn-python-lintの使い方
こういったCFnテンプレートがあった場合、
--- AWSTemplateFormatVersion: '2010-09-09' Description: 'My CloudFormation Template.' Parameters: MyCidrBlock: Type: String Default: 192.0.2.0/24 Resources: Vpc: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref MyCdirBlock
CFnテンプレート名を引数に cfn-lint
コマンドを実行すると、
$ cfn-lint template.yml
CFnテンプレートのおかしなところを出力してくれます。
W2001 Parameter MyCidrBlock not used. template.yml:6:3 E1012 Ref MyCdirBlock not found as a resource or parameter template.yml:14:7
エディタのプラグインを入れる
CFnテンプレートのチェックをするのに、いちいちコマンド打つのはめんどくさいです。 もっとリアルタイムで指摘が欲しいです。
そういう時は、エディタのプラグインを入れましょう。エディタ上でチェックできるようになります。 以下エディタのプラグインが開発されているようです。
- Atom
- NeoVim 0.2.0+/Vim 8
- ALE
- Syntastic
- Sublime
- Visual Studio Code
- IntelliJ IDEA
私はIntelliJ IDEAが好きで、Pythonを書くこともあるのでPyCharm CE(Community Edition)を使用しています。ありがたいことに無料で使えます。
https://www.jetbrains.com/pycharm/download/
IntelliJ IDEAを使う場合、あわせてCloudFormationプラグインも使うと便利です。 IntelliJ IDEAのCloudFormationプラグインについては弊社ブログを御覧ください。
PyCharmプラグイン導入手順
プラグインブラウザでcfn-lintを探してインストールします。
プラグインのインストールが終わったらCFNLintの設定が必要です。
設定画面でcfnlintで検索して、設定を有効(enable)にします。
cfn-lint exeには cfn-lint
コマンドのフルパスを入れてください。パスは $ which cfn-lint
で確認してください。
WarningとErrorを目立たせたいんで下2つにもチェック入れます。
CFnテンプレートをチェックしてみる
テンプレートを書きながら、Linterの使用感を確認していきます。
例えば、DynamoDBのCFnテンプレートを書いてみます。
--- AWSTemplateFormatVersion: '2010-09-09' Resources: DynamoDB: Type: "AWS::DynamoDB::Table" Properties: TableName: "MyDynamoDB" AttributeDefinitions: - AttributeName: "Id" AttributeType: "String" KeySchema: - AttributeName: "ArtistId" KeyType: "HASH"
DynamoDBのAttributeTypeって何があるんだっけ?Stringだっけ? 覚えていないので、とりあえずStringとか適当に書いてしまいます。
すると、Valid values are ['B', 'N', 'S']
って怒られます。これで間違いにもすぐ気づけます。
次はEC2のCFnテンプレートを書いてみます。
--- AWSTemplateFormatVersion: "2010-09-09" Resources: MyEC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: "ami-0f9ae750e8274075b" IamInstanceProfile: !Ref Ec2Role Ec2Role: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "ec2.amazonaws.com" Action: - "sts:AssumeRole" Policies: - PolicyName: "root" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "*" Resource: "*"
EC2作って、なんでもできるRoleをつけて…と。
すると、"IamInstanceProfile" can Ref to resources of type [AWS::IAM::InstanceProfile]
と怒られています。
忘れがちな、InstanceProfileの存在にもすぐに気づけます。
おわりに
Linterを使ってCFnテンプレートの間違いにすばやく気づき、即修正のループを回していくことで、 圧倒的にCFnテンプレートが書きやすくなります。
ぜひお試しください。