AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 833810
Accepted
vikas027
vikas027
Asked: 2017-02-21 15:14:32 +0800 CST2017-02-21 15:14:32 +0800 CST 2017-02-21 15:14:32 +0800 CST

Terraform - 使用带有计数的嵌套循环

  • 772

我正在尝试在 terraform 中使用嵌套循环。我有两个列表变量list_of_allowed_accountsand list_of_images,并希望遍历 list list_of_images,然后遍历 list list_of_allowed_accounts。

这是我的地形代码。

variable "list_of_allowed_accounts" {
  type    = "list"
  default = ["111111111", "2222222"]
}

variable "list_of_images" {
  type    = "list"
  default = ["alpine", "java", "jenkins"]
}

data "template_file" "ecr_policy_allowed_accounts" {
  template = "${file("${path.module}/ecr_policy.tpl")}"

  vars {
    count = "${length(var.list_of_allowed_accounts)}"
    account_id = "${element(var.list_of_allowed_accounts, count.index)}"
  }
}

resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
  count = "${length(var.list_of_images)}"
  repository = "${element(aws_ecr_repository.images.*.id, count.index)}"
  count = "${length(var.list_of_allowed_accounts)}"
  policy = "${data.template_file.ecr_policy_allowed_accounts.rendered}"
}

这相当于我正在尝试做的事情。

for image in alpine java jenkins
do 
  for account_id in 111111111 2222222
  do 
    // call template here using variable 'account_id' and 'image'
  done
done
count terraform
  • 6 6 个回答
  • 39440 Views

6 个回答

  • Voted
  1. Best Answer
    Martin Atkins
    2017-04-04T13:23:00+08:002017-04-04T13:23:00+08:00

    Terraform 没有直接支持这种嵌套迭代,但我们可以用一些算术来伪造它。

    variable "list_of_allowed_accounts" {
      type = "list"
      default = ["1111", "2222"]
    }
    
    variable "list_of_images" {
      type = "list"
      default = ["alpine", "java", "jenkins"]
    }
    
    data "template_file" "ecr_policy_allowed_accounts" {
      count = "${length(var.list_of_allowed_accounts) * length(var.list_of_images)}"
    
      template = "${file("${path.module}/ecr_policy.tpl")}"
    
      vars {
        account_id = "${var.list_of_allowed_accounts[count.index / length(var.list_of_images)]}"
        image      = "${var.list_of_images[count.index % length(var.list_of_images)]}"
      }
    }
    
    resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
      count = "${data.template_file.ecr_policy_allowed_accounts.count}"
    
      repository = "${var.list_of_images[count.index % length(var.list_of_images)]}"
      policy = "${data.template_file.ecr_policy_allowed_accounts.*.rendered[count.index]}"
    }
    

    由于我们要为帐户和图像的每个组合创建一个策略模板,count因此template_file数据块上的 是两者相乘。然后,我们可以使用除法和模运算来返回count.index每个列表的单独索引。

    由于我没有您的策略模板的副本,因此我只使用了占位符;因此,这种配置给出了以下计划:

    + aws_ecr_respository_policy.repo_policy_allowed_accounts.0
        policy:     "policy allowing 1111 to access alpine"
        repository: "alpine"
    
    + aws_ecr_respository_policy.repo_policy_allowed_accounts.1
        policy:     "policy allowing 1111 to access java"
        repository: "java"
    
    + aws_ecr_respository_policy.repo_policy_allowed_accounts.2
        policy:     "policy allowing 1111 to access jenkins"
        repository: "jenkins"
    
    + aws_ecr_respository_policy.repo_policy_allowed_accounts.3
        policy:     "policy allowing 2222 to access alpine"
        repository: "alpine"
    
    + aws_ecr_respository_policy.repo_policy_allowed_accounts.4
        policy:     "policy allowing 2222 to access java"
        repository: "java"
    
    + aws_ecr_respository_policy.repo_policy_allowed_accounts.5
        policy:     "policy allowing 2222 to access jenkins"
        repository: "jenkins"
    

    每个策略实例适用于不同的帐户 ID 和图像对,涵盖所有组合。

    • 41
  2. user529562
    2019-06-28T19:40:10+08:002019-06-28T19:40:10+08:00

    这里的答案确实有效(我最初使用它们),但我认为使用 Terraform 的setproduct函数有更好的解决方案。我还没有看到很多它在互联网上使用的例子,但是 setproduct 需要两个集合(或更重要的是,两个列表)并生成一个包含每个输入排列的集合列表。就我而言,我正在创建 SSM 参数:

    variable "list1" {
      type    = "list"
      default = ["outer1", "outer2"]
    }
    
    variable "list2" {
      type    = "list"
      default = ["inner1", "inner2", "inner3"]
    }
    
    locals {
      product = "${setproduct(var.list1, var.list2)}"
    }
    
    resource "aws_ssm_parameter" "params" {
      count     = "${length(var.list1) * length(var.list2)}"
      name      = "/${element(local.product, count.index)[0]}/${element(local.product, count.index)[1]}"
      type      = "String"
      value     = "somevalue"
      overwrite = false
      lifecycle { ignore_changes = ["value"] }
    }
    

    这将创建名为:

    /outer1/inner1
    /outer1/inner2
    /outer1/inner3
    /outer2/inner1
    /outer2/inner2
    /outer2/inner3
    

    我的小脑袋可以比其他答案中的模魔法更容易地解析这个!

    • 11
  3. Justin Grote
    2019-05-22T15:29:49+08:002019-05-22T15:29:49+08:00

    仅供参考,如果有人从谷歌来这里,如果你使用的是 terraform 0.12,你将需要在你做划分的任何地方使用 floor 函数,否则你会收到关于部分索引的错误。

    account_id = var.list_of_allowed_accounts[ floor (count.index / length(var.list_of_images))]

    • 7
  4. Pieter
    2021-01-14T08:36:12+08:002021-01-14T08:36:12+08:00

    虽然在某些情况下使用setproduct和使用模数的解决方案有效,但还有一个更优雅的解决方案:使用terraform 模块(不要与模运算符混淆)。通过使用 terraform 模块,出现了使用 count 元参数的额外机会。

    如果不是所有输入组合都适用,则此解决方案特别有用。例如,我使用这个解决方案来处理一个项目列表,其中每个项目都有一个独特角色的列表。

    例如,在顶层你可以使用这个:

    variable "account_images" {
      type = map(list(string))
      default = {
        "1111" = ["alpine", "java"],
        "2222" = ["jenkins"]
      }
    }
    
    module "account" {
      source = "../accounts"
      count = length(var.account_images)
      account = keys(var.account_images)[count.index]
      images = var.account_images[keys(var.account_images)[count.index]]
    }
    

    ../accounts然后在包含此内容的目录中添加一个额外的 terraform 模块。

    variable "account" {
      type = string
    }
    
    variable "images" {
      type = list(string)
    }
    
    
    data "template_file" "ecr_policy_allowed_accounts" {
      count = length(var.images)}
    
      template = "${file("${path.module}/ecr_policy.tpl")}"
    
      vars {
        account_id = var.account
        image      = var.images[count.index]
      }
    }
    

    我发现这种方法更容易理解。

    • 1
  5. IgorC
    2017-03-13T14:11:39+08:002017-03-13T14:11:39+08:00

    基本上问题出在数据“template_file”中,无法按照您认为的方式设置 account_id,因为您的情况下的计数只是另一个永远不会增加/更改的 var。只是说因为我想看看你的问题到底是什么。

    • 0
  6. user9192156
    2019-04-13T09:50:01+08:002019-04-13T09:50:01+08:00

    我没有足够的声誉点来为@Martin Atkins提供的答案添加评论,所以我发布了他的答案并稍作修改,这适用于Terraform 问题 20567

    variable "list_of_allowed_accounts" {
      type = "list"
      default = ["1111", "2222"]
    }
    
    variable "list_of_images" {
      type = "list"
      default = ["alpine", "java", "jenkins"]
    }
    
    # workaround for TF issue https://github.com/hashicorp/terraform/issues/20567
    locals {
      policy_count = "${length(var.list_of_allowed_accounts) * length(var.list_of_images)}"
    }
    
    data "template_file" "ecr_policy_allowed_accounts" {
      count = "${local.policy_count}"
    
      template = "${file("${path.module}/ecr_policy.tpl")}"
    
      vars {
        account_id = "${var.list_of_allowed_accounts[count.index / length(var.list_of_images)]}"
        image      = "${var.list_of_images[count.index % length(var.list_of_images)]}"
      }
    }
    
    resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
      count = "${local.policy_count}"
    
      repository = "${var.list_of_images[count.index % length(var.list_of_images)]}"
      policy = "${data.template_file.ecr_policy_allowed_accounts.*.rendered[count.index]}"
    } 
    
    • 0

相关问题

  • 如何在 windows-7 上使用 Apache 2.2 计算图像下载量?

  • innodb 表的行号

  • 如何计算目录中的所有子文件夹?

  • 使用命令行工具按排序顺序计算重复项

  • 如何快速统计一个文件夹中的文件数量?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve