AWS CDKで既存のASLファイルを使ってStep Functionsをデプロイする
「AWS CDKで既存のASLファイルを使ってStepFunctionsをデプロイしたい」
「既存のASLファイルを活かしつつAWS CDKでStep Functionsをデプロイしたいけど、L2 ConstructのStateMachineではファイルを渡せなさそう。」
ということがあり、少し調べたのでブログにします。
結論: L1 Construct(CfnStateMachine)を使えばできる。
// 結論部分の抜き出し // コード全文はブログ中にあります const file = fs.readFileSync('./step-functions/HelloWorld.asl.json') new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', { definitionString: file.toString(), stateMachineName: 'HelloWorld-CDK', roleArn: role.roleArn })
やってみた
今回は以下のワークフローをJSONでエクスポートして、エクスポートしたファイルをCDKで使ってデプロイします。
Workflow StudioでASLファイルをJSONでエクスポート
まずはASLファイルをJSONでエクスポートします。
以下のファイルをダウンロードできました。
{ "Comment": "A Hello World example of the Amazon States Language using Pass states", "StartAt": "Hello", "States": { "Hello": { "Type": "Pass", "Next": "World" }, "World": { "Type": "Pass", "Result": "World", "End": true } } }
CDKを書いてデプロイ
ディレクトリ構成は以下です。 ダウンロードしたjsonファイルは、step-functionsディレクトリを作ってその下に置きました。
├── README.md ├── bin │ └── index.ts ├── cdk.json ├── cdk.out │ └── 省略... ├── jest.config.js ├── lib │ └── StepFunctionStack.ts ├── node_modules │ └── 省略... ├── package-lock.json ├── package.json ├── step-functions │ └── HelloWorld.asl.json # ダウンロードしたjsonファイル ├── test │ └── cdk-stepfunctions-asl.test.ts └── tsconfig.json
#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { StepfunctionsStack } from '../lib/StepFunctionsStack'; const app = new cdk.App(); new StepfunctionsStack(app, 'StepfunctionsStack', {});
import * as cdk from 'aws-cdk-lib' import * as iam from 'aws-cdk-lib/aws-iam' import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions' import * as fs from 'fs' import { Construct } from 'constructs' export class StepfunctionsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props) const file = fs.readFileSync('./step-functions/HelloWorld.asl.json') // ステートマシン作成にIAM Role必須のため、今回の検証ではポリシーは不要 const role = new iam.Role(this, "StepFunctionsRole", { assumedBy: new iam.ServicePrincipal('states.amazonaws.com') }) new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', { definitionString: file.toString(), stateMachineName: 'HelloWorld-CDK', roleArn: role.roleArn }) } }
コード用意したらCDKデプロイします。
npm run cdk deploy
マネジメントコンソールから、指定したJSONファイルの内容のステートマシンが作成できたことを確認できました。
おまけ: Escape Hatch
L2 Constructを使いつつ、JSONファイルを渡したいパターンもあるかと思います。
そういった場合は、以下のように書くことで実現できます。
CDKのドキュメントで言うところのEscape Hatchです。
import * as cdk from 'aws-cdk-lib' import * as iam from 'aws-cdk-lib/aws-iam' import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions' import * as fs from 'fs' import { Construct } from 'constructs' export class StepfunctionsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props) const file = fs.readFileSync('./step-functions/HelloWorld.asl.json') // ステートマシン作成にIAM Role必須のため、今回の検証ではポリシーは不要 const role = new iam.Role(this, "StepFunctionsRole", { assumedBy: new iam.ServicePrincipal('states.amazonaws.com') }) // new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', { // definitionString: file.toString(), // stateMachineName: 'HelloWorld-CDK', // roleArn: role.roleArn // }) // Escape Hatch const statemachine = new stepfunctions.StateMachine(this, "HelloWorldMachineL2Construct", { definition: new stepfunctions.Pass(this, 'StartState'), role, stateMachineName: "HelloWorld-CDK-L2" }); const cfnStatemachine = statemachine.node.defaultChild as stepfunctions.CfnStateMachine; cfnStatemachine.definitionString = file.toString(); } }
おわりに
Step Functionsで既存のASLファイルを使って、CDKでデプロイする方法でした。
L1 Constructの使用やEscape Hatchは似たような問題の時にも役に立つと思います。
このブログが誰かの参考になったら幸いです。
以上、AWS事業本部の佐藤(@chari7311)でした。