在使用AWS的Terraform时,可以通过实例配置文件进行角色扮演
要在AWS上使用terraform apply,最现实的做法是给予所有的AWS操作权限。否则,每次尝试使用未使用过的服务或新服务时都需要进行策略修正。
即使准备一个专门用于terraform作业的实例,也不能始终开启太强大的权限。作为一个实例配置文件,我们只需切换到ReadOnlyAccess这种更轻量级的权限,并且只在执行terraform命令时赋予完全权限。我在尝试中遇到了一些问题,所以在这里做一些记录。
将Terraform操作员的IAM用户设为MFA必需,并通过该用户进行assume-role可能是最佳平衡点。本文介绍的是在此之前的步骤。假设assume-role的方法应该是共享的。
只读角色
-
- Usecase: EC2
instance-profile として使える role
これを terraform作業用instance のIAM roleとして割り当てる
ReadOnlyAccess AWS 管理ポリシー
ProfileOnlyPolicy
instance-profile:ReadOnly-Role の instanceでの利用でなければ何もさせない
{
"Version": "2012-10-17",
"Statement": [
{
"Resource": "*",
"Action": "*",
"Effect": "Deny",
"Condition": {
"ArnEquals": {
"ec2:InstanceProfile": "arn:aws:iam::<account-id>:role/ReadOnly-Role"
}
}
}
]
}
角色/地形变形角色
-
- AdministratorAccess AWS 管理ポリシー
Terraform用に原則全部の操作を可能とする
ProfileOnlyPolicy
instance-profile:ReadOnly-Role の instanceでの利用でなければ何もさせない
PolicyDocument
role/ReadOnly-Role からの switch だけを許す
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account-id>:role/ReadOnly-Role"
},
"Action": "sts:AssumeRole"
}
]
}
提供者.tf
provider "aws" {
region = "ap-northeast-1"
version = ">1.56.0"
profile = "terraform-role"
}
terraform {
backend "s3" {
bucket = "foo-terraform"
key = "bar/terraform.tfstate"
region = "ap-northeast-1"
skip_metadata_api_check = true
profile = "terraform-role"
}
}
~/.aws/credentials可以被本地化为”家目录下的.aws文件夹中的credentials文件”。
[terraform-role]
role_arn = arn:aws:iam::<account-id>:role/Terraform-Role
credential_source = Ec2InstanceMetadata
政策/角色/資格的操作驗證
首先,我们需要验证在没有使用terraform的情况下能够查看的范围。
$ aws sts get-caller-identity
{
"Account": <account-id>,
"UserId": "xxxx:<instance-id>",
"Arn": "arn:aws:sts::<account-id>:assumed-role/ReadOnly-Role/<instance-id>"
}
$ aws sts get-caller-identity --profile terraform-role
{
"Account": <account-id>,
"UserId": "xxxx:botocore-session-1598506181",
"Arn": "arn:aws:sts::<account-id>:assumed-role/Terraform-Role/botocore-session-1598506181"
}
执行terraform应用程序
通过向现有资源添加新的标签,或者稍微更改注释标签的字符串,使用terraform apply命令。
一個選項的中文的翻譯為:迷住點
将terraform state保存在S3中的backend “s3″块十分棘手。
考虑到Terraform操作员的数量增加以及Terraform作业实例可能因故障或误操作而丢失,无法排除使用S3进行存储的必要性。
然而,无论在provider块中指定profile还是使用export AWS_PROFILE=设置环境变量,都会导致错误。
Failed to save state: failed to upload state: AccessDenied: Access Denied
尽管已经在资源中反映出为验证目的而添加的标签和标签字符,所以应该已经成功执行了assume-role。
如同代码块所示,backend块中也需要指定profile。后端保存操作似乎与提供者块的credential设置是独立的。此外,这里还需要添加skip_metadata_api_check = true选项。
参考问题
terraform-providers/terraform-provider-aws#5018
s3后端不使用提供者块。
下次遇到类似情况时,也试试这个。
我使用 TF_LOG=DEBUG 运行 terraform init。