Skip to content

Instantly share code, notes, and snippets.

@guitarrapc
Last active June 22, 2023 15:05
Show Gist options
  • Save guitarrapc/f46b62c8fc43e35c368a68d855bcc84f to your computer and use it in GitHub Desktop.
Save guitarrapc/f46b62c8fc43e35c368a68d855bcc84f to your computer and use it in GitHub Desktop.
Minimum sample of IAM User MFA input on awscli. This is same pattern of switch role to same account.

README

  1. Terraformを実行して IAM user a-user と IAM Role mfa-roleを作成します。 a-usermfa-role にAssumeRoleできます。mfa-role は 同一アカウントからの AssumeRoleを許可しますが利用には mfaが必須です。mfa-role は S3 へのフルアクセスを持っています。
  2. ~/.aws/credentials を作成します。 ~/.aws/credentials の a-user プロファイルは IAM User a-user の aws access/secretkey の入力に使います。
  3. ~/.aws/config を作成します。 ~/.aws/config で、 mfa-role プロファイルは、a-user から mfa-role にAssumeRoleし利用すること。mfa-role が求めるmfaに mfa_serialで指定した に IAM User a-user の仮想MFAデバイスのarnを使うことを宣言します。mfa_serial によって、aws cli はmfaが必要な時に自動的にプロンプトを行います。

準備ができました。aws cli で mfa-role プロファイルとして s3一覧取得を実行しましょう。 コマンドを実行すると、.aws/config で指定した IAM User の MFAデバイスのパスコード入力が求められます。TOTP を入力すると、IAM Role mfa-role に付与されたポリシーに従って S3 バケットのリストを列挙します。 S3 アクセス権限は IAM User a-user にはなかったので、mfa-role に AssumeRole され、また MFA が必須になっていることがわかります。

TIPS: mfa がないと Deny するポリシーを用いるとわかりやすい

$ aws s3 ls --profile mfa-role
Enter MFA code for arn:aws:iam::0123456789:mfa/foobar: ここに MFA のTOTPを入力する
# .aws/config
[profile a-user]
region = ap-northeast-1
[profile mfa-role]
source_profile = default
role_arn = arn:aws:iam::123456789012:role/mfa-role
mfa_serial = arn:aws:iam::123456789012:mfa/a-user
output = json
# .aws/credentials
[a-user]
aws_access_key_id = AKIASXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
data "aws_caller_identity" "current" {}
data "aws_iam_policy" "s3full" {
arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}
# iam role
resource "aws_iam_role" "mfa_role" {
name = "mfa-role"
path = "/"
description = "Terraform managged."
assume_role_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "",
"Effect" : "Allow",
"Principal" : {
"AWS" : data.aws_caller_identity.current.account_id # allow this account's user to assume this role
},
"Action" : "sts:AssumeRole",
"Condition" : {
"Bool" : {
"aws:MultiFactorAuthPresent" : "true" # check if MFA is enabled
}
}
}
]
})
policy_arns = [
data.aws_iam_policy.s3full.arn # allow this role to access s3
]
}
# iam user
resource "aws_iam_user" "a_user" {
name = "a-user"
}
resource "aws_iam_policy" "assume_mfa_role" {
name = "assume-role-policy" # you can omit this policy if iam user has `ReadOnlyAccess` or `AdministratorAccess`.
path = "/"
description = "Terraform managged."
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : [
"sts:AssumeRole"
],
"Resource" : aws_iam_role.mfa_role.arn # allow to assume mfa_role
}
]
})
}
resource "aws_iam_user_policy_attachment" "a_user" {
user = aws_iam_user.a_user.name
policy_arn = aws_iam_policy.assume_role_policy_json.arn # allow this user to assume mfa_role
}
resource "aws_iam_access_key" "a_user" {
user = aws_iam_user.a_user.name
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment