AWS Step Functions 値の受け渡しについて


こんにちは。GxPの2年目の伊藤です。
この記事は[グロースエクスパートナーズ アドベントカレンダー](https://qiita.com/advent-calendar/2020/gxp)の6日目の記事となります。

「今年の学び」がテーマということで、僕は今年の4月から案件が変わりAWSへ移行する案件に就くことになりました。AWSについてほとんど知識のない状態でしたが、仕事を通してAWSについてだけではなく多くのことを学ばせてもらいました。
今回の記事はTerraformで管理しているStep FunctionsでECS Taskを実行したときに値を渡したかったのですが、そのやり方で詰まったのでその方法の紹介になります。

#構成
CloudWatch Eventsから直接ECS Taskを起動することもできますが、監視をしやすくするためにStep Functionsを挟んでいます。

![スクリーンショット 2020-12-02 10.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906528/a4cd118b-6144-703b-c9c7-c2d6fca1693a.png)



バージョン
Terraform: 0.12.20
aws provider: 3.13.0

#Step Functionsから値を受け渡す
上記の構成だったのですが、ECS Task実行時に値を渡す必要が出てきました。そこで、Step Functionsから値を受け渡して実行できるようにしなくてはなりませんでした。
僕たちの案件ではAWSのリソースをTerraformで管理していたため、Step Functionsだと実行時のポップアップのJSONがECS Taskに値を渡す場所になりますが、Terraformだとどのように書くのかわからず詰まってしまいました。

[こちら](https://dev.classmethod.jp/articles/step-functions-parameters/)でStepFunctionsの入出力制御について丁寧に説明されています。
参考にするとState InputがStep Functions実行時のポップアップのJSONに当たります。今回はここから値を入れてあげたいのですが、どうやればよいのか分からなかったという話です。
![スクリーンショット 2020-12-01 1.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906528/639a39ae-392e-5bcd-0af3-3a15ddbaca5d.png)
##Step Functionsの定義
StepFunctionsでECSを操作についての[AWSのドキュメント](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-ecs.html)を参考にするとOverridesを使うとStep FunctionsからECSへ値を渡せるようでした。そこで以下のようにStep Functionsのoverridesを定義することで環境変数を設定することができました。

```json:StepFunctionsの定義
  "Parameters":{
    "Overrides":{
      "ContainerOverrides":[
        {
          "Environment":[
            {
              "Name":"hoge",
              "Value.$":"$.VALUE"
            }
          ],
          "Name":"hoge-task"
        }
      ]
    },
```

これによりECS Taskにhogeという名前でState Inputから受け取ったVALUEの値を環境変数として設定し、値を渡すことができるようになります。$.を使うことによって実行中のJSONの値を取り出すことができます。

**注意1**：渡し先のECS TaskのNameもちゃんと設定してあげないとエラーになります。

**注意2**：.$を使う場合はダブルクォーテーションで括ってあげないとちゃんと認識してもらえませんでした。

**注意3**：StepFunction定義のキーに .$を使って値をパス解決させた場合、実行時にJson-pathが表すキーが存在しないとエラーになります。つまり、State Inputにキーを与えないといけません。
![kako-t3DYfD7a8M2FAXxl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906528/8fa70388-bf23-7fbd-a820-7ed04b45d681.png)



##CloudWatch Eventsの定義
このままではCloudWatch Eventsから実行したときにJson-pathが表すキーが存在しないため、CloudWatch EventsからStepFunctionsに渡すinputを設定しました。
Step FunctionsにVALUEという名前で値を渡してくれます。

```terraform:CloudWatchEvents
resource "aws_cloudwatch_event_target" "cloudwatch_event" {
  ...
  input    = "{\"VALUE\" : \"\"}"
}

```



#確認
Step Functionsの手動実行時のポップアップのJSONに画像のようにキーを設定し、実行後TaskSubmittedのjsonのEnvironmentのNameとValueが設定されていればECS Taskに値を渡すことができるています。
![スクリーンショット 2020-12-01 17.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906528/5df9983d-97d5-de6a-c0a4-adde576cf967.png)



```json:TaskSubmitted
    "Overrides": {
      "ContainerOverrides": [
        {
          "Command": [],
          "Environment": [
            {
              "Name": "hoge",
              "Value": ""
            }
          ],
          "EnvironmentFiles": [],
          "Name": "hoge-task",
          "ResourceRequirements": []
        }
      ],
      "InferenceAcceleratorOverrides": []
    }
```


最終的に以下のように値の受け渡しがされています。
![スクリーンショット 2020-12-03 11.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906528/1efc76d0-427a-504a-a975-7880c8dcc31f.png)


#今回の学び
ほとんど分からなかった状態からチームメンバーの助けを借りつつも自分で調べて解決することができたので自信を付けることが出来ました。
AWSのドキュメントは難解なところはありましたが、ちゃんと読み解くと欲しい情報は結構書いてあったりするので他の記事を参考にしつつも頑張って読むことが大切だなと思いました。
これからも多くのことに触れて学びを増やしていこうと思います。