この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
「ASLファイルの変更をトリガーにStepFunctionsを自動デプロイしたい」
GitHub等ででASLファイルを管理している環境で、ASLファイルの変更があった際に自動でStepFunctionの設定も更新できるようにしたいことがありました。
今回は以下の構成でやってみました。
- IaCツール: AWS CDK
- CI/CDツール: Github Actions
IaCツールやCI/CDツールが異なる場合も、基本的には同じような流れで実行できるかと思います。 (例えば、IaCツールがTerraformだったらcdk deployの部分をterraform applyに変える等。)
概要
- AWS CDKでStep Functionsを作成
- ASLファイルの変更をトリガーにGithub Actionsを実行
- Github Acitions上でAWS CDKを使用して環境を更新(cdk deploy)
StepFunctionsはIaCツール(AWS CDK)で作成します。
IaCツールでStepFunctionsを作成するメリットとしては、複数のステートマシンを作成したい場合もCI/CDパイプラインを組むのが容易だからです。
ASLファイルの変更をトリガーにCI/CDツール上で、「aws stepfunctions update-state-machine」コマンドを実行してステートマシンを更新することも可能かと思います。
しかし、ワークフローの数が増えていくとその分コマンドを増やす・または何かしらのスクリプト作成の必要があります。
CIツールで実行するコマンド(awscliで更新するパターン)
aws stepfunctions update-state-machine --state-machine-arn <state-machine AのARN> --definition <state-machin A definition>
aws stepfunctions update-state-machine --state-machine-arn <state-machine BのARN> --definition <state-machin B definition>
aws stepfunctions update-state-machine --state-machine-arn <state-machine CのARN> --definition <state-machin C definition>
# 数が増えると追加が必要
IaCツールで作成する場合は、ステートマシンが増えてもコマンドを変更する必要はありません。 (IaCツール内で作成するステートマシンの記述は必要です)
CIツールで実行するコマンド(cdkで更新するパターン)
npm ci
npm run cdk deploy "*" --require-approval never
やってみた
コードは以下にあります。
msato0731/cdk-stepfunctions-asl
AWS CDKで環境を用意する
CDKのコードでは既存のASLファイルを使うため、今回はL1 Constructを使用しています。 Github Actionsで使うIAMロールも同じスタックで作成しています。
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 { GithubActionsIdentityProvider, GithubActionsRole } from 'aws-cdk-github-oidc';
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)
// すでにProvider作成済みのため
const provider = GithubActionsIdentityProvider.fromAccount(this, this.account)
// Provider存在しない場合は、以下の記述が必要
// const provider = new GithubActionsIdentityProvider(this, 'GithubProvider');
const githubActionsRole = new GithubActionsRole(this, 'GithubActionsRole', {
provider: provider,
owner: 'msato0731', // 書き換え必要
repo: 'cdk-stepfunctions-asl',
roleName: 'stepfunctions-gh-deploy-test',
maxSessionDuration: cdk.Duration.hours(2),
});
// デプロイ検証用のため強めの権限付与
githubActionsRole.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess") )
new cdk.CfnOutput(this, "GithubActionsRoleArn", {
value: githubActionsRole.roleArn
})
// ステートマシン作成にIAM Role必須のため、今回の検証ではポリシーは不要
const stepFunctionsRole = new iam.Role(this, "StepFunctionsRole", {
assumedBy: new iam.ServicePrincipal('states.amazonaws.com')
})
// ステートマシン作成
const file = fs.readFileSync('./step-functions/HelloWorld.asl.json')
new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', {
definitionString: file.toString(),
stateMachineName: 'HelloWorld-CDK',
roleArn: stepFunctionsRole.roleArn
})
}
}
補足: ステートマシン追加
「CfnStateMachine」を以下のように追加することで、ステートマシンを追加できます。
lib/StepFunctionsStack.ts
// 省略
const file = fs.readFileSync('./step-functions/HelloWorld.asl.json')
new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', {
definitionString: file.toString(),
stateMachineName: 'HelloWorld-CDK',
roleArn: stepFunctionsRole.roleArn
})
// ステートマシン追加
const file2 = fs.readFileSync('./step-functions/HelloWorld2.asl.json')
new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine2', {
definitionString: file.toString(),
stateMachineName: 'HelloWorld-CDK2',
roleArn: stepFunctionsRole.roleArn
})
Github ActionsのシークレットにIAMロールをセット
「cdk deploy」を実行して作成されたCloudFormationスタックの出力を確認します。 IAMロールARNが出力されるため、これをコピーしておきます。
GithubActionsのシークレットに以下を追加します。
- シークレット名: AWS_IAM_ROLE_ARN
- 値: [コピーしたIAMロールARN]
Github Actionsのワークフローファイルを用意
CDKデプロイ用のワークフローファイルを用意します。
mainブランチにPR時に、cdk diffを実施します。 mainブランチでpushしたタイミング(PR マージ)時に、cdk deployが実行されます。
deploy-cdk.yml
name: deploy-cdk
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
deploy-cdk:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
aws-region: ap-northeast-1
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '16'
- name: CDK package install
run: npm ci
- name: CDK Diff Check
if: contains(github.event_name, 'pull_request')
run: |
npm run cdk -- diff "*"
- name: CDK Deploy
if: contains(github.event_name, 'push')
run: |
npm run cdk -- deploy --require-approval never "*"
動作確認
修正前は、以下の状態です。
ASLファイルを修正して、PRを作成します。 「StepFunctions」という名前で、Pass Stateを追加しました。
PR時にはGithub Actionsによってcdk diffが実行されるため変更差分を確認します。
変更差分が問題なければ、マージします。 Github Actionsによって、「cdk deploy」が自動で実行されます。
マネジメントコンソール上からも、変更が適用されたことが確認できました
おわりに
CIツールにGithub Actions・IaCツールにAWS CDKを使用して、ASLファイルの変更があった際にステートマシンに変更を自動反映させる方法でした。
誰かの参考になれば幸いです。
以上、AWS事業本部の佐藤(@chari7311)でした。