问题描述
在使用Terraform管理AWS基础架构时,遇到了一个问题。他想要在一个S3存储桶上启用mfa_delete
,但在尝试应用更改时遇到了以下错误:
1 error occurred:
* aws_s3_bucket.logs: 1 error occurred:
* aws_s3_bucket.logs: Error putting S3 versioning: AccessDenied: Mfa Authentication must be used for this request
status code: 403, request id: <redacted>, host id: <redacted>
用户的IAM帐户已经附加了一个虚拟MFA设备,但在运行Terraform时,MFA没有被使用,因为Terraform使用与帐户关联的API访问密钥。用户想知道如何在运行Terraform时使用多因素认证(MFA)。
解决方案
以下解决方案基于Terraform提供者版本 v2.65.0 或更高版本。在操作之前,请确保做好备份并了解涉及的风险。
方案1:使用assume_role
语句
通过在Terraform配置中指定assume_role
语句,可以解决这个问题。这将允许你在Terraform运行时使用指定的角色。
以下是如何配置Terraform以使用assume_role
语句的步骤:
- 打开你的Terraform配置文件(通常为
main.tf
)。 - 在
provider "aws"
块中添加一个assume_role
语句,指定要使用的角色ARN。
hcl
provider "aws" {
profile = "default"
assume_role {
role_arn = "arn:aws:iam::[ACCOUNT_ID]:role/terraform-test-role"
}
}
请将[ACCOUNT_ID]
替换为你的AWS帐户ID,terraform-test-role
替换为你要使用的角色名。
方案2:使用API调用来启用mfa_delete
在一些情况下,Terraform提供者可能无法直接设置某些属性,比如mfa_delete
。对于这种情况,你可以考虑使用AWS CLI进行API调用,手动设置这些属性。
- 确保你的IAM用户可以使用
GetSessionToken
生成MFA会话令牌,并且你知道如何将令牌应用于~/.aws/credentials
文件中。 - 使用AWS CLI执行API调用,将
mfa_delete
属性设置为启用。以下是一个示例命令:
sh
aws --profile my_profile s3api put-bucket-versioning --bucket bucket-name --versioning configuration 'MFADelete=Enabled,Status=Enabled' --mfa 'arn:aws:iam::<account-id>:mfa/root-account-mfa-device <mfacode>
请将my_profile
替换为你的AWS CLI配置文件中的配置文件名,bucket-name
替换为存储桶名称,<account-id>
替换为你的AWS帐户ID,<mfacode>
替换为MFA代码。
方案3:手动设置环境变量
你可以通过执行sts assume-role
并将返回值中的凭证分解到环境变量中,然后让Terraform使用这些环境变量来完成操作。
以下是一个示例脚本,演示如何使用AWS CLI执行sts assume-role
,并将返回的凭证存储为环境变量,然后运行Terraform操作:
#!/bin/bash
# 执行 sts assume-role 并将结果存储到 session_token 变量中
session_token=$(aws sts assume-role \
--profile ${profile} \
--role-arn "${role_arn}" \
--role-session-name "${session_name}" \
--serial-number "${mfa_serial}" \
--duration-seconds $session_duration \
--token-code "${token_code}" \
--query Credentials)
# 将返回的凭证分解到环境变量中
export AWS_REGION=${region}
export AWS_ACCESS_KEY_ID="$(echo $session_token | jq -r .AccessKeyId)"
export AWS_SECRET_ACCESS_KEY="$(echo $session_token | jq -r .SecretAccessKey)"
# 运行 Terraform 操作
terraform plan
在上面的示例中,我们执行了sts assume-role
命令,然后使用jq
命令将返回的凭证分解到环境变量中,最后运行Terraform操作。
请根据你的需求和配置进行相应的调整。这个方法允许你手动获取临时凭证并在Terraform中使用,从而实现MFA认证。
请注意,以上解决方案提供了不同的方法来解决在Terraform中使用AWS MFA的问题。你可以根据你的情况选择合适的方法。