クロスアカウントで別のAWSアカウントのS3にファイルをアップロードしたい

n-ozawan

皆さん、こんにちは。技術開発グループのn-ozawanです。
猫のゴロゴロ音には心を癒す効果どころか、骨折の治りを早める効果も期待されています。

本題です。
基本的に1つのAWSアカウントで環境を構築するものですが、中には複数のAWSアカウントで環境を構築するケースもあるかと思います。今回はクロスアカウントで異なるAWSアカウントのS3にファイルをアップロードすることがあったので、その方法を紹介します。

クロスアカウントによるS3アップロード

はじめに

現在、私が関わっているプロジェクトでは構成管理にGitLabを利用しています。ソースコードはGitLabで管理され、CI/CDによりコンテナイメージを開発環境のECRへアップロードします。一方で、設計書関連は関係者全員と共有するため、開発環境とは異なるAWSアカウント(ドキュメント環境)のS3にアップロードする必要があります。

ECRへのPushにしても、S3へのアップロードにしても、それを行うためのIAMユーザーが必要になります。GitLabのCI/CDで利用できるIAMユーザーは1つだけです。つまり、開発環境のIAMユーザーでCI/CDを実行すれば、ECRへのPushは出来ますが、ドキュメント環境への権限がないため、S3へのアップロードは出来ないことになります。

ゴール

この問題を解決するために、クロスアカウントアクセスによるS3へのファイルアップロードが出来るようにします。IAM STSから一時的な認証情報を取得して、その認証情報によりS3へファイルをアップロードを行うまでが本稿のゴールです。

S3へアクセス出来るようにロールを設定する

まずはS3へアップロード可能なポリシーを定義します。このポリシーはドキュメント環境側に作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::[対象のバケット名]"
            ]
        }
    ]
}

次に開発環境のIAMユーザーが引き受けられるようにロールを作成します。このロールもドキュメント環境側に作成します。また、このロールに先ほどのポリシーをアタッチしてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "[開発環境のIAMユーザーのARN]"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Principal.AWSに開発環境のIAMユーザーのARNを指定することにより、ドキュメント環境は、開発環境のIAMユーザーに対してS3へのアクセス許可を与えられるようになります。

ドキュメント環境側の設定は以上となります。

STSを取得してS3にアップロードする

開発環境のIAMユーザーは、以下のコマンドによりSTSから認証情報を得ることが出来ます。

aws sts assume-role --role-arn [先ほど作成したロールのARN] --role-session-name [任意の名前]
{
    "Credentials": {
        "AccessKeyId": [アクセスキー],
        "SecretAccessKey": [シークレットアクセスキー],
        "SessionToken": [セッショントークン],
        "Expiration": [有効期限]
    },
    "AssumedRoleUser": {
        "AssumedRoleId": xxx,
        "Arn": xxx
    }
}

上記のCredentials.AccessKeyIdCredentials.SecretAccessKeyCredentials.SessionTokenをそれぞれAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKENの環境変数に設定することにより、開発環境のIAMユーザーで、ドキュメント環境のS3にアクセスすることが出来るようになります。

以下はgitlab-ci.ymlの例です。export ~のところで、STSからの認証情報取得と環境変数への反映を行っています。

  script:

    # STSから認証情報を取得して、環境変数に反映
    - >
      export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s"
      $(aws sts assume-role --role-arn [先ほど作成したロールのARN]
      --role-session-name [任意の名前]
      --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
      --output text))

    # S3にファイルをアップロード
    - aws s3 cp dist s3://[対象のバケット名]/ --recursive

おわりに

今回初めてクロスアカウントアクセスをやってみて、わりと簡単な設定で出来たので驚きました。ただ、STSの仕組みなどをちゃんと知らないと、はまりそうな気がします。

ではまた。

Recommendおすすめブログ