以前、IAMのスイッチロール周りをまとめた記事を書いたのですが、訳あってCompute Engineで構築したLinuxからCLIでAWSリソースへアクセスする必要が出てきたので、AssumeRoleWithWebIdentityを使ったやり方をまとめます(AssumeRole自体の説明は省略します)
GCP サービスアカウントの準備
AWS IAMロールの準備
まずは普通にIAMロールを作成します。GCPからのアクセスに必要な権限だけをつけてください
作成したIAMロールの信頼ポリシーを↓のように修正します。accounts.google.com:audは先ほど作成したサービスアカウントの一意のIDを記載します。信頼ポリシーの内容は最小限にしてるので、IPアドレス制限などする場合は過去記事ご参照ください
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "accounts.google.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:aud": "xxxxxxxxxxxx" <= 先ほどコピーしたID
},
"StringLike": {
"sts:RoleSessionName": "任意の値"
}
}
}
]
}
Compute Engineインスタンスを起動する
AWS CLIを設定する
インスタンスが起動したら管理コンソールからSSHで接続して設定していきます
-
AWS CLIをインストールします
公式ドキュメントに記載の通り -
boto3をインストールしておきます
# pipも入ってなければインストール $ sudo apt install -y python3-pip $ pip install boto3
-
AWS CLIの設定
$ aws configure AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [ap-northeast-1]: ap-northeast-1 Default output format [json]: json
作成されたconfigファイルを開いて、
credential_process
の行を追加しておきます
後ほど、pythonファイルをインスタンスにコピーするので配置場所を決めてcredential_process
に書いておきます[default] region = ap-northeast-1 output = json credential_process = python3 /path/to/credential_process.py arn:aws:iam::012345678901:role/{role_name}
-
credential_process.pyをconfigに記載したパスに配置します
credential_process.pyはこちら/path/to/credential_process.py#!/usr/bin/python3 import requests import boto3 import json import sys def get_metadata(path: str, parameter: str): metadata_url = f'http://metadata.google.internal/computeMetadata/v1/{path}/{parameter}' headers = {'Metadata-Flavor': 'Google'} try: meta_request = requests.get(metadata_url, headers=headers) except requests.exceptions.RequestException as e: raise SystemExit(e) if meta_request.ok: return meta_request.text else: raise SystemExit('Compute Engine meta data error') if __name__ == '__main__': try: aws_role_arn = sys.argv[1] except IndexError: exit(0) token = get_metadata('instance', 'service-accounts/default/identity?format=standard&audience=gcp') sts = boto3.client('sts', aws_access_key_id='', aws_secret_access_key='') res = sts.assume_role_with_web_identity( RoleArn=aws_role_arn, WebIdentityToken=token, RoleSessionName='任意の値') <= 信頼ポリシーに設定した値を記載 aws_temporary_credentials = { 'Version': 1, 'AccessKeyId': res['Credentials']['AccessKeyId'], 'SecretAccessKey': res['Credentials']['SecretAccessKey'], 'SessionToken': res['Credentials']['SessionToken'], 'Expiration': res['Credentials']['Expiration'].isoformat() } print(json.dumps(aws_temporary_credentials))
動作確認する
これで動くようになったはずです
$ aws sts get-caller-identity
{
"UserId": "xxxxxxxxxxxxxxxxx:{role_session_name}",
"Account": "012345678901",
"Arn": "arn:aws:sts::012345678901:assumed-role/{your_role_name}/{role_session_name}"
}
以上です