🎃

CDK StepFunctionsのデモ

2022/07/31に公開

ステートマシン

  • 同じLambda functionsでWait(10秒)を挟んでいる。

  • LambdaはSNSでメールを出すだけ。topic_arnをハードコードしてもよいが、.envで環境変数の設定もできる。

  • メールの例

2022-07-30 07:44:43
event:{'statusCode': 200, 'waitSeconds': 10}

  • Lambda はCloudWatchにprint出力するだけでもよい。

lib/test-stack.ts

lib/test-stack.ts
import { Stack, StackProps, Duration } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
import * as sns from 'aws-cdk-lib/aws-sns';

export class TestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const myTopic = sns.Topic.fromTopicArn(this, 'MyTopic', process.env.SNS_ARN ?? '');

    const fn = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.PYTHON_3_9,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'my_lambda.handler',
      environment: { 'SNS_ARN': myTopic.topicArn, },
    });

    const snsTopicPolicy = new iam.PolicyStatement({
      actions: ['sns:publish'],
      resources: ['*'],
    });

    fn.addToRolePolicy(snsTopicPolicy);

    const firstJob = new tasks.LambdaInvoke(this, 'Submit Job', {
      lambdaFunction: fn,
      outputPath: '$.Payload',
    });

    const waitX = new sfn.Wait(this, 'Wait X Seconds', {
      time: sfn.WaitTime.secondsPath('$.waitSeconds'),
    });

    const secondJob = new tasks.LambdaInvoke(this, 'Get Job Status', {
      lambdaFunction: fn,
      outputPath: '$.Payload',
    });

    const definition = firstJob
      .next(waitX)
      .next(secondJob);

    new sfn.StateMachine(this, 'StateMachine', {
      definition,
      timeout: Duration.minutes(5),
    });
  }
}

lambda/my_lambda.py

lambda/my_lambda.py
from datetime import datetime
import os

import boto3


def send_sns(message, subject):
    client = boto3.client("sns")
    topic_arn = os.environ["SNS_ARN"]
    client.publish(TopicArn=topic_arn, Message=message, Subject=subject)


def handler(event, context):
    time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    message = time + "\n event:" + str(event)
    subject = "From  Lambda"
    send_sns(message, subject)

    print("Hello!", time, event)

    return {'statusCode': 200,
            'waitSeconds': 10}

SNS使わないなら

my_lambda.py
from datetime import datetime

import boto3


def handler(event, context):
    time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    print("Hello!", time, event)

    return {'statusCode': 200,
            'waitSeconds': 10}

Discussion