【備忘録】AWS:S3 オブジェクトのコピー処理を行った際に VPC endpoints do not support cross-region requests が発生した際の対応
環境
前提
- コピー対象のobjectは 同一VPC内 かつ 同一リージョン内に存在する
事象
- 以下のような処理で同一バケット内のobjectを別の階層のobjectにコピーする処理を実行した際に、
ステータスコード403かつAws::S3::Errors::AccessDenied: VPC endpoints do not support cross-region requestsが発生した
def backup_objects(bucket, prefix)
bucket.objects(prefix: prefix).each do |obj|
next if obj.key.sub(prefix, '').start_with?('bk/')
backup_key = obj.key.sub(prefix, "#{prefix}bk/")
bucket.object(backup_key).copy_from(
copy_source: "#{obj.key}"
)
Rails.logger.info "Backup: #{obj.key} -> #{backup_key}"
end
end
結論
bucket.object(backup_key).copy_from(copy_source: "#{obj.key}") の引数にバケット名が不足していたこと bucket.object(backup_key).copy_from(copy_source: "#{bucket.name}/#{obj.key}") としたことで解消
プロセス
VPC endpoints do not support cross-region requestsとなっていたため、IAMロールやバケットのアクセスポリシーに問題があるのかと考えたため、ハマった。- 冷静に考えると、同一バケットへの処理なので、そんなはずなかった。(すでにIAMロールやバケットのアクセスポリシーが正常に動作している実績があったため)
Class: Aws::S3::Object — AWS SDK for Ruby V3 を見ると、bucketの指定が必要であることも確認できた
メソッドの引数に不正な値が入る時、 403エラーかつ
Aws::S3::Errors::AccessDenied: VPC endpoints do not support cross-region requestsが返るということを頭の片隅に置いておく必要がある- 存在しないパスに対してコピー処理を実行しているなら、404とかでもいい気がするけどそれは違うのだろうか
補足
- copy_fromメソッドは
5GB以上のobjectを処理する場合は、multipart_copy: trueを指定する必要がある