AWSで開発をする際に必須のわりには、CLIやSDKからAWSアカウントへのアクセス設定ってかなり複雑ですよね。
私も未だによく混乱しては調べ直しているので、改めてベスプラを整理してまとめておきます。
AWS Organizations & IAM Identity Centerが使える場合
理由がなければこちらを採用しましょう。
個人検証用のAWSアカウントでも、用途ごとにアカウントをつど発行して使い捨てにできるので、安全ですし便利です。
理想的なアクセス方式
個人用IAM IICユーザー(Assume Role権限のみ) -> Assume Roleを実施(MFA認証必須) -> 作業対象AWSアカウント(作業に必要なIAMロールを利用)
補足: IAM IICとは?
IAMユーザーとは別に、IIC自体にユーザーアカウントを作成することができます。このIICユーザーには、IAMポリシーの代わりにIICの「許可セット」を設定することができ、これによってOrganization内の他のAWSアカウントへのアクセス権限を付与します。
このIICユーザーを、同じOrganization配下の各AWSアカウントにAssume Roleするためのスイッチ元アカウントとして使うことができます。
設定手順
管理用AWSアカウントでAWS Organizationsをセットアップ
- AWS Organizationsを有効にする
- 作業用AWSアカウントを組織に追加する
管理用AWSアカウントでIAM IICをセットアップ
- IAM IICを有効化する
- IAM IICユーザーを作成する
- IICユーザーに許可セットを設定する
IICユーザーにMFAをセットアップ
- AWSアクセスポータルでIICユーザーにMFAデバイスを設定する
作業用PCに認証情報をセットアップ
- AWS CLI v2をインストールする
- aws configure ssoでSSO認証情報を設定する
[sso-session my-sso]
sso_start_url = https://xxxxxx.awsapps.com/start
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access
[profile admin]
sso_session = my-sso
sso_account_id = XXXXXXXXXX
sso_role_name = AdministratorAccess
region = ap-northeast-1
毎回のアクセス手順
GUI(マネジメントコンソール)の場合
- AWSアクセスポータルにアクセスする
- 作業用AWSアカウントの、必要な許可セットを選択してアクセスする
AWS CLIの場合
-
aws sso login --profile <プロファイル名>
で作業用AWSアカウントの一時権限を取得する - 実施したいコマンドに
--profile <プロファイル名>
を付けて実行する
aws s3 ls --profile admin
AWS SDKの場合(Boto3の例)
- Boto3の
client
メソッドを実行する前に、プロファイル名を指定してAssumeRoleを行う
import boto3
# AssumeRoleを実施
session = boto3.Session(profile_name="admin")
# 目的の処理を実行
s3 = session.client("s3")
response = s3.list_buckets()
print(response)
AWS Organizations & IAM Identity Centerが使えない場合
お仕事でリセラー制約下のAWSアカウントを使う場合など、IAM IICが利用できない場合のベスプラも紹介します。
理想的なアクセス方式
個人用IAMユーザー(Assume Role権限のみ) -> Assume Roleを実施(MFA認証必須) -> 作業対象AWSアカウント(作業に必要なIAMロールを利用)
※AWSアカウントを分けているのは、個人用IAMユーザーを作業先アカウントごとに複数持たなくてもいいよう、1箇所に統一するためです。
設定手順
管理用AWSアカウントに個人用IAMユーザーを作成
- 個人用IAMユーザーを作成する(下記2ポリシーを適用)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<アカウントID>:role/<遷移先ロール名>",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListActions",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowUserToCreateVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/*"
},
{
"Sid": "AllowUserToManageTheirOwnMFA",
"Effect": "Allow",
"Action": [
"iam:EnableMFADevice",
"iam:GetMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowUserToDeactivateTheirOwnMFAOnlyWhenUsingMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice"
],
"Resource": [
"arn:aws:iam::*:user/${aws:username}"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "BlockMostAccessUnlessSignedInWithMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
作業用AWSアカウントにIAMロールを作成
- 作業用IAMロールを作成する
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<遷移元アカウントID>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
IAMユーザーにMFAをセットアップ
- 管理用AWSアカウントのマネジメントコンソールに個人用IAMユーザーでサインインし、MFAデバイスを設定する
作業用PCに認証情報をセットアップ
- AWS CLI v2をインストールする
-
aws configure --profile <プロファイル名>
でIAM認証情報を設定する
[profile assume-only]
aws_access_key_id = <アクセスキーID>
aws_secret_access_key = <シークレットアクセスキー>
- configファイルに作業用IAMロールの情報を追記する
[profile assume-only]
region = ap-northeast-1
[profile admin-role]
role_arn = arn:aws:iam::<アカウントID>:role/<遷移先ロール名>
mfa_serial = arn:aws:iam::<アカウントID>:mfa/<MFAデバイス名>
source_profile = assume-only
region = ap-northeast-1
毎回のアクセス手順
GUI(マネジメントコンソール)の場合
- 管理用AWSアカウントに個人用IAMユーザーでサインインする
- 作業用AWSアカウントのIAMロールへスイッチロールする
AWS CLIの場合
- 作業コマンド実行時に
--profile
オプションで作業用IAMロールのプロファイル名を指定するだけ
※スイッチ元の認証情報もcredentialsファイルに記録されているため、CLI利用時に認証コマンドを手動で2段階実施する必要はありません。
AWS SDKの場合(Boto3の例)
- Boto3の
client
メソッドを実行する前に、プロファイル名を指定してAssumeRoleを行う
import boto3
# AssumeRoleを実施
session = boto3.Session(profile_name="admin-role")
# 目的の処理を実行
s3 = session.client("s3")
response = s3.list_buckets()
print(response)
※MFA認証が必要な場合は、ターミナル上でMFAコードを尋ねてくれます。
次のステップ
このへんの作業を便利にしてくれるOSS「AWSume」があります!
私はこれに1Password用のプラグインを設定して、MFA入力まで自動化しました。
※ちなみに読み方は不明です。脳内ではアウシュームと呼んでます。