この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
「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でエクスポートします。
以下のファイルをダウンロードできました。
HelloWorld.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
bin/index.ts
#!/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', {});
lib/StepFunctionsStack.ts
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です。
lib/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
// })
// 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)でした。