CloudFormationテンプレート内のStep functionsのState machine定義をS3に置けるようになった
まえおき
今週あったチーム先輩(Aさん)との会話
私 :CloudFormationテンプレートにStepfunctionsを書こうとするとyamlにベタ書きしかできないんですよ。
これが私がCDKを押す理由の一つなんですよ。
Aさん:LambdaみたいにS3バケットに定義ファイルを置いてそのパスをyamlに書けばいいじゃん。
私 :あれ?私が調べたときはそれができなかったので、今あるテンプレートはすべてベタ書きにしているんですが…。
Aさん:うん?これでできないんだけ?(CloudFormationのドキュメントURLを共有)
私 :できるじゃん!?
送られてきたCloudFormationドキュメントを見ると、DefinitionS3Location
というプロパティがあった。おかしいな…調べたときは本当になかったんだようなーと思いずつ更新履歴を見ると、2020年5月20日更新。私が調べたのは1月ごろだったから、その時はなかったということだ。うーん、What's Newはほぼ毎日見るけど、使っているサービスのドキュメント更新履歴も頻繁にチェックしないといけないのかな…。とりあえず、試してみることにした。
DefinitionS3Locationを試してみる
Step Functionsのテンプレートを準備
State Machineの定義はAWSドキュメントのGetting Started with Step Functionsにあるコードから最後のstateを少し変えた簡単な以下のコードを利用する。DefinitionSubstitutions
も使ってみたかったので。DefinitionSubstitutions
はテンプレート内で同時に作成されるリソースをState Machine内で利用する場合に使う。例えば、Lambdaを作成して、それをState machineに入れるとか。(LambdaのARNが必要になる)
{ | |
"Comment": "A Hello World example of the Amazon States Language using Pass states", | |
"StartAt": "Hello", | |
"States": { | |
"Hello": { | |
"Type": "Pass", | |
"Result": "Hello", | |
"Next": "Message" | |
}, | |
"Message": { | |
"Type": "Pass", | |
"Result": "${SubstitutionsMessage}", | |
"End": true | |
} | |
} | |
} |
jsonファイルで保存し、S3のバケットに保存する。
これでStep Functions側の準備は終わり。
CloudFormationテンプレートを準備
CloudFormationのStepFunctions::StateMachineのドキュメントページを参考し、State machineと紐づくIAM Roleを作るテンプレートを作成する。テンプレートは事前にS3にアップロードした。
AWSTemplateFormatVersion: "2010-09-09" | |
Resources: | |
TestStateMachine: | |
Type: AWS::StepFunctions::StateMachine | |
Properties: | |
StateMachineName: DefinitionS3LocationTest | |
DefinitionS3Location: | |
Bucket: your-bucket-name | |
Key: stepFunctionsTemplate.json | |
DefinitionSubstitutions: | |
SubstitutionsMessage: "World" | |
RoleArn: !GetAtt TestStateMachineRole.Arn | |
TestStateMachineRole: | |
Type: AWS::IAM::Role | |
Properties: | |
RoleName: DefinitionS3LocationTestRole | |
AssumeRolePolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- states.amazonaws.com | |
Action: | |
- "sts:AssumeRole" | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess |
これでCloudFormationのところも準備完了。
実行してみる
CloudFormationのページで新しいStackを生成した。
エラーなく完了している。Step Functions側もState machineが作成され、実行も問題ない。2個目のStateには定義ファイルではなく、CloudFormationのテンプレートのDefinitionSubstitutions
で入れたWorld
が入っていることがわかる。
疑問:定義ファイルの更新について
似たようにS3にコードを置けることができるLambdaの場合、パスが変わらないとファイルの中が変わっても更新がないことになる(Cloudformation側でS3まで見張ってないから当たり前なことだけど)。Step Functionsも同じ動きをすると思うけど、とりあえず試してみる。
まず、State machineの定義ファイルに追加のStateを入れて、S3のバケットにアップロードした。(gistのファイル名は後ろにeditをつけているが、実際は同じファイル名でアップロードし、バケットのファイルを更新した。)
{ | |
"Comment": "A Hello World example of the Amazon States Language using Pass states", | |
"StartAt": "Hello", | |
"States": { | |
"Hello": { | |
"Type": "Pass", | |
"Result": "Hello", | |
"Next": "Wait_for_it" | |
}, | |
"Wait_for_it": { | |
"Type": "Pass", | |
"Result": "Wait for it", | |
"Next": "Message" | |
}, | |
"Message": { | |
"Type": "Pass", | |
"Result": "${SubstitutionsMessage}", | |
"End": true | |
} | |
} | |
} |
そして、Stackをアップデートしてみると、予想通りに「何も変わってないよ」とエラーになる。
まとめ
DefinitionS3Location
を利用すれば、CloudFormationのテンプレートファイルに直接State machineの定義を書く必要なく、S3にアップロードして利用できる。しかし、外部ファイルになるので、Lambdaと同様に定義ファイル内のアップデートは検知できなくなってしまう。
また、CloudFormationのアップデートが割と頻繁に行わることがわかったので、できるだけドキュメントの更新履歴をチェックすることにしたいと思う。
最後に、このアップデートでCDKへの説得の材料が減ってしまったのは悲しい…。早めに更新の検知がCDKでできないか試してみよう…。