AWS CloudFormation のテンプレートとスタックを便利に操作できる AWS 公式ツール「rain」を紹介する.僕自身も AWS CloudFormation スタックを試行錯誤しながら実装するときによく rain を使っている.rain には機能が多くあるけど,今回は個人的に便利だと思う「10点」にしぼって紹介する❗️
セットアップ
Homebrew で簡単にセットアップできる.サブコマンドは大きく「スタック用」と「テンプレート用」でたくさんある❗️
$ brew install rain $ rain --version Rain v1.3.3 darwin/arm64 $ rain -h Rain is a command line tool for working with AWS CloudFormation templates and stacks Usage: rain [command] Stack commands: cat Get the CloudFormation template from a running stack deploy Deploy a CloudFormation stack from a local template logs Show the event log for the named stack ls List running CloudFormation stacks rm Delete a running CloudFormation stack stackset This command manipulates stack sets. watch Display an updating view of a CloudFormation stack Template commands: build Create CloudFormation templates diff Compare CloudFormation templates fmt Format CloudFormation templates merge Merge two or more CloudFormation templates pkg Package local artifacts into a template tree Find dependencies of Resources and Outputs in a local template Other Commands: completion Generate the autocompletion script for the specified shell console Login to the AWS console help Help about any command info Show your current configuration
便利な操作を紹介する
1. rain build
でテンプレートの雛形を作ろう
AWS CloudFormation テンプレートを作るときに個人的によくやるのは AWS CloudFormation のドキュメントを検索して,YAML の雛形をコピーペーストして,あとは必須項目を埋めていく流れだけど,rain build
コマンドを使うと AWS CloudFormation テンプレートの雛形をサクッと作れる👌
$ rain build AWS::S3::Bucket AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyBucket: Type: AWS::S3::Bucket Properties: AccelerateConfiguration: # Optional AccelerationStatus: CHANGEME AccessControl: CHANGEME # Optional (中略)
AWS::S3::Bucket
は設定が多く200行以上も出力される.CHANGEME
に値を設定したり,Optional
は必要なければ消したりしながら組み立てる.また最初はシンプルに作りたいことも多いと思う.--bare
オプションを設定すると必要最低限のテンプレートの雛形を作れる.AWS::S3::Bucket
には必須項目はなく,以下のように驚くほどシンプルになる❗️
$ rain build --bare AWS::S3::Bucket AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyBucket: Type: AWS::S3::Bucket
rain build
コマンドには複数のリソースを指定できる.以下の例は AWS::EC2::VPC
と AWS::EC2::Subnet
を指定している.VpcId !Ref MyVPC
のように紐付きまでは自動的に解決されないところは注意点かなぁー.
$ rain build --bare AWS::EC2::VPC AWS::EC2::Subnet AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MySubnet: Type: AWS::EC2::Subnet Properties: VpcId: CHANGEME MyVPC: Type: AWS::EC2::VPC
2. rain build --list
でリソース一覧を検索しよう
rain build --list
コマンドを使うと AWS CloudFormation でサポートしているリソース一覧を確認できる.現時点で1000種類以上もあるため,僕は peco
と組み合わせて検索できるようにしている(おすすめ!).適当にエイリアスを設定しておくと便利で,よく使っている👾
$ rain build --list | head -n 5 AWS::ACMPCA::Certificate AWS::ACMPCA::CertificateAuthority AWS::ACMPCA::CertificateAuthorityActivation AWS::ACMPCA::Permission AWS::APS::RuleGroupsNamespace $ rain build --list | wc -l 1032 $ rain build --list | peco | pbcopy $ alias cr='rain build --list | peco | pbcopy'
3. rain deploy
でデプロイしよう
次に AWS::S3::Bucket
をデプロイする.デプロイするときは rain deploy
コマンドを使う.aws cloudformation deploy
コマンドとあまり差がなさそうに思うけど,影響のあるリソース一覧が表示されたり,実行するかどうか (Y/n
) のプロンプトが表示されたり,より価値のある情報が確認できるようになっている.
$ rain build --bare AWS::S3::Bucket > s3-bare.yaml $ rain deploy s3-bare.yaml CloudFormation will make the following changes: Stack s3-bare: + AWS::S3::Bucket MyBucket Do you wish to continue? (Y/n) Y Deploying template 's3-bare.yaml' as stack 's3-bare' in ap-northeast-1. Stack s3-bare: CREATE_COMPLETE Successfully deployed s3-bare
rain の特徴の一つに「必要なログのみを表示する」という思想があって(Rain also filters out uninteresting log messages by default so you just see the errors that require attention.
),rain
コマンドで出力されるログや rain logs
コマンドで取得できるログなどはデフォルトで非常に工夫されている.
$ rain logs s3-bare No interesting log messages to display. To see everything, use the --all flag $ rain logs s3-bare --all Apr 16 00:00:00 s3-bare/s3-bare (AWS::CloudFormation::Stack) CREATE_COMPLETE Apr 16 00:00:00 s3-bare/MyBucket (AWS::S3::Bucket) CREATE_COMPLETE Apr 16 00:00:00 s3-bare/MyBucket (AWS::S3::Bucket) CREATE_IN_PROGRESS "Resource creation Initiated" Apr 16 00:00:00 s3-bare/MyBucket (AWS::S3::Bucket) CREATE_IN_PROGRESS Apr 16 00:00:00 s3-bare/s3-bare (AWS::CloudFormation::Stack) CREATE_IN_PROGRESS "User Initiated" Apr 16 00:00:00 s3-bare/s3-bare (AWS::CloudFormation::Stack) REVIEW_IN_PROGRESS "User Initiated"
4. rain ls
でスタック一覧を確認しよう
rain ls
コマンドを使うとスタック一覧とステータスを確認できる.aws cloudformation list-stacks
コマンドでも同じ情報は取得できるけど,無駄な情報がなくシンプル👍
$ rain ls CloudFormation stacks in ap-northeast-1: s3-bare: CREATE_COMPLETE
5. rain rm
でスタックを削除しよう
rain rm
コマンドでスタックを削除できる.
$ rain rm s3-bare Stack s3-bare: CREATE_COMPLETE Are you sure you want to delete this stack? (y/N) y Successfully deleted stack 's3-bare'
6. rain deploy
でパラメータを設定しよう
以下のように Amazon S3 バケット名をパラメータから取得するように変更した.このテンプレートを aws cloudformation deploy
コマンドでデプロイするときはパラメータを指定しないと ValidationError
になる.
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: BucketName: Type: String Resources: MyBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName
rain deploy
コマンドを使うと未指定の場合はインタラクティブに指定できる❗️これも便利〜
$ rain deploy s3-with-parameters.yaml Enter a value for parameter 'BucketName': kakakakakku-s3-with-parameters CloudFormation will make the following changes: Stack s3-with-parameters: + AWS::S3::Bucket MyBucket Do you wish to continue? (Y/n) Y Deploying template 's3-with-parameters.yaml' as stack 's3-with-parameters' in ap-northeast-1. Stack s3-with-parameters: CREATE_COMPLETE Successfully deployed s3-with-parameters
スタックを一度消しておく.
$ rain rm s3-with-parameters
7. rain deploy
で失敗してもそのままやり直そう
今度は Amazon S3 バケット名として許容されていない _
を含めてデプロイするとエラーになり,そのままもう一度 rain deploy
コマンドを実行すると Deleted existing, empty stack.
というメッセージが出力されて自動的に ROLLBACK_COMPLETE
で失敗したスタックを削除してくれる.
$ rain deploy s3-with-parameters.yaml Enter a value for parameter 'BucketName': kakakakakku_s3_with_parameters CloudFormation will make the following changes: Stack s3-with-parameters: + AWS::S3::Bucket MyBucket Do you wish to continue? (Y/n) Y Deploying template 's3-with-parameters.yaml' as stack 's3-with-parameters' in ap-northeast-1. Stack s3-with-parameters: ROLLBACK_COMPLETE Messages: - MyBucket: Bucket name should not contain '_' failed deploying stack 's3-with-parameters' $ rain deploy s3-with-parameters.yaml Deleted existing, empty stack. Enter a value for parameter 'BucketName' (existing value: kakakakakku_s3_with_parameters): kakakakakku-s3-with-parameters CloudFormation will make the following changes: Stack s3-with-parameters: + AWS::S3::Bucket MyBucket Do you wish to continue? (Y/n) Y Deploying template 's3-with-parameters.yaml' as stack 's3-with-parameters' in ap-northeast-1. Stack s3-with-parameters: CREATE_COMPLETE Successfully deployed s3-with-parameters
AWS CloudFormation スタックを作ったことがある人は経験していると思うけど,スタックを作るのに失敗して ROLLBACK_COMPLETE
になると,1度スタックを削除する必要があって,地味にこの作業が手間に感じる.rain deploy
コマンドではその手間を削減してくれて最高❗️
8. rain fmt
でテンプレートを整形しよう
rain fmt
コマンドを使うと AWS CloudFormation テンプレートを整形できる.整形できることを確認するために AWS::S3::Bucket
のテンプレートを以下のように一部修正した.
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: BucketName: Type: String Default: "kakakakakku-s3-bucket" Resources: MyBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName Tags: - Key: 'Key1' Value: 'Value1' Outputs: MyBucketArn: Value: Fn::GetAtt: - MyBucket - Arn
このテンプレートに rain fmt
コマンドを実行すると整形できる.
- 文字列の
"
や'
が削除された Fn::GetAtt
組み込み関数が短縮形の!GetAtt
になって1行にまとまった
rain fmt s3-before-format.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Parameters: BucketName: Type: String Default: kakakakakku-s3-bucket Resources: MyBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName Tags: - Key: Key1 Value: Value1 Outputs: MyBucketArn: Value: !GetAtt MyBucket.Arn
他にも YAML / JSON を相補変換したりもできる(これは cfn-flip
コマンドでもできるけど!).
9. rain tree
で Resources と Outputs の依存関係を図にしよう
rain tree
コマンドを使うと AWS CloudFormation テンプレートから Resources と Outputs の依存関係を図にできる.dot フォーマットで出力されるため,dot
コマンドを使えば png ファイルなどに変換できる.
$ rain tree -d s3-with-parameters.yaml digraph { rankdir=LR; concentrate=true; subgraph cluster_Parameters { label="Parameters"; "Parameters: BucketName" [label="BucketName" shape=diamond]; } subgraph cluster_Resources { label="Resources"; "Resources: MyBucket" [label="MyBucket" shape=Mrecord]; } subgraph cluster_Outputs { label="Outputs"; } "Parameters: BucketName" -> "Resources: MyBucket"; } $ rain tree -d s3-with-parameters.yaml > s3-with-parameters.dot $ dot -T png s3-with-parameters.dot -o s3-with-parameters.png
10. rain cat
で AWS SAM リソースの変換後テンプレートを確認しよう
rain cat
コマンドを使うと AWS CloudFormation スタックのテンプレートを確認できる.さらに --transformed
オプションを付けると AWS SAM などマクロを使った AWS CloudFormation テンプレートの変換後を確認できる.今回は AWS SAM のサンプルテンプレートを用意してスタックを作る.
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.9 Architectures: - x86_64
次に rain cat template --transformed
コマンドを実行すると,以下のようにリソース名が AWS::Lambda::Function
になっている.マクロによってどのように変換されたのかを確認したいときに使える.
$ rain cat template --transformed AWSTemplateFormatVersion: "2010-09-09" Resources: HelloWorldFunction: Type: AWS::Lambda::Function Properties: {Code: {S3Bucket: rain-artifacts-000000000000-ap-northeast-1, S3Key: b769a6f86744588f72b9c40013aec639a9dd8f8fdcbca559029a388836f8fe12}, Handler: app.lambda_handler, Role: !GetAtt HelloWorldFunctionRole.Arn, Runtime: python3.9, Tags: [{Key: 'lambda:createdBy', Value: SAM}], Architectures: [x86_64]} HelloWorldFunctionRole: Type: AWS::IAM::Role Properties: {AssumeRolePolicyDocument: {Version: "2012-10-17", Statement: [{Action: ['sts:AssumeRole'], Effect: Allow, Principal: {Service: [lambda.amazonaws.com]}}]}, ManagedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'], Tags: [{Key: 'lambda:createdBy', Value: SAM}]}
まとめ
AWS CloudFormation のテンプレートとスタックを便利に操作できる AWS 公式ツール「rain」を紹介した.aws cloudformation
コマンドを使うよりも便利なので,AWS CloudFormation を使っていたら試してみると良いかと❗️おすすめです〜