OPS

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

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でスイッチロールする方法をご紹介します。 AWS SDK for Pythonでスイッチロールする方法

事前準備

IAM Role作成

スイッチロールを行うためには当然ロールが必要となりますので、はじめにIAM Role を作成します。 エンティティタイプは、[AWSアカウント]を選択し、[このアカウント]を選択します。※IAM Userと環境が異なる場合は、[別のAWSアカウント]を選択し、対象のアカウントを指定します。 AWS SDK for Pythonエンティティタイプ 次の画面の[許可ポリシー]は、このロールで必要となる権限を付与します。当検証では、[AmazonEC2FullAccess]を付与しました。 AWS SDK for Python許可ポリシー 最後の画面で[ロール名]を決めてロールを作成します。 AWS SDK for Pythonロール名 作成したロールの画面を開き、[ARN]と[コンソールでロールを切り替えるためのリンク]を控えておきます。 AWS SDK for Pythonテストロール

IAM Policy作成

次に、IAM Userがスイッチロールするために必要なIAM Policyを作成します。 ポリシーの作成画面に進み、ビジュアルエディタにて以下の通り項目を選択します。
  • サービス:STS
  • アクション:AssumeRole
  • リソース:IAM RoleのARN
AWS SDK for Pythonポリシーの作成 サービスに指定した[STS]とは、”Security Token Service”の略で、その名の通り認証情報を扱うサービスです。また、アクションで指定した[AssumeRole]は、ロールを継承するための権限となります。 次の画面では必要に応じてタグを設定し、最後にポリシー名を決め、ポリシーを作成します。 AWS SDK for Pythonポリシーの確認

IAM User作成

最後にIAM Userを作成します。 [AWS認証情報タイプ]は用途に応じた選択をすれば良いのですが、当検証では、コンソールとBoto3の両方でスイッチロールの動作確認をするため、両方選択しました。 AWS SDK for Pythonユーザーを追加 次の[アクセス許可の設定]では、[既存のポリシーを直接アタッチ]を選択し、先ほど作成したロール継承用のポリシーをアタッチします。 AWS SDK for Pythonユーザーを追加2 次のタグの画面は必要に応じて設定し、ユーザーを作成します。作成後、[.CSVのダウンロード]をクリックし、認証情報が記載されているCredentials.csvを保存します。 AWS SDK for Pythonユーザーを追加3

スイッチロール動作確認(コンソール)

続いて、スイッチロールの動作確認を行います。ダウンロードしたCSVファイルを開き、AWSコンソールにログインします。まずは、スイッチロールせずにEC2の画面に進み、権限不足によりEC2が表示されていないことを確認します。 AWS SDK for PythonスイッチロールインスタンスID その後、ロール作成後に控えた[ロールを切り替えるためのリンク]にアクセスし、[ロールの切り替え]をクリックして、スイッチロールします。 AWS SDK for PythonスイッチロールインスタンスID2

※表示名は、必須ではありません。

再度EC2の画面に進み、EC2が表示されていること(ロールの権限が有効であること)を確認します。 AWS SDK for PythonスイッチロールインスタンスID3 コンソール上でのスイッチロールの動作確認ができましたので、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)の一覧が出力され、スイッチロールされていることを確認できました。 AWS SDK for PythonスイッチロールインスタンスID4

※画像は加工しています。

おわりに

Boto3でスイッチロールする方法をご紹介しました。ロールのセッションはデフォルトで1時間ですが、最大で12時間まで引き延ばすことができます。また、スイッチしたロールから別のロールを継承(ロールの連鎖)することもできますので、環境に応じた設定をお試しいただければと思います。 最後までお読みいただきありがとうございました。