🔁
Step FunctionsでNextTokenを返すAPIをループ処理する
AWS Step Functionsで、レスポンスアイテム数に上限があってNextToken/Maker/ContinuationToken等を返すList/Describe APIの結果を全部ループして処理する方法です。
Map
ステートで1レスポンス内のリストをループ処理し、さらにそれをループするようなステートマシンを作成します。
参考
こちらをパク参考にしました。
サンプル
IAM ListRoles APIで、アカウントに存在するロールをすべてリストして処理するサンプルです。
このAPIは、MaxItems
を超えるロールがまだ存在するときMarker
(NextToken)を返します。続いて、その値をリクエストに含めてAPIを実行することで、残りのロール一覧を取得できます。それでもすべてのロールを取得できていない場合は、さらに別のMarker
を返します。
CloudFormationテンプレート
AWSTemplateFormatVersion: 2010-09-09
Resources:
StateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: states.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: StepFunctionsPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- iam:ListRoles
Resource: '*'
StateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: !Sub ${AWS::StackName}-StateMachine
StateMachineType: STANDARD
RoleArn: !GetAtt StateMachineRole.Arn
DefinitionString: |
{
"Comment": "Sample state machine handling paginated API responses",
"StartAt": "ListRoles",
"States": {
"ListRoles": {
"Type": "Task",
"Parameters": {
"MaxItems": 30
},
"Resource": "arn:aws:states:::aws-sdk:iam:listRoles",
"Next": "ForEachRole"
},
"ForEachRole": {
"Type": "Map",
"ItemsPath": "$.Roles",
"MaxConcurrency": 1,
"ItemProcessor": {
"ProcessorConfig": {
"Mode": "INLINE"
},
"StartAt": "DoSomething",
"States": {
"DoSomething": {
"Type": "Pass",
"End": true
}
}
},
"ResultPath": null,
"Next": "IfNextTokenExists"
},
"IfNextTokenExists": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.Marker",
"IsPresent": true,
"Next": "ListMoreRoles"
}
],
"Default": "Success"
},
"ListMoreRoles": {
"Type": "Task",
"Parameters": {
"MaxItems": 30,
"Marker.$": "$.Marker"
},
"Resource": "arn:aws:states:::aws-sdk:iam:listRoles",
"Next": "ForEachRole"
},
"Success": {
"Type": "Succeed"
}
}
}
解説(一部)
Map
ステートで結果を棄てる("ResultPath": null
)ことで、ListRoles
ステートの結果をIfNextTokenExists
ステートに渡しています。ResultPath
の使い方はStep Functions ワークフローで ResultPath を使用して状態出力を指定するをご参照ください。
ステートマシンのプロパティにはDefinition
を使いたかったのですが、そうすると"ResultPath": null
がエラーになってしまったため、DefinitionString
を使用しています。
Discussion