CodeBuildでクロスアカウントのs3にアクセスする

  • 2020.09.05
  • AWS
NO IMAGE

AWSのCodeシリーズでCI/CDを構築する際に、異なるアカウントのS3からファイルをコピーしたいという要件があり、少しハマったのでその解決方法をメモ。

やり方は3つある

“s3 クロスアカウント”などで検索すると、AWS公式のサイトがヒットして、やり方が書いてあります。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/cross-account-access-s3/

ここでは、最もシンプルだと思われる、一つ目の方法(S3 バケットオブジェクトへのプログラムによるアクセスのみのリソースベースのポリシーと AWS Identity and Access Management (IAM) ポリシー)で進めていきました。

実際に行った設定

上記のサイトに記載している通り、クロスアカウントでのアクセスを行う場合、アクセスをする側のアカウントのIAMロールと、アクセスされるアカウントのs3バケットのバケットポリシー両方に設定を行うことが重要です。設定方法は基本的にサイトに記載してある通り。
CodeBuildが参照するbuildspec.ymlは以下のように記載しました。

version: 0.2

phases:
  install:
    commands:
      - echo install
  build:
    commands:
      - aws s3 sync s3://${FROM_FRONT_BUCKET} s3://${TO_FRONT_BUCKET} --delete --exact-timestamps
  post_build:
    commands:
      - echo post_build

installフェーズとpost_buildフェーズはechoしているだけなので、意味があるのはbuildフェーズのコマンドのみです。環境変数で受け取ったコピー元のバケットから、同様に環境変数で受け取ったコピー先のバケットにファイルをコピーする(これらのバケットが異なるアカウントにある)という処理を記載しています。

どこでハマったか

これでできたと思って動かしてみると、CodeBuildで以下エラーが発生。

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

記載されている通りに設定を行ったのに、アクセスが許可されていない?この後、いろんなことを試して結構ハマりましたが、結果的に以下のようにバケットポリシーを変更することで解決しました。

解決方法

変更前のバケットポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            :
            :
            "Resource": [
                "arn:aws:s3:::AccountABucketName/*"
            ]
        }
    ]
}

変更後のバケットポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            :
            :
            "Resource": [
                "arn:aws:s3:::AccountABucketName", ←追加
                "arn:aws:s3:::AccountABucketName/*"
            ]
        }
    ]
}

バケットのディレクトリ以下の任意のファイル、ディレクトリにはアクセス許可を与えていたけれど、バケットそのものにはアクセス許可を与えていなかったことが原因でした。結果だけみると、かなりあっけない感じですが、公式の通りにやっても動かず割とハマったので、メモとして残しておきます。