
AWS SDK for Python (Boto3)でスイッチロールする方法、権限設定などを紹介
はじめに

AWS IAM (Identity and Access Management:アイアム)の運用において、IAMユーザーに閲覧権限のみを付与し、AWSリソースを操作する必要に迫られた場合のみ操作権限のあるロールに切り替えて作業をする、といった場面はよく見受けられます。
そのようなユーザーがAWS SDK for Python (Boto3)でAWSリソースを操作したいとなった場合、boto3上でも同様にスイッチロールする必要があります。当記事では、Boto3でスイッチロールする方法をご紹介します。

AWS SDKについて
AWS SDKは、効率的にAWSを運用するためのサービスです。アプリケーションの開発や、その管理を行う上で役に立ちます。SDKには、開発者がアプリへ統合したいライブラリやドキュメント、コードなどが含まれます。そのため、開発のたびにこれらを用意する面倒から解放され、パフォーマンス向上を進める上で強力なソリューションとなるでしょう。
何もない状態からアプリを組み上げるのは、負担の大きい作業です。AWS SDKがあれば、必要に応じて既存のプログラムを呼び出して、新しい開発業務に適用することができます。EC2の起動やIDの取得など、AWS運用の負担を効果的に減らせます。
AWS SDK for Python(Boto3)とは
AWS SDK for Pythonは、Pythonの運用効率を改善することに特化したサービスです。Python運用に伴うアプリケーションやライブラリ、スクリプトなどを、AWS環境へ簡単に統合することができます。
Pythonは近年、アプリ開発の需要拡大やAI開発の強化が企業で進むにあたり、最も注目度の高い言語です。一方、Pythonのスキルを迅速に身につけることは難しく、プログラミングを始めたばかりの人が実践で活躍するには、ある程度の時間が求められます。
Boto3の導入は、こういったPython初学者がすぐに現場で活躍する上で有効なソリューションです。Pythonを使って迅速にAWSリソースを扱えるため、人材不足の問題を解消できます。
スイッチロールとは?期待できるメリット

Boto3によって実行可能なスイッチロールとは、あるアカウントのIAMユーザーを、別のアカウントの権限で利用できるようにするというものです。異なるアカウントから同じIAMユーザーを使えるようになるため、複数のAWSアカウントを管理することによる複雑化を回避できます。
スイッチロールが実現すれば、複数のユーザーが共同でAWSを運用する場合でも、一つの管理アカウントだけで業務を遂行可能です。組織の規模が大きくなり、チームメンバーが増えてきた時には積極的に実現を進めると良いでしょう。
事前準備

スイッチロールをBoto3を使って実現するには、まず以下の手順でその準備を進めます。
IAM Role作成
スイッチロールを行うためには当然ロールが必要となります。まずは複数アカウントで共有するためのIAM Role を作成します。
エンティティタイプは、[AWSアカウント]を選択し、[このアカウント]を選択します。※IAM Userと環境が異なる場合は、[別のAWSアカウント]を選択し、対象のアカウントを指定します。

次の画面の[許可ポリシー]は、このロールで必要となる権限を付与します。当検証では、[AmazonEC2FullAccess]を付与しました。

最後の画面で[ロール名]を決めてロールを作成します。

作成したロールの画面を開き、[ARN]と[コンソールでロールを切り替えるためのリンク]を控えておきます。

IAM Policy作成
次に、IAM Userがスイッチロールするために必要なIAM Policyを作成します。
ポリシーの作成画面に進み、ビジュアルエディタにて以下の通り項目を選択します。
サービス:STS
アクション:AssumeRole
リソース:IAM RoleのARN

サービスに指定した[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でスイッチロールする方法をご紹介しました。スイッチロールが可能な環境をBoto3で整備することにより、現場の管理業務効率化に貢献します。ロールのセッションはデフォルトでは1時間ですが、最大で12時間まで引き延ばすことができます。また、スイッチしたロールから別のロールを継承(ロールの連鎖)することも可能です。必要に応じて、その時々で最適な環境を実現するための設定をお試しいただければと思います。
最後までお読みいただきありがとうございました。