AWS Application Composerを使うと、動的参照があるStep Functionsを簡単に作れる

# はじめに
Step FunctionsをCloudFormationで作る際、以下のようなことを行っていて面倒でした。

1. CloudFormationで、簡単なStep Functionsを書いて作成
1. 作られたStep FunctionsをコンソールのWorkflow Studioから修正
1. 修正後のASLで、CloudFormationテンプレートのStep Functionsの箇所を差し替え
1. Lambda関数などを使う場合は、該当箇所を変数に差し替え
1. スタックを更新
1. 2.から5.を繰り返して調整

Application Composerでは、Workflow Studioが使えるようになっており、リソースを動的に参照できます。

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/use-wfs-in-app-composer.html

そのため最初に書いたような、差し替えして文字列置き換え、のような面倒なことがしなくて済むようになります。

今回はこの内容について、簡単に確認してみました。

# 概要

- AWS Application Composerで、Step FunctionsがあるSAMテンプレートを作成
    - その際Workflow Studioを使うことで、リソースを動的参照するコードが生成されることを確認
- AWS Application Composerは、PCにインストールしたVSCodeで実行
- SAMは、Cloud9を構築して実行

# やってみた

## 準備
VSCodeの拡張機能で、`AWS Toolkit`を検索してインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/5ce7722e-727e-578a-5796-7b0680e1a17c.png)


フォルダを作って、`template.yaml`を作り、`Open with Application Composer`で開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/297b431f-6d70-cef8-46d8-43ad0a964b36.png)

## Lambda関数を１つ設置

Lambda関数を置きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1309b52b-4cc7-f8d7-3022-8b6ae852c5ae.png)
ランタイムをPythonにしておきます。（3.9にしているのは、この後Cloud9で動かす際に、デフォルトでインストールされているバージョンのためです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/78060ad0-6ae0-d066-8ef4-192f715fe82e.png)



Step Functionsステートマシンを置きます。デフォルトでLambda Taskが作られています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/0ea5f481-28d9-8ba1-6800-3cdc08a5fadf.png)


Lambda TaskとLambda関数を結びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/9f8396ca-d545-8adb-c959-498c74d35588.png)
Composer上の詳細では以下のように紐づけられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/f0a9ec39-3335-9f1c-32f5-a28486635d51.png)


Cloud9上に移して、SAMで動かしていきます。
```bash
sam build
sam validate

sam deploy --guided
```

作成されたASLは以下になります。
```json
{
  "StartAt": "LambdaTask",
  "States": {
    "LambdaTask": {
      "End": true,
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-Function-CAnigRNGzDvR",
        "Payload.$": "$"
      },
      "Resource": "arn:aws:states:::lambda:invoke",
      "Type": "Task"
    }
  }
}
```
以前であれば、「コンソールのWorkflow Studioから修正されたASLをコピペして、Lambda関数の個所を変数に置き換える」ということをやっていましたが、AWS Application Composerを使えばそのような手間がなくなりました。

## Workflow Studioを使って、Lambda関数をもう一つ設置
Lambda関数をもう一つ作って、Step Functionsに追加してみます。

AWS Application ComposerのWorkflow Studioを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/5f4464b3-b8c9-8152-bc9f-688578872b71.png)

2個目のLambda関数を設置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/130c4910-1259-1ac0-7ddb-7097b9429a45.png)
Function nameを、`CloudFormation 置換を入力`にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/02a8a02e-8f47-8e6e-8e03-f496ed9617b7.png)
変数名を指定します。ここでは`${LambdaFunction2}`としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8b0f0eb4-e53c-f61f-30db-379aec41ab9f.png)
右上で保存をして、Application Composerに戻ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/fdd5265c-a984-65de-44ce-34bcb4349013.png)

Step Functionsに2つ目のLambdaが認識されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/1e63375d-10a5-134b-c2c3-63f3598540b2.png)
Lambdaをもう一つ追加して、繋いでみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/786e6ab7-5241-be39-4efe-4598b7954069.png)
変数のマッピングも作ってくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/8ba4f9b8-f343-eb5f-ae7b-561dbd4f47cf.png)

再度、上げなおしてデプロイします。
作られたASLは以下で、ちゃんとLambda関数の部分が置換されています。
```json
{
  "StartAt": "LambdaTask",
  "States": {
    "Lambda Invoke": {
      "End": true,
      "OutputPath": "$.Payload",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-Function2-M8Ljf0sG9Hfo",
        "Payload.$": "$"
      },
      "Resource": "arn:aws:states:::lambda:invoke",
      "Retry": [
        {
          "BackoffRate": 2,
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException",
            "Lambda.TooManyRequestsException"
          ],
          "IntervalSeconds": 1,
          "MaxAttempts": 3
        }
      ],
      "Type": "Task"
    },
    "LambdaTask": {
      "Next": "Lambda Invoke",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-Function-CAnigRNGzDvR",
        "Payload.$": "$"
      },
      "Resource": "arn:aws:states:::lambda:invoke",
      "Type": "Task"
    }
  }
}
```
## 片付け
`sam delete`でAWS上のリソースは削除されます。ロググループは保持されていますので、コンソールから削除してください。

Cloud9やPCで作成したファイル群は適宜削除してください。

# おわりに
今回はApplication ComposerのWorkflow Studioを使うことで、Step Functionsのリソースの動的参照を簡単に実現してみました。
これでStep FunctionsのIaC化がかなりはかどるのではないでしょうか。

この記事がどなたかのお役に立てれば幸いです。