Cloudformationツール:rainの便利なコマンドと記法
概要
rainで利用できる、「あまり存在を知られていなそうだけど便利なコマンドや記法」について一部紹介します。
rainの基本的な使い方については触れません。以下の記事が大変わかりやすいです。
rain: CloudFormation を便利に操作しちゃおう - kakakakakku blog
rainについて
rainは、AWS CloudFormationのテンプレート作成やデプロイを簡素化するためのコマンドラインツールです。
テンプレートの検証、フォーマット、デプロイを効率的に行うことができます。
コマンド
今回利用するCloudformationテンプレート
AWSTemplateFormatVersion: 2010-09-09
Description: Generated by rain
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: kagamirror-2024-09-26
ls
通常 rain deploy の際に、以下のようにスタックの差分を確認することができますが、これだと「S3バケットに何らかの変更がある」ことは分かっても、「S3バケットにどんな変更があったか」までは分かりません。
そこで、ls --changeset
を使うことで差分の詳細を確認することができます。
# --no-execでチェンジセットの作成までに留めておく
output=$(rain deploy template.yaml kagamirror-test --no-exec --yes)
# チェンジセットIDを取得
changeset_id=$(echo "$output" | grep 'not executed: ' | awk -F ': ' '{print $2}')
# チェンジセットを確認
rain ls -c kagamirror-test ${changeset_id}
before/afterが表示され、プロパティレベルで差分を確認することができました。
差分が問題なければ、rain deploy --changeset
でスタックをデプロイすればOK
forecast
デプロイ失敗の可能性に関する警告を出力してくれるコマンドです。
同じテンプレートでスタック名だけ変えてデプロイしてみます。
> rain forecast --experimental template.yaml kagamirror-test-2
Stormy weather ahead! 🌪
1 checks failed out of 1 total checks
FG001 FAIL on line 6: AWS::S3::Bucket Bucket - Resource with this name already exists
すでに存在するS3バケット名でデプロイしようとしたので、デプロイ前にエラーを検知してくれました。
この程度であればわざわざforecastするまでもないですが、デプロイに時間のかかるテンプレートの場合などは役立ちそうなコマンドです。
logs
rain logs はスタックのイベントログを出力するコマンドです
❯ rain logs kagamirror-test --all
Sep 26 08:17:36 kagamirror-test/Bucket (AWS::S3::Bucket) CREATE_COMPLETE
Sep 26 08:17:36 kagamirror-test/kagamirror-test (AWS::CloudFormation::Stack) CREATE_COMPLETE
Sep 26 08:17:23 kagamirror-test/Bucket (AWS::S3::Bucket) CREATE_IN_PROGRESS "Resource creation Initiated"
Sep 26 08:17:21 kagamirror-test/Bucket (AWS::S3::Bucket) CREATE_IN_PROGRESS
Sep 26 08:17:19 kagamirror-test/kagamirror-test (AWS::CloudFormation::Stack) CREATE_IN_PROGRESS "User Initiated"
Sep 26 08:12:28 kagamirror-test/kagamirror-test (AWS::CloudFormation::Stack) REVIEW_IN_PROGRESS "User Initiated"
--chart
オプションをつけることで、スタックの各リソースのデプロイにかかった時間をガントチャートで表示することができます。
rain logs --chart kagamirror-test > gantchart.html
記法
!Rain::Embed
テンプレートに別ファイルの内容を文字列として埋め込むことの出来るディレクティブです。
テンプレートと同じ階層にindex.py
を作成して以下のように記述することで埋め込みができます。
.
├ index.py
└ template.yaml
def handler_name(event, context):
print("Hello World")
return "ok"
AWSTemplateFormatVersion: 2010-09-09
Description: Generated by rain
Resources:
TestLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: test-lambda
Role: arn:aws:iam::xxxxxxxxxxx:role/AWSLambdaBasicExecutionRole
Runtime: python3.12
Handler: index.lambda_handler
Code:
ZipFile: !Rain::Embed index.py
!Rain::Include
テンプレートに別のyamlをincludeすることのできるディレクティブです。
肥大化したテンプレート等で適切な粒度でファイルを分けると見通しが良くなりそうです。
以下のように使います。
.
├ s3.yaml
├ lambda.yaml
├ index.py
└ template.yaml
Type: AWS::S3::Bucket
Properties:
BucketName: kagamirror-2024-09-26
Type: AWS::Lambda::Function
Properties:
FunctionName: test-lambda
Role: arn:aws:iam::xxxxxxxxxxx:role/AWSLambdaBasicExecutionRole
Runtime: python3.12
Handler: index.lambda_handler
Code:
ZipFile: !Rain::Embed index.py
AWSTemplateFormatVersion: 2010-09-09
Description: Generated by rain
Resources:
TestS3:
!Rain::Include s3.yaml
TestLambda:
!Rain::Include lambda.yaml
!Rain::S3Http / !Rain:S3
このディレクティブを使用すると、CloudFormation テンプレート内で指定されたローカルファイルが Rain CLI によって自動的に S3 にアップロードされ、その HTTPS URL をテンプレート内で使用できます。
アップロード先のS3のことを考えなくてよいので非常に便利です。
アップロード先の S3 バケットは rain によって自動的に作成されるバケットです。(rain-artifacts-<AWSアカウントID>-<AWSリージョン>
という規則で作成されます。)
ディレクティブの違い
- !Rain::S3Http :
https://
から始まるURLが返ってくる - !Rain:S3 :
s3:://
から始まるS3URLが返ってくる
単純に指定する場合
Resources:
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Rain::S3Http templates/child-stack.yaml
Resources:
MySageMakerModel:
Type: AWS::SageMaker::Model
Properties:
PrimaryContainer:
Image: <ECR Image URI>
ModelDataUrl: !Rain::S3 model/model.tar.gz
バケットやキーを分けて指定する必要がある場合
以下は、API Gateway をデプロイする例です。
バケット名とキー名をそれぞれ個別に指定する必要のあるリソースでは、以下のようにPath, Zip, BucketProperty, KeyPropertyに分解して書く必要があるようです。
AWSTemplateFormatVersion: '2010-09-09'
Description: '!Rain::S3Http を使用した API Gateway の例'
Resources:
MyApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: MyAPI
BodyS3Location: !Rain::S3
Path: api-definition.yaml
Zip: false
BucketProperty: Bucket
KeyProperty: Key
AWSTemplateFormatVersion: "2010-09-09"
Description: '!Rain::S3Http を使用した API Gateway の例'
Resources:
MyApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: MyAPI
BodyS3Location:
Bucket: rain-artifacts-xxxxxxxxxxxxxx-us-west-2
Key: 2944a86b8861de0ae0c1f7exxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Parameters / Tags
rainでは別ファイルのyamlに定義したParameters
とTags
をデプロイの際に読み込むことが出来る。
環境ごとに読み込ませたいparameters.yaml
を切り替えることで柔軟な運用が可能になる。
Parameters:
ParamA: aaa
ParamB: bbb
Tags:
Environment: dev
rain deploy template.yaml <stack_name> --config parameters.dev.yaml
Discussion