Terraform 是“地形”吗;“循环”;没用?还是我遗漏了什么?
我今天写了一些使用“循环”的配置,但直到后来我才想知道这是否是正确的路径,因为terraform将资源作为列表/数组保存在状态文件中 考虑以下配置:Terraform 是“地形”吗;“循环”;没用?还是我遗漏了什么?,terraform,Terraform,我今天写了一些使用“循环”的配置,但直到后来我才想知道这是否是正确的路径,因为terraform将资源作为列表/数组保存在状态文件中 考虑以下配置: locals { users_list = [ "ab", "cd", "ef" ] } resource "aws_iam_user" "users" { count = "${length(local.users_list)}" name = "${local.users_list["${count.index}"]}
locals {
users_list = [ "ab", "cd", "ef" ]
}
resource "aws_iam_user" "users" {
count = "${length(local.users_list)}"
name = "${local.users_list["${count.index}"]}"
path = "/"
}
运行“terraform apply”将创建用户,并在状态文件中创建以下资源:
- aws_iam_用户。用户[0]
- aws_iam_用户。用户[1]
- aws_iam_用户。用户[2]
locals {
users_list = [ "cd", "ef" ]
}
然后terraform将尝试更改状态文件([0]-->“cd”、[1]-->“ef”)中的资源以及AWS中的用户本身,这可能是灾难性的,因为每个用户都有自己的密钥,这样做会造成混乱。这也与其他资源类型相关,尽管有些资源删除并再次创建不会造成如此混乱,但这仍然是错误的
所以,对于我的问题,就像在标题中一样——也许我完全弄错了?或者这就是它的工作方式?(使整个“循环”机制毫无用处)v0.11.x之前的terraform实际上并不正式支持循环。使用
count.index
as循环的方法来自博客
从版本0.12开始(目前仍处于beta测试阶段),它支持使用新关键字的循环,但我仍然不能保证它是否解决了您问题中的问题
因此,我将详细说明问题所在,以及如何解决问题,像@Aniket Chopade这样的人可以理解这个问题的来源
在改变了当地人之后
$ terraform apply -auto-approve
aws_iam_user.users[0]: Refreshing state... (ID: ab)
aws_iam_user.users[1]: Refreshing state... (ID: cd)
aws_iam_user.users[2]: Refreshing state... (ID: ef)
aws_iam_user.users[2]: Destroying... (ID: ef)
aws_iam_user.users[1]: Modifying... (ID: cd)
name: "cd" => "ef"
aws_iam_user.users[0]: Modifying... (ID: ab)
name: "ab" => "cd"
aws_iam_user.users[2]: Destruction complete after 2s
Error: Error applying plan:
2 error(s) occurred:
* aws_iam_user.users[0]: 1 error(s) occurred:
* aws_iam_user.users.0: Error updating IAM User ab: EntityAlreadyExists: User with name cd already exists.
status code: 409, request id: 24853da7-452c-11e9-a853-bf4c89d8ebba
* aws_iam_user.users[1]: 1 error(s) occurred:
* aws_iam_user.users.1: Error updating IAM User cd: EntityAlreadyExists: User with name ef already exists.
status code: 409, request id: 24839027-452c-11e9-b3d5-3deb12943195
我必须将这些资源标记为已销毁并再次应用
$ terraform taint aws_iam_user.users.1
The resource aws_iam_user.users.1 in the module root has been marked as tainted!
$ terraform taint aws_iam_user.users.0
The resource aws_iam_user.users.0 in the module root has been marked as tainted!
$ terraform apply -auto-approve
...
aws_iam_user.users[0]: Destroying... (ID: ab)
aws_iam_user.users[1]: Destroying... (ID: cd)
aws_iam_user.users[0]: Destruction complete after 2s
aws_iam_user.users[0]: Creating...
arn: "" => "<computed>"
force_destroy: "" => "false"
name: "" => "cd"
path: "" => "/"
unique_id: "" => "<computed>"
aws_iam_user.users[1]: Destruction complete after 2s
aws_iam_user.users[1]: Creating...
arn: "" => "<computed>"
force_destroy: "" => "false"
name: "" => "ef"
path: "" => "/"
unique_id: "" => "<computed>"
$terraform污染aws\u iam\u用户。用户。1
模块根目录中的资源aws_iam_user.users.1已标记为受污染!
$terraform taint aws_iam_用户。用户。0
模块根目录中的资源aws_iam_user.users.0已标记为受污染!
$terraform应用-自动批准
...
aws\u iam\u用户。用户[0]:正在销毁。。。(ID:ab)
用户[1]:正在销毁。。。(ID:cd)
aws_iam_用户。用户[0]:2秒后销毁完成
aws\u iam\u用户。用户[0]:正在创建。。。
arn:“”=>“”
强制销毁:“”=>“假”
名称:“”=>“cd”
路径:“”=>“/”
唯一\u id:“”=>“”
aws_iam_用户。用户[1]:2秒后销毁完成
用户[1]:正在创建。。。
arn:“”=>“”
强制销毁:“”=>“假”
名称:“”=>“ef”
路径:“”=>“/”
唯一\u id:“”=>“”
我的结论是,在当前情况下,
污染
资源,如果您更改列表中的顺序,则强制terraform创建新资源 在上述情况下,删除ab用户导致的确切问题是什么?是否也在数组中创建密钥?谢谢您的回答。作为一种解决方法,我更愿意在状态中更改阵列(使用地形状态mv
),这样其他用户将保持不变,只有我删除的用户将被销毁。但这当然太乱了。另外,如果资源仍然是状态文件中的数组,我不确定版本0.12中的for_each
(或for
)循环是否有帮助。您提供的链接中的示例是资源中的动态时钟。我认为实现这一目标的唯一方法是两种方法之一:(在下一条评论中)1。Terraform应该将状态文件中的资源保存为资源映射/散列,而不是数组,以便知道哪个用户属于哪个位置。2.资源仍将保存为数组,但terraform将进行一些计算,以了解我是否刚刚从列表中删除了一项。也许我会为此打开一个功能请求,但我不确定terraform的内部以及这些选项是否有意义。@roeezab否,terraform state mv
根本无法解决这个问题terraform state rm
仅用于清除tfstate文件中的指定资源,而不是真正清除aws帐户中的资源taint
将标记要销毁的资源,因此,terraform apply
将始终首先销毁这些受污染的资源,然后应用其余的更改。同意为此直接向GitHub中的terraform团队提出功能/错误请求。严格来说,这不是真的count
始终被正式用于创建多个资源(否则它的意义是什么),这包括API没有要传递给它的count概念的地方(例如,EC2实例允许您在单个API调用中指定在保留中创建的多个实例)。0.12确实在资源中添加了额外的循环功能,它最终将取代count
语法,但count
对资源仍然有效。此外,0.12将正确处理自动删除count
资源中的非最后一个元素。