Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
【Developers.IO 2020 CONNECT】AWS CDK + Step Func...
Search
Sato Naoya
July 03, 2020
Programming
3.3k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
【Developers.IO 2020 CONNECT】AWS CDK + Step Functions 入門
Sato Naoya
July 03, 2020
More Decks by Sato Naoya
See All by Sato Naoya
Cloudflare AgentsとAI SDKでAIエージェントを作ってみた
briete
0
1.2k
Cloudflare Workersのユースケースと開発方法
briete
0
4.1k
re:Invent 2019 サーバーレス関連アップデート
briete
0
1.1k
Other Decks in Programming
See All in Programming
Jetpack Compose Mechanisms
skydoves
2
510
Are APIs Still Relevant in the AI Era?
soyuka
0
430
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
350
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
450
The Rails Doctrine Decade
koic
2
510
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
450
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
350
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
450
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
920
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.5k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
Featured
See All Featured
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
Why Our Code Smells
bkeepers
PRO
340
58k
Product Roadmaps are Hard
iamctodd
55
13k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Accessibility Awareness
sabderemane
1
240
Abbi's Birthday
coloredviolet
4
10k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Exploring anti-patterns in Rails
aemeredith
4
520
The Cost Of JavaScript in 2023
addyosmani
55
10k
ラッコキーワード サービス紹介資料
rakko
1
5.2M
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Transcript
AWS CDK + Step Functions ⼊⾨ 2020/7/2 Developers.IO 2020 CONNECT
クラスメソッド株式会社 CX事業本部 佐藤直哉
2 このセッションについて • AWS Step Functionsの簡単な概要 • AWS CDKの簡単な概要 •
AWS CDK と Step Functionsを使ったステートマシンの 実装⽅法について • ⾔語はTypeScript、実⾏基盤は AWS Lambdaを前提とし ています。
3 ⾃⼰紹介 クラスメソッド株式会社 CX事業本部 MAD(Modern Application Development)チーム サーバーサイドエンジニア 佐藤直哉(Sato Naoya)
4 アジェンダ l AWS Step Functionsとは l AWS CDKの登場 l
ステートマシンにおけるAWS CDKの実装⽅法につ いて
5 AWS Step Functionsとは
6 AWS Step Functionsとは
7 AWS StepFunctionsとは l サーバーレスなワークフロー処理を作成することが できるサービス l ステートマシン l ワークフロー全体の処理のこと
l ステートマシン⼀つ⼀つの処理単位のことをStateと呼ぶ l ユースケース l 複数のLambda関数を順次的に処理したい l アプリケーションのジョブ機能として使う l Lambda単体では処理しきれない⼤容量ファイルを並列 に処理する
8 ステートマシンの構成要素について
9 Stateとは l ステートマシンにおける 処理の単位のこと l 全部で7つの種類があり ます l Task
l Wait l Parallel l Pass l Choice l Succeed l Fail
10 Task 単⼀の処理を⾏う基本的な State l タスクの実⾏基盤として、AWS Lambda、ECS等を選択するこ とができます l 基本的には、このTaskを組み合
わせてステートマシンを構成し ていくことになります start end 最初の処理 次の処理
11 Pass 前stateのoutputをそのままパ ススルーするstate l デバッグ⽤途で使うことが多い l 前stateのoutput JSONがその まま流れてくるので、その値を
確認したりするのに使う l とりあえず、全体のステートマ シンをPassで定義して、あとか らPassをTaskに置き換えていく という⽅法も取れる start end 処理 Pass
12 Wait 最初の処理 Start End 10秒待つ 最後の処理 指定された時間を待機する State l
StateとStateの間に⼊り、指定 された時間待機する
13 Parallel 並列に処理を実⾏するState l 複数のTask(Lambda)を並列 に処理させることができる l Parallel内の全てのStateが実⾏ されたら処理3に遷移する 並列処理1
並列処理2 start end 処理3
14 Choice 条件により分岐するState l IF⽂のように条件によって分岐 させるState l 処理1のoutputを受け取り、 ChoiceStateはその値により、 分岐させます
処理1 ChoiceState 処理2 処理3 処理4 start end
15 Succeed, Fail 成功か失敗かを定義するState l 前のChoiceと組み合わせて、 Choiceの結果に合わせて、ス テートマシンが成功したか失敗 したかをマークするなどで使う l
Succeed、Failに到達した段階 でステートマシンは終了する ChoiceState 処理 Succeed 処理 Fail start end
16 Map 動的並列処理を⾏うState l inputに配列を受け取り、配列 の数だけ処理を繰り返すState start 処理1 処理2
17 ASL(Amazon State Language) ASLと呼ばれるJSONベー スの⾔語を使ってステー トマシンを定義
18 ASLの⾟み l JSON形式の⾔語のため、あ る程度処理が複雑化してくる と、処理を追うのが⼤変にな る l プログラミング⾔語ではない ため、ある程度の複雑さがあ
ると可読性が悪くなってしま う
19 そこでAWS CDKが登場します
20 AWS CDKとは
21 AWS CDKとは l TypeScriptやPythonといったプログラミング⾔語を 使ってAWSリソースを定義する事ができるツール l Constructというライブラリを使うことで、 CloudFormationよりも少ない⾏数で記述が可能
22 Constructとは https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html
23 AWS CDKのメリット l 使い慣れたプログラミング⾔語でAWSリソースを定 義することができる l IDEの恩恵を受けることができる l CloudFormationや独⾃⾔語(今回の場合だとASL)
がConstructによって抽象化されているため、通常よ りも少ない記述量でリソースを定義することができ ます
24 AWS CDKにおけるステートマシンの実装⽅ 法について
25 AWS CDKプロジェクトの作成
26 AWS CDKのインストール npm install –g aws-cdk
27 CDKプロジェクトの作成 mkdir stepfunctions-sample cd stepfunction-sample cdk init app –language=typescript
28 ディレクトリ構成
29 AWS CDK Constructのインストール npm install –d @aws-cdk/aws-lambda npm install
–d @aws-cdk/aws-stepfunctions npm install –d @aws-cdk/aws-stepfunction-tasks
30 Lambda(タスク)のサンプルコード handlers/task.ts export async function handler(event: any): Promise<TaskResponse> {
console.log(JSON.stringify(event)); return { title: 'Hello’, message: 'World’, }; } type TaskResponse = { title: string; message: string; }
31 スタックのコード lib/stepfunction-sample-stack.ts import * as cdk from '@aws-cdk/core'; import
* as lambda from '@aws-cdk/aws-lambda'; import * as sfn from '@aws-cdk/aws-stepfunctions'; import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; export class StepfunctionsSampleStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // ここにAWSリソースを定義していく } }
32 スタックのコード lib/stepfunction-sample-stack.ts import * as cdk from '@aws-cdk/core'; import
* as lambda from '@aws-cdk/aws-lambda'; import * as sfn from '@aws-cdk/aws-stepfunctions'; import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; export class StepfunctionsSampleStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); } } 先程インストールした、Constructライブラ リをimportします。
33 ステートマシンの基本的な実装⽅法
34 Taskの順次処理(Next) l 基本的なNextでタスク同⼠を順 次処理させる⽅法です。 l AWS CDKでは .next() を使う
ことで簡単にタスクをつなげる ことができます。 start end 最初の処理 次の処理
35 Taskの順次処理(Next) lib/stepfunctions-sample-stack.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, });
36 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); タスクの処理を実⾏する Lambda関数を作成します
37 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを定義します。
38 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを定義します。 aws-stepfunctions-tasksライブラリのクラスを 使うことで、Lambdaを実⾏基盤としたタス クを定義することができます。
39 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを定義します。 lambdaFunctionsに上で定義したtaskFnインス タンスを渡します。
40 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを定義します。 outputPath には Taskの output を指定します。 $.Payload を指定することで, Lambdaの戻り 値を次のTaskに渡すことができます
41 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを定義します。 inputPath にはoutputPathから何を Taskの input とするかを指定します。 $とすることで、上のTaskのJSONがすべて Inputに渡ることになります。
42 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); Taskを .next() でつなげます。
43 Taskの順次処理(Next) lib/stepfunctions-sample.ts const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler’, }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload’, }); const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); ステートマシンを作成します。
44 デプロイ npm run build npm run cdk deploy
45 デプロイされたステートマシン図
46 他のStateについても実装してみます
47 Wait(再掲) 最初の処理 Start End 10秒待つ 最後の処理 指定された時間を待機する State この例だと、最初の処理が終わっ
てから、10秒後に最後の処理が実 ⾏されることになります。
48 Wait(AWS CDKで実装) const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const wait10 = new sfn.Wait(this, '10秒待つ', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)), }) const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(wait10).next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); lib/stepfunctions-sample-stack.ts Wait Stateを定義して、WatiTimeクラスの durationを使って秒数を指定します
49 Wait(AWS CDKで実装) const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const firstState = new tasks.LambdaInvoke(this, '最初の処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const wait10 = new sfn.Wait(this, '10秒待つ', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)), }) const secondState = new tasks.LambdaInvoke(this, '次の処理', { inputPath: '$.message’, lambdaFunction: taskFn, }); const definition = firstState.next(wait10).next(secondState); new sfn.StateMachine(this, 'stateMachine', { definition: definition, }); lib/stepfunctions-sample-stack.ts 先程と同じく.nextでつなげます。
50 デプロイ
51 Parallel(再掲) 並列に処理を実⾏するState 並列処理1 並列処理2 start end 処理3
52 Parallel(AWS CDKで実装) const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const paralellState1 = new tasks.LambdaInvoke(this, '並列処理1', { lambdaFunction: taskFn, }); const paralellState2 = new tasks.LambdaInvoke(this, '並列処理2', { lambdaFunction: taskFn, }); const wait10 = new sfn.Wait(this, '10秒待つ', { time: sfn.WaitTime.duration(cdk.Duration.minutes(10)), }) const parallel = new sfn.Parallel(this, 'Parallel'); parallel.branch(paralellState1, paralellState2).next(wait10); new sfn.StateMachine(this, 'stateMachine', { definition: parallel, }); lib/stepfunctions-sample-stack.ts
53 Parallel(AWS CDKで実装) const taskFn = new lambda.Function(this, 'TaskFn', {
runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const paralellState1 = new tasks.LambdaInvoke(this, '並列処理1', { lambdaFunction: taskFn, }); const paralellState2 = new tasks.LambdaInvoke(this, '並列処理2', { lambdaFunction: taskFn, }); const wait10 = new sfn.Wait(this, '10秒待つ', { time: sfn.WaitTime.duration(cdk.Duration.minutes(10)), }) const parallel = new sfn.Parallel(this, 'Parallel'); parallel.branch(paralellState1, paralellState2).next(wait10); new sfn.StateMachine(this, 'stateMachine', { definition: parallel, }); lib/stepfunctions-sample-stack.ts branch()メソッドで、並列処理するstate を指定します。
54 デプロイ
55 Choice(再掲) 条件により分岐するState 処理1 ChoiceState 処理2 処理3 処理4 start end
56 Choice(AWS CDKで実装) lib/stepfunctions-sample-stack.ts const taskFn = new lambda.Function(this, 'TaskFn',
{ runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const task = new tasks.LambdaInvoke(this, '処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const choice = new sfn.Choice(this, 'ChoiceState'); choice.when(sfn.Condition.stringEquals('$.message', 'Hello'), new sfn.Pass(this, '処理1')); choice.when(sfn.Condition.stringEquals('$.message', 'World'), new sfn.Pass(this, '処理2')); choice.otherwise(new sfn.Pass(this, '処理3')); const definition = task.next(choice); new sfn.StateMachine(this, 'stateMachine', { definition });
57 Choice(AWS CDKで実装) lib/stepfunctions-sample-stack.ts const taskFn = new lambda.Function(this, 'TaskFn',
{ runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const task = new tasks.LambdaInvoke(this, '処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const choice = new sfn.Choice(this, 'ChoiceState'); choice.when(sfn.Condition.stringEquals('$.message', 'Hello'), new sfn.Pass(this, '処理1')); choice.when(sfn.Condition.stringEquals('$.message', 'World'), new sfn.Pass(this, '処理2')); choice.otherwise(new sfn.Pass(this, '処理3')); const definition = task.next(choice); new sfn.StateMachine(this, 'stateMachine', { definition }); when()メソッドで、分岐条件を定義します
58 Choice(AWS CDKで実装) lib/stepfunctions-sample-stack.ts const taskFn = new lambda.Function(this, 'TaskFn',
{ runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const task = new tasks.LambdaInvoke(this, '処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const choice = new sfn.Choice(this, 'ChoiceState'); choice.when(sfn.Condition.stringEquals('$.message', 'Hello'), new sfn.Pass(this, '処理1')); choice.when(sfn.Condition.stringEquals('$.message', 'World'), new sfn.Pass(this, '処理2')); choice.otherwise(new sfn.Pass(this, '処理3')); const definition = task.next(choice); new sfn.StateMachine(this, 'stateMachine', { definition }); Conditionクラスを使って条件を記述します この場合は、前のタスクから渡されてきた $.PayloadのmessageがHelloという⽂字列なら 次の引数のStateに遷移するという意味にな ります。
59 Choice(AWS CDKで実装) lib/stepfunctions-sample-stack.ts const taskFn = new lambda.Function(this, 'TaskFn',
{ runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('handlers’), handler: 'task.handler', }); const task = new tasks.LambdaInvoke(this, '処理', { lambdaFunction: taskFn, outputPath: '$.Payload', }); const choice = new sfn.Choice(this, 'ChoiceState'); choice.when(sfn.Condition.stringEquals('$.message', 'Hello'), new sfn.Pass(this, '処理1')); choice.when(sfn.Condition.stringEquals('$.message', 'World'), new sfn.Pass(this, '処理2')); choice.otherwise(new sfn.Pass(this, '処理3')); const definition = task.next(choice); new sfn.StateMachine(this, 'stateMachine', { definition }); otherwise()で条件にあてはまらなかった場合 のstateの遷移先を指定します。
60 デプロイ
61 まとめ l AWS CDKを使うことで、JSONベースなASLを書か なくとも、TypeScriptやPythonのようなプログラミ ング⾔語でStep Functionsのワークフローを書くこ とができる l
ASLで書くよりも直感的に実装できる
62 参考⽂献 l https://docs.aws.amazon.com/cdk/api/latest/ docs/aws-stepfunctions-readme.html l https://docs.aws.amazon.com/cdk/api/latest/ docs/aws-stepfunctions-tasks-readme.html
None