Terraform - 当模块的资源已存在时出现错误 (409)



我正在编写一个地形模块,它应该在不同的环境中重用。

为了使事情变得简单,这里有一个从一个环境根模块调用模块的基本示例:

##QA-resources.tf
module "some_module" {
source = "./path/to/module" 
}
some_variable = ${module.some_module.some_output}

问题是,当一个模块已经创建时,Terraform会抛出一个错误:

创建[资源类型][资源名称]时出错:具有[资源名称]的EntityAlreadyExists:[资源类型]已存在。状态代码:409,请求id:。。。

当模块是在外部terraform.tfstate的作用域下创建的,并且其中一个资源具有类似"Name"的唯一字段时,就会发生这种情况。

在我的案例中,它发生在尝试使用IAM模块时,该模块已经创建了具有该特定名称的角色,但在许多其他情况下也可能发生(我不希望讨论特定于我的用例(。

我希望,如果模块的某个资源存在,则不会发生故障,并且模块的输出将可用于root模块

如何管理(可能使用特定命令或标志(有什么建议吗?


我发现了几个相关的线程:

Terraform没有重用它刚刚创建并失败的AWS角色?

解决地形中EntityAlreadyExists错误的最佳方法是什么?

Terraform错误EntityAlreadyExists:名为iam_for_lambda的角色已存在


编辑

对于@Martin Atkins的请求,以下是导致错误的资源。

它是附加了2个策略(通过var.policies传递(的AWS EKS集群的基本角色:

resource "aws_iam_role" "k8s_role" {
name = "k8s-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy_attachment" "role-policy-attach" {
role  = "${aws_iam_role.k8s_role.name}"
count = "${length(var.policies)}"
policy_arn = "${element(var.policies, count.index)}"
}

此角色被包装为一个模块,并被传递给根模块
由于根模块试图创建角色时该角色已存在,因此发生了上面在块引号中提到的错误。

在Terraform的视图中,每个对象要么由Terraform管理,要么不由Terraform管理。Terraform避免隐式地获取现有对象的所有权,因为如果要这样做,那么当您随后运行terraform destroy时,您可能会无意中破坏Terraform不打算管理的东西。

在您的情况下,这意味着您需要决定名为k8s-role的角色是否由Terraform管理,如果您有多个Terraform配置,则需要选择一个配置来管理该对象。

在一个将管理对象的Terraform配置中,可以使用resource "aws_iam_role"来指定。如果任何其他配置需要访问它,或者它根本不会用Terraform管理,那么在需要的情况下,您可以直接引用角色名称k8s-role。如果您需要更多关于该角色的信息,而不仅仅是它的名称,那么您可以使用aws_iam_role数据源来获取该信息,而无需声明要管理对象:

data "aws_iam_role" "k8s" {
name = "k8s-role"
}

例如,如果您需要使用此角色的ARN,则可以使用data.aws_iam_role.k8s.arn访问此数据资源的arn属性。

最后,如果您的角色当前不是由Terraform管理的,但您想将其归Terraform所有,您可以明确地告诉Terraform开始管理现有对象,方法是导入该对象以创建现有对象和您的resource块之间的关联:

terraform import aws_iam_role.k8s_role k8s-role

相关内容

  • 没有找到相关文章

最新更新