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時間まで引き延ばすことができます。また、スイッチしたロールから別のロールを継承(ロールの連鎖)することもできますので、環境に応じた設定をお試しいただければと思います。

    最後までお読みいただきありがとうございました。