[AWS]CodePipelineでStepFunctionsを実行する

## はじめに

AWS CodePipelineでStepFunctionsのステートマシンを実行します。

## 準備

S3バケットを2つとStepFunctionsのステートマシンを1つ用意します。S3バケットの1つは、バージョニングを有効にします。CodePipelineのソース(Source)ステージのアクションに使用するS3バケットは、バージョニング有効が条件のようです。

- S3バケット名
    - tmp-0wwkdvhvwz (バージョニング有効)
    - tmp-hokdvhvwzw


StepFuncitions ステートマシン `HOGE` を作成しました。ペイロード(入力値:JSON形式)の`HOGE`の値によって処理が分岐します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/982f4b15-7f7a-d283-8946-3f29adb462df.png)

```json:StepFunctionsステートマシンHOGE
{
  "Comment": "This is your state machine",
  "StartAt": "Choice",
  "States": {
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.HOGE",
          "NumericEquals": 100,
          "Next": "Pass HOGE 100"
        }
      ],
      "Default": "Pass HOGE Not 100"
    },
    "Pass HOGE 100": {
      "Type": "Pass",
      "End": true
    },
    "Pass HOGE Not 100": {
      "Type": "Pass",
      "End": true
    }
  }
}
```

## CodePipeline

パイプラインを作ります。

---
---

### パイプライン test001 (S3 -> S3)

S3バケットのデータを別のS3バケットに格納するパイプラインを作ります。（StepFunctionsは使用しません）
Sourceステージと、DeployステージにS3バケットを使用したアクションを設定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/e9d32661-6219-68ea-2927-5f451e03c77e.png)


```json:sample.json
{"HOGE": 50}
```

s3バケット `tmp-0wwkdvhvwz` に test/sample.zipをアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/46d7910b-75e0-ef21-d8d1-14207eaca31f.png)

---

sample.zipのアップロードを検知しパイプライン `test001` が実行を開始します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/155e6378-de0e-f2ce-3b12-692fd3d46863.png)


パイプライン `test001`実行により、s3バケット `tmp-hokdvhvwzw` にsample.jsonがアップロードされます。

```json:sample.json(s3バケットtmp-hokdvhvwzw)
{"HOGE": 50}
```

---
---


### パイプライン test002 (S3 -> StepFunctions-> S3)

S3バケット`tmp-0wwkdvhvwz`のデータを入力値としてStepFunctionsを実行します。また、StepFunctionsの実行結果をS3バケット`tmp-hokdvhvwzw`に出力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/131d5f5f-6120-c46a-0eef-391fa86d618b.png)


- SourceステージとDeployステージの間に、invokeステージを追加
- ① SouceステージのSourceアクションについて
    - S3バケット`tmp-0wwkdvhvwz`を指定
    - `test/hoges.zip`が更新された際にパイプラインが実行する
    - 出力アーティファクト名`SourceArtifact`とする
- ② invokeステージのStepFuncアクションについて
    - S3バケット`tmp-hokdvhvwzw`を指定
    - 入力アーティファクトを`SourceArtifact`とする
    - StepFunctions スマートマシン`HOGE`とする
    - 入力タイプをファイルパスとし、`hoge-200.json`とする
        - ※`hoges.zip`の中の`hoge-200.json`をStepFunctionに渡す
    - 出力アーティファクト名`hogeout`とする
- ③ DeployステージのDeployアクションについて
    - S3バケット`tmp-0wwkdvhvwz`を指定
    - 入力アーティファクトを`hogeout`とする


---

実行します
以下2つのファイルを圧縮した`hoges.zip`をS3バケット`tmp-0wwkdvhvwz`の`test/hoges.zip`としてアップロードします。

アップロードする`hoges.zip`の内容を変えて2回実施します

1回目の`hoges.zip`

```json:hoge-100.json
{"HOGE": 100}
```

```json:hoge-200.json
{"HOGE": 200}
```

2回目の`hoges.zip`

```json:hoge-100.json
{"HOGE": 100}
```

```json:hoge-200.json
{"HOGE": 100}
```

実行結果
1回目と2回目でStepFunctionsの処理が変わっていることを確認しました(期待した処理)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/13b65b2c-bcb8-ee99-ca68-4f3b060ee7e5.png)

また、S3バケット`tmp-hokdvhvwzw`の`test2/out.zip`を解凍すると`output.json`があります。

```json:2回目のoutput.json
{"HOGE": 100}
```

### (おまけ)パイプライン test002 に承認処理を加える

Sourceステージとinvokeステージに間にProcedureステージを作成し、承認処理を設定しました。承認依頼はメール送信なのでSNSトピックが必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/23a91da3-8355-ef72-9969-c0240ebc78d6.png)

---

実行します
実行すると、以下のようなメールが送信されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/9a2f51b5-aa93-c36f-b9e0-de0d73187c48.png)

メールにはパイプライン`test002`へのリンクがあり、パイプライン上のレビューボタンから却下/承認を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/a99b6d0f-0ae6-349b-50fb-2180d8393552.png)

承認処理を承認すると処理はそのまま実行されます。却下すると以下のようになり、その後の処理は実行されません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/fd33b8f8-621e-1474-8f14-656d5f797133.png" width="350">

---

実行者と承認者をわける権限設定について
承認プロセスを追加しても、実行者が承認できないように権限を設定する必要があります。動作確認はしていませんが、おそらく以下の権限割り当てでいけると思います。

- 実行者
    - S3バケット`tmp-0wwkdvhvwz`へファイルをアップロードする権限
    - パイプライン`test002`を閲覧する権限
        - IAMポリシー`AWSCodePipelineReadOnlyAccess`
- 承認者
    - パイプライン`test002`で承認できる権限
        - IAMポリシー`AWSCodePipelineApproverAccess`


※課題※ 承認者が、却下/承認の判断を楽にできる仕組みが必要そう。

---

## 最後に

CodePipelineとStepFunctionsを組み合わせると、運用にかかわる手順を自動化できそうです。