【问题标题】:Terraform - EntityAlreadyExists Error (409) when a module's resource already existsTerraform - 当模块的资源已经存在时,EntityAlreadyExists 错误 (409)
【发布时间】:2020-03-12 10:45:05
【问题描述】:

我正在编写一个 模块,它应该可以在不同的环境中重复使用。

为了简单起见,这里有一个从环境根模块之一调用模块的基本示例:

##QA-resources.tf

module "some_module" {
  source = "./path/to/module" 
}

some_variable = ${module.some_module.some_output}

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

创建 [resource-type] [resource-name] 时出错:EntityAlreadyExists:带有 [resource-name] 的 [resource-type] 已存在。 状态码:409,请求ID:...

当模块在外部 terraform.tfstate 范围内创建并且其中一个资源具有唯一字段(如“名称”)时,就会发生这种情况。

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

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

对如何管理有任何建议(可能使用特定命令或标志)?


我找到了一些相关的线程:

Terraform doesn't reuse an AWS Role it just created and fails?

what is the best way to solve EntityAlreadyExists error in terraform?

Terraform error EntityAlreadyExists: Role with name iam_for_lambda already exists


编辑

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

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

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)}"
}

这个角色被包装成一个模块并被传递给根模块。
上面提到的块引用中的错误是因为在根模块尝试创建角色时角色已经存在。

【问题讨论】:

  • 为了提供有用的答案,查看minimal reproducible example 和您看到的确切错误消息会有所帮助,而不会省略其中的关键部分(我们正在谈论的资源类型)。正如目前所写,这个问题过于笼统,无法给出具体答案。
  • 感谢@MartinAtkins,我已经编辑了问题并添加了导致错误的资源。请注意,我已经指定了我收到的确切错误消息(在块引用中)。告诉我是否缺少其他内容。

标签: terraform amazon-web-services terraform amazon-iam


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多