クロスアカウントで別のAWSアカウントのS3にファイルをアップロードしたい
皆さん、こんにちは。技術開発グループの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.AccessKeyId
、Credentials.SecretAccessKey
、Credentials.SessionToken
をそれぞれAWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、AWS_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の仕組みなどをちゃんと知らないと、はまりそうな気がします。
ではまた。