仅在不存在时如何创建 terraform 资源

Posted

技术标签:

【中文标题】仅在不存在时如何创建 terraform 资源【英文标题】:How to create a terraform resource only if doesn't exists 【发布时间】:2020-04-13 17:54:17 【问题描述】:

我正在使用 terraform 在 AWS 中创建一个角色。由于 IAM 是非区域服务,我只想创建一次角色。所以每当我运行 terraform 时,它应该检查角色是否已经存在,如果不存在,它应该创建一个。

data "aws_iam_role" "iam_role_check" 
  name = "some_role"


resource "aws_iam_role" "iam_role" 
  count= "$data.aws_iam_role.iam_role_check != "null" ? 0 : 1"
  name = "some_role"

  assume_role_policy = <<EOF

  "Version": "2012-10-17",
  "Statement": [
    
      "Action": "sts:AssumeRole",
      "Principal": 
        "Service": "lambda.amazonaws.com"
      ,
      "Effect": "Allow",
      "Sid": ""
    
  ]

EOF

data.aws_iam_role.iam_role_check:刷新状态...

错误:读取 IAM 角色 (some_role) 时出错:NoSuchEntity:具有 找不到名称 some_role。状态码:404,请求ID:

【问题讨论】:

这是 terraform 默认执行的操作。检查资源是否已经存在,如果不存在则创建一个 只有当我有 .tfstate 文件时才这样。例如,如果我正在为 us-east-1 和预置资源创建工作区,则现在在 AWS 中创建角色,并且 .tfstate 文件位于工作区 us-east-1 下。如果我为 us-east-2 再创建一个工作区并再次运行 terraform 会怎样,因为没有 .tfstate 文件,它将再次尝试配置该角色。我的要求是在所有 AWS 区域中运行相同的 terraform(具有 lambda 函数以在所有区域中部署)并且只配置一次角色。 添加了我的答案。我认为您应该编辑帖子,因为您描述的场景仅通过阅读帖子并不清楚 【参考方案1】:

我认为这种情况下最简单的解决方案是只为共享资源创建一个单独的状态,并在对其他状态运行应用之前对其运行应用

【讨论】:

【参考方案2】:

我也遇到过类似的问题。我编写了一个 python 脚本来检查 IAM 角色是否存在。基于此,它将在 tfvar 文件中设置计数变量值(0/1)。 仅使用 terraform 是无法实现的。

【讨论】:

知道你是如何创建 python 的吗?如果你能分享会喜欢吗? 嗨@Cryptic22,但是当您执行另一个terraform 应用程序时,由于现在count 值在您的下一个应用程序中变为0,它会删除资源。你是怎么处理的?我有同样的问题【参考方案3】:

没有已知方法,因为它的设计原理,请参阅this GitHub issue。

我认为根据需要创建尽可能多的角色并没有错。您可以在角色名称中包含一些区别位,例如部署名称或环境。您可能还希望将一些常见配置与其他“常见”terraform 部署分开,并仅在其他地方使用数据源。

如果无法为同一事物创建多个实例,例如 AWSServiceRoleForAmazonElasticsearchService for the Amazon Elasticsearch Service,Cloud Posse 会在其 terraform Elasticsearch module 中创建一个简单的变量是否应该创建角色,请在其中搜索 create_iam_service_linked_role README.md。

【讨论】:

以上是关于仅在不存在时如何创建 terraform 资源的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb如何仅在不存在时插入(如果存在则不更新)?

terraform 资源创建 - 这个关键字

Oracle - 仅在不存在时创建索引

postgres仅在不存在时创建用户[重复]

仅在不存在时将脚本添加到头部

Fluent NHibernate - 仅在不存在时创建数据库模式