1
1

クレデンシャルではなくAssume Roleを利用した外部AWSアカウントへのアクセス

Last updated at Posted at 2024-02-22

概要

データエンジニアをしています。
直近で参画したプロジェクトにて、データマートのデータをファイル形式にして外部のAWS S3へエクスポートする機能を開発する必要がありました。

我々のチームではデータパイプラインをスクラッチで内製開発したという経緯があり、データマートをファイル出力する機能自体は存在していました。
一方で、外部のAWS S3へ出力する機能は存在しなかったので、機能追加とともに主にAssume Roleについて改めて学習する機会となりました。

以降、主にAssume Roleに焦点を当てた内容となります。

Assume Roleの仕組み

まずはかんたんにAssume Roleの仕組みについて振り返ってみます。

IAMユーザーおよびリソースが、STS経由でロールの権限を一時的に引き受ける(Assume)仕組みとなります。引き受けた側は一時的にロールにアタッチされたポリシー相当の権限を行使することができます。

image.png

使い所としては下記のようなものがあります。

  • 外部AWSアカウントのAWリソースの操作
    • 外部AWSアカウントのロールを一時的に引き受けることで、外部AWSのリソースへアクセスできる
    • 一時的な認証情報が都度発行されるため、クレデンシャルによるアクセスよりもセキュア
  • クロスアカウントアクセス
    • 例えばプロダクトや環境ごとに複数のAWSアカウントが存在するとき、それぞれのAWSアカウントにてIAMユーザーを設けるのではなく、それぞれのAWSアカウントにて作成したロールを使用して各アカウントへアクセスする

Assume Roleに対応するためのソースコード改修

ざっくりAssume Roleについて捉えたところで、具体的な必要作業について見ていきます。

今回、Pythonにてアップロードの処理を記述していたため、そこにAssume Roleによる一時的な認証情報の取得処理を加えます。
下記はソースコードの追加内容を簡略化したものです。

sample.py
# stsへのコネクションを確立
sts_connection = boto3.client('sts')

# stsから一時的なクレデンシャルを発行してもらう
sts_credentials = \
    sts_connection.assume_role(RoleArn="[Assume RoleのARN]", RoleSessionName="[任意のセッション名]")

STS_ACCESS_KEY = sts_credentials['Credentials']['AccessKeyId']
STS_SECRET_ACCESS_KEY = sts_credentials['Credentials']['SecretAccessKey']
SESSION_TOKEN =sts_credentials['Credentials']['SessionToken']

# stsの認証情報を用いて各リソースへ接続
s3 = boto3.resource(
    's3',
    aws_access_key_id=STS_ACCESS_KEY,
    aws_secret_access_key=STS_SECRET_ACCESS_KEY,
    aws_session_token=SESSION_TOKEN
)

# オブジェクトを外部S3へアップロードする処理
# ...

Assume Roleに対応するためのIAMの編集

Assume Roleによる権限委譲のために、ソースコードだけではなくIAMの編集が必要となります。
「ロールを引き受ける側」と「ロール側」に分けて、設定例を示します。

ロールを引き受ける側

まず、オレンジ色で示された「ロールを引き受ける側」部分の設定を実施します。

image.png

Assume Roleするためには、ロールを引き受けるIAMユーザーやリソースに、STSへのアクションを許可するポリシーを設定します。
これは、STSに対してXXXロールを使用するための認証情報の発行を依頼するためです。

ポリシー.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::[AWSアカウントID]:role/[使用したいロール]"
        }
    ]
}

ロール側

次に、オレンジ色で示された「ロール側」部分の設定を実施します。

image.png

Assume Roleするためには、ロール側に「AAA(ユーザーおよびリソース)にロールを使わせてもいいよ」と明記してあげる必要があります。
これは、信頼ポリシーにて表現します。

信頼ポリシー.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::[AWSアカウントID]:user/[Assume Roleを許可するIAM]",
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

さらに、このロールにてどのようなアクションを許可するかも定義をしておきます。ここは要件に合わせて原則最小権限で設定をします。
例えば、AmazonS3ReadOnlyAccessを許可する場合はこのようになります。

ポリシー.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:Describe*",
                "s3-object-lambda:Get*",
                "s3-object-lambda:List*"
            ],
            "Resource": "*"
        }
    ]
}

まとめ

  • 外部のAWSアカウントへのアクセスをAssume Roleで実施した
  • そのために、Assume Roleの概要を把握した後、ソースコードの改修とIAMの編集を実施した
  • 既存のデータパイプラインの機能としては、IAMのクレデンシャルキーを用いたデータファイルのエクスポートにのみ対応していたが、Assume Roleによるアクセスも可能となった
    • 様々な要件に対応可能となったうえ、よりセキュアな方式を提案することができるようになった
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1