Serverless Framework で Step Functions を設定する

## はじめに

今回はServerless Frameworkを使用して、Step Functionsのステートマシンを作成する方法をご紹介します。

今回ご紹介する方法は、Serverless FrameworkをDockerコンテナ上で実行する形にしています。

今回のサンプルプログラムは以下に置いてあります。
https://github.com/memememomo/sls-step-functions-sample


## プロジェクトディレクトリの作成

まずは、プロジェクト用のディレクトリを作成します。

```bash:プロジェクトディレクトリを作成
$ mkdir sls-step-functions-sample
$ cd sls-step-functions-sample
```

## Dockerの設定ファイル作成と初期化

Serverless FrameworkをDockerで実行するための設定ファイルを作成します。

```yaml:docker-compose.yml
version: '3'
services:
  sls:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - .:/opt/app
    env_file:
      - aws-credentials
```

```dockerfile:Dockerfile
FROM amaysim/serverless:1.60.0
WORKDIR /opt/app
COPY . /opt/app/
```

設定ファイルを作成したら、 docker-composeコマンドでビルドします。

```bash:ServerlessFrameworkの初期化
$ docker-compose build
```

## ServerlessFrameworkの初期化

Dockerコンテナ
上で、ServerlessFrameworkの初期化コマンドを実行します。

```bash:ServerlessFrameworkの初期化
$ docker-compose run sls sls create -t aws-nodejs
$ docker-compose run sls npm init -y
```

## ServerlessFrameworkのプラグインインストール

Step Functionsの設定をするために、プラグインをインストールする必要があります。以下のように、必要なプラグインをインストールします。

```bash:必要なプラグインをインストール
$ docker-compose run sls npm install -D serverless-pseudo-parameters
$ docker-compose run sls npm install -D serverless-step-functions
```

Step Functionsプラグインの他に、疑似パラメーターを使用できるようになるプラグインもインストールしています。このプラグインにより、 `#{AWS::AccountId}` や `#{AWS::Region}` などのパラメーターが設定ファイル上で使用できるようになります。

これらのプラグインを有効にするため、Serverless Frameworkの設定ファイルに追記します。

```yaml:serverless.yml
plugins:
  - serverless-step-functions
  - serverless-pseudo-parameters
```

## サンプル用のプログラムを作成

以下のように、`hello` と `world` をそれぞれ返す関数を定義します。

```javascript:handler.js
'use strict';

module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Hello',
      },
      null,
      2
    ),
  };
};

module.exports.world = async event => {
    return {
        statusCode: 200,
        body: JSON.stringify(
            {
                message: 'World',
            },
            null,
            2
        ),
    }
};
```

これらのLambda関数を作成するために、Serverless Frameworkの設定ファイルに追記します。

```yaml:serverless.yml
functions:
  hello:
    name: hello
    handler: handler.hello
  world:
    name: world
    handler: handler.world
```

## Step Functionsのステートマシンの設定

Step Functionsのステートマシンは正式にはJSONで定義するのですが、Serverless Frameworkの設定ファイルではYAMLで以下のように定義します。

```yaml:serverless.yml
stepFunctions:
  stateMachines:
    HelloWorld:
      name: hello-world
      definition:
        StartAt: Hello
        States:
          Hello:
            Type: Task
            Resource: arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:hello
            Next: World
          World:
            Type: Task
            Resource: arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:world
            End: true
```

helloとworldを順番に実行するステートマシンを定義しています。

<img width="721" alt="スクリーンショット 2019-12-22 11.54.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278/dcb9d100-900c-fd69-54f0-241bb91b0c6d.png">


## デプロイと実行

以上で、ひととおりの設定が終わったので、以下のコマンドでデプロイします。

```bash:デプロイ
$ docker-compose run sls sls deploy
```

コマンドの実行が終わると、AWS上のStep Functionsのステートマシンが作成されます。「実行の開始」ボタンを押して実行すると、ステートマシンが正常に実行されることが確認できます。


<img width="715" alt="スクリーンショット 2019-12-22 11.34.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278/2d316671-8492-3966-af7d-560aea5d7a9d.png">

以上が、Step Functionsの設定の流れとなります。


## おわりに

Serverless Frameworkで、Step Functionsの設定を行う方法をご紹介しました。とっかかりとして、参考にしていただければ幸いです。