AWS SDK for Python (Boto3)でスイッチロールする方法、権限設定などを紹介
2023.01.27
当記事では、AWS SDK for Python (Boto3)でスイッチロールするために必要な権限設定、準備、設定方法などを網羅的にご紹介します。
はじめに
AWS IAM (Identity and Access Management:アイアム)の運用において、IAMユーザーに閲覧権限のみを付与し、AWSリソースを操作する必要に迫られた場合のみ操作権限のあるロールに切り替えて作業をする、といった場面はよく見受けられます。
そのようなユーザーがAWS SDK for Python (Boto3)でAWSリソースを操作したいとなった場合、boto3上でも同様にスイッチロールする必要があります。当記事では、Boto3でスイッチロールする方法をご紹介します。
事前準備
IAM Role作成
スイッチロールを行うためには当然ロールが必要となりますので、はじめにIAM Role を作成します。
エンティティタイプは、[AWSアカウント]を選択し、[このアカウント]を選択します。※IAM Userと環境が異なる場合は、[別のAWSアカウント]を選択し、対象のアカウントを指定します。
次の画面の[許可ポリシー]は、このロールで必要となる権限を付与します。当検証では、[AmazonEC2FullAccess]を付与しました。
最後の画面で[ロール名]を決めてロールを作成します。
作成したロールの画面を開き、[ARN]と[コンソールでロールを切り替えるためのリンク]を控えておきます。
IAM Policy作成
次に、IAM Userがスイッチロールするために必要なIAM Policyを作成します。
ポリシーの作成画面に進み、ビジュアルエディタにて以下の通り項目を選択します。
サービスに指定した[STS]とは、”Security Token Service”の略で、その名の通り認証情報を扱うサービスです。また、アクションで指定した[AssumeRole]は、ロールを継承するための権限となります。
次の画面では必要に応じてタグを設定し、最後にポリシー名を決め、ポリシーを作成します。
IAM User作成
最後にIAM Userを作成します。
[AWS認証情報タイプ]は用途に応じた選択をすれば良いのですが、当検証では、コンソールとBoto3の両方でスイッチロールの動作確認をするため、両方選択しました。
次の[アクセス許可の設定]では、[既存のポリシーを直接アタッチ]を選択し、先ほど作成したロール継承用のポリシーをアタッチします。
次のタグの画面は必要に応じて設定し、ユーザーを作成します。作成後、[.CSVのダウンロード]をクリックし、認証情報が記載されているCredentials.csvを保存します。
スイッチロール動作確認(コンソール)
続いて、スイッチロールの動作確認を行います。ダウンロードしたCSVファイルを開き、AWSコンソールにログインします。まずは、スイッチロールせずにEC2の画面に進み、権限不足によりEC2が表示されていないことを確認します。
その後、ロール作成後に控えた[ロールを切り替えるためのリンク]にアクセスし、[ロールの切り替え]をクリックして、スイッチロールします。
※表示名は、必須ではありません。
再度EC2の画面に進み、EC2が表示されていること(ロールの権限が有効であること)を確認します。
コンソール上でのスイッチロールの動作確認ができましたので、Boto3でも同様にスイッチロールが可能となっているはずです。
スイッチロール動作確認(Boto3)
Boto3初期化モジュール作成
Boto3でAWSリソースを操作するためには、アクセスキーやシークレットアクセスキーといった認証情報を扱う必要があります。
また、IAMの運用方法によってはスイッチロール処理も必要となるため、この2つの処理はモジュール化しておくと、汎用的に再利用でき大変便利です。AWSリソースにアクセスするプログラム側でモジュールをimportして使用するイメージです。
以下の通りコーディングします。※ここではファイル名を「aws_conf.py」とします。
import boto3
from botocore.config import Config
class Conf:
def __init__(self, access_key, secret_access_key, region, service):
my_config = Config(region_name = region)
self.client = boto3.client(
service,
aws_access_key_id = access_key,
aws_secret_access_key = secret_access_key,
config = my_config
)
# switch role method
def switch_role(self, role_arn, role_name, role_region, role_service):
assumed_role_object = self.client.assume_role(
RoleArn = role_arn,
RoleSessionName = role_name
)
role_config = Config(region_name = role_region)
switch_client = boto3.client(
role_service,
aws_access_key_id = assumed_role_object['Credentials']['AccessKeyId'],
aws_secret_access_key = assumed_role_object['Credentials']['SecretAccessKey'],
aws_session_token = assumed_role_object['Credentials']['SessionToken'],
config = role_config
)
return switch_client
ポイントは、switch_role関数内のassume_roleです。これを実行することで一時的な認証情報(アクセスキー、シークレットアクセスキー、セッショントークン)を発行します。この認証情報を利用することで、roleに付与された権限の範囲内でAWSリソースにアクセス可能になるという仕組みです。
オペレーションプログラム作成
初期化モジュールと同じ階層のディレクトリにAWSリソースにアクセスするためのプログラムを作成します。当検証では、EC2のインスタンスIDを取得するプログラムとし、スイッチロールした場合とそうでない場合の動作を比較検証します。
スイッチロールしない場合のコードは、以下の通りです。
import aws_conf
access_key = '〓IAM Userのアクセスキー〓'
secret_access_key = '〓IAM Userのシークレットアクセスキー〓'
region = 'ap-northeast-1'
conf = aws_conf.Conf(access_key, secret_access_key, region, 'ec2')
response = conf.client.describe_instances()
for i in range(len(response['Reservations'])):
print(response['Reservations'][i]['Instances'][0]['InstanceId'])
先ほど作成した初期化モジュールをimportで読み込んで、東京リージョンにあるEC2のインスタンスのID一覧を取得する処理になっています。なお、当検証ではIAM Userのアクセスキーとシークレットアクセスキーを平文でコードに埋め込んでいますが、実運用する際は、暗号化するなどして慎重に取り扱ってください。
スイッチロールする場合のコードは、以下の通りです。
import aws_conf
access_key = '〓IAM Userのアクセスキー〓'
secret_access_key = '〓IAM Userのシークレットアクセスキー〓'
region = 'ap-northeast-1'
role_arn = '〓IAM RoleのARN〓'
role_name = '〓任意のロール名〓'
role_region = 'ap-northeast-1'
conf = aws_conf.Conf(access_key, secret_access_key, region, 'sts')
switch_client = conf.switch_role(role_arn, role_name, role_region, 'ec2')
response = switch_client.describe_instances()
for i in range(len(response['Reservations'])):
print(response['Reservations'][i]['Instances'][0]['InstanceId'])
先ほどと異なる点は、初期化モジュールをimportで読み込んでConfクラスをインスタンス化する際、第4引数にスイッチロールするために必要なサービスであるstsを指定しています。次に、Confクラスのswitch_role関数を実行し、一時的な認証情報を取得してスイッチロールし、EC2の情報を取得しています。
スイッチロール動作検証(Boto3)
まずは、スイッチロールしない場合のオペレーションプログラムを実行し、動作を確認します。すると次のように権限不足に関するエラーが出力されます。
「botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.」
Boto3でもIAM Userに権限がないことが確認できましたので、最後にBoto3でスイッチロールの動作確認をします。
スイッチロールありのオペレーションプログラムを実行します。するとEC2のインスタンスID(i-xxxxxxxx)の一覧が出力され、スイッチロールされていることを確認できました。
※画像は加工しています。
おわりに
Boto3でスイッチロールする方法をご紹介しました。ロールのセッションはデフォルトで1時間ですが、最大で12時間まで引き延ばすことができます。また、スイッチしたロールから別のロールを継承(ロールの連鎖)することもできますので、環境に応じた設定をお試しいただければと思います。
最後までお読みいただきありがとうございました。