備忘録も兼ねたメモです。
概要
やりたいこと
stepfunctions で S3 の特定の prefix のオブジェクトを指定してそのオブジェクトをすべて削除する。
追記:オブジェクトが1000を超えるとページネーションが必要になるのですが、stepfunctions では NextContinuationToken を使うことができないのでオブジェクト数が多いときは Lambda を使用したほうがよいです。
結論
次の Code で実現可能です。
{
"Comment": "A description of my state machine",
"StartAt": "ListObjectsV2",
"States": {
"ListObjectsV2": {
"Type": "Task",
"Next": "Map",
"Parameters": {
"Bucket": "icpcgs3cdc",
"Prefix": "prefix"
},
"Resource": "arn:aws:states:::aws-sdk:s3:listObjectsV2",
"ResultSelector": {
"Delete.$": "$.Contents[*].Key"
}
},
"Map": {
"Type": "Map",
"ItemProcessor": {
"ProcessorConfig": {
"Mode": "INLINE"
},
"StartAt": "リストからマップへの変換",
"States": {
"リストからマップへの変換": {
"Type": "Pass",
"End": true,
"ResultPath": "$",
"Parameters": {
"Key.$": "$"
}
}
}
},
"Next": "DeleteObjects",
"ItemsPath": "$.Delete",
"InputPath": "$"
},
"DeleteObjects": {
"Type": "Task",
"Parameters": {
"Bucket": "BucketName",
"Delete": {
"Objects.$": "$"
}
},
"Resource": "arn:aws:states:::aws-sdk:s3:deleteObjects",
"End": true
}
}
}
prefix 部分は他のステートマシンから呼び出して柔軟に変えられるようにする場合は "Prefix.$": ".$prefix"
のようにします。
デザインは次のようになります。
ポイント
DeleteObjects API
AWS の stepfunctions からは S3 の DeleteObjects API を呼び出すことが出来ますが、DeleteObjects は prefix を渡しての削除はできず、オブジェクトを複数渡す必要があります。
そのため一旦 ListObjectsV2 API を使って特定の prefix のオブジェクトを取得して、 DeleteObjects にわたします。
ListObjectsV2
ListObjects は prefix を指定するとその prefix のオブジェクトの一覧をリストで返します。
次のようにしてオブジェクトの名前の一覧を取得します。
"Delete.$": "$.Contents[*].Key"
結果としては次のようになります。
{
"Delete": [
"prefix_object1",
"prefix_object2",
]
}
Map
DeleteObjects に渡す値は次のような形式にする必要があります。
[
{
"Key": "prefix_object1",
},
{
"Key": "prefix_object2",
}
]
リストから JSON の形式にするには Map を利用します。
Map の使い方は JSON の定義の通りです。
感想
stepfunctions に慣れていないためちょっと苦労しました。
同じことをやろうとしている方の役に立てたら幸いです。