AWS Step Functionsの新機能AWS SDK Service Integrationsを使ってみた

## はじめに
StepFunctionsに大きなアップデートがあり、AWS SDK Service Integrationsが使えるようになりました。

https://aws.amazon.com/jp/blogs/aws/now-aws-step-functions-supports-200-aws-services-to-enable-easier-workflow-automation/

> AWS Step Functionsは、新機能AWS SDK Service Integrationsにより、サポートするAWSサービスの数を17から200以上に、AWS API Actionsを46から9,000以上に拡大しました。

- 従来のStepFunctionsは手軽に始められる反面、[Optimized integrations](https://docs.aws.amazon.com/step-functions/latest/dg/connect-supported-services.html)に無いサービスを呼び出す場合、APIを呼び出すだけのLambda Functionを作る必要があり、構築、管理上の負担がありました
- 新機能のAWS SDK service integrationsは、StepFunctionsから直接呼び出せるAPIが増え、APIを呼び出すだけのLambda Functionが不要になりました
    
#### 新機能AWS SDK service integrationsで使用可能になったサービスの一覧
https://docs.aws.amazon.com/step-functions/latest/dg/supported-services-awssdk.html
    
## 処理の流れ
- DynamoDBからS3エクスポートを行う
  - DynamoDBのExportTableToPointInTimeのAPIを利用


https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ExportTableToPointInTime.html


 Step Functions Workflow Studioの左メニューにある、アクションからDynamoDBを選択
<img width="300" alt="action.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846185/ae60940e-68ed-6684-ec34-15f5419208ae.png">


ExportTableToPointInTimeのパーツを選択
<img width="300" alt="parts.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846185/471c1e6b-f284-0b75-bd56-7b0317e1f80d.png">


- 60秒待機して、エクスポート状態を確認する
  - DynamoDBのDescribeExportのAPIを利用

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeExport.html

同じくDynamoDBにあるDescribeExportのパーツを選択
<img width="300" alt="describe.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846185/b9eb7967-dc01-eeb1-29e2-20a9c9302a94.png">


- エクスポートが完了したら、終了とする
- (実運用上はエクスポート後に、Athenaから検索するための、パーティション化、データカタログ作成処理などがありますが、長くなるので本記事では割愛します)
    
## 構成
- ステートマシーン図 <br>

![state.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846185/18f29cac-edc2-f3f7-fc9e-e8851b860d09.png)

    

- ASL(Amazon States Language)
  - 以下2点を行えば、このまま動きます 
     - 対象のDynamoDBのポイントインタイムリカバリ (PITR)の有効化
     - IAMロール(DynamoDBへの操作権限、S3への書き込み権限)の設定

```json:state_machine.json
{
  "Comment": "This is your state machine",
  "StartAt": "ExportTableToPointInTime",
  "States": {
    "ExportTableToPointInTime": {
      "Type": "Task",
      "Parameters": {
        "S3Bucket.$": "$.s3Bucket",
        "TableArn.$": "$.tableArn",
        "S3Prefix.$": "$.s3Prefix"
      },
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:exportTableToPointInTime",
      "Next": "Wait",
      "ResultPath": "$.ExportTableResult"
    },
    "Wait": {
      "Type": "Wait",
      "Seconds": 60,
      "Next": "DescribeExport"
    },
    "DescribeExport": {
      "Type": "Task",
      "Parameters": {
        "ExportArn.$": "$.ExportTableResult.ExportDescription.ExportArn"
      },
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:describeExport",
      "Next": "Choice",
      "ResultPath": "$.DescribeExportResult"
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.DescribeExportResult.ExportDescription.ExportStatus",
          "StringEquals": "COMPLETED",
          "Next": "Success"
        },
        {
          "Variable": "$.DescribeExportResult.ExportDescription.ExportStatus",
          "StringEquals": "IN_PROGRESS",
          "Next": "Wait"
        }
      ],
      "Default": "Fail"
    },
    "Fail": {
      "Type": "Fail"
    },
    "Success": {
      "Type": "Succeed"
    }
  }
}
```

## StepFunctionsの実行時パラメータ
| key | value |
|:-:|:-:|
| tableArn | DynamoDBのARN |
| s3Bucket | エクスポート先のS3バケット [^1] |
| s3Prefix | エクスポート先のS3パスの先頭文字列 [^1] |

- エクスポート先のS3のパス構成<br>
`s3://${s3Bucket}/${s3Prefix}/AWSDynamoDB/{DynamoDBが付けるエクスポートのユニークID}/data/`

```json:input.json
{
  "tableArn": "arn:aws:dynamodb:ap-northeast-1:12345XXXXXXX:table/test_table",
  "s3Bucket": "dynamodb-export",
  "s3Prefix": "test-table"
}
```
## StepFunctions実行後
`s3://dynamodb-export/test-table/AWSDynamoDB/01635316601377-6eb6d317/data/`[^1]


この場所にDynamoDBのデータがエクスポートされています。

## 最後に
Lambda Functionをなるべく使わない構成はポータビリティ性が高く、運用保守面でも大きなメリットになります。
また、Terraformで管理を行っていますが、作成するリソースが少なくなる点もメリットでした。

- StepFunctions by Terraform

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sfn_state_machine



[^1]: エクスポート先のS3パス`s3://${s3Bucket}/${s3Prefix}/AWSDynamoDB/{DynamoDBが付けるエクスポートのkey}/data/`