【问题标题】:Can terraform use a variable hash or map or maps to create data entries in .tf files?terraform 可以使用变量散列或映射或映射在 .tf 文件中创建数据条目吗?
【发布时间】:2018-02-13 23:37:18
【问题描述】:

我一直在测试 terraform (v.0.10) 以在 AWS 中为企业预置 EC2 实例、安全组、RDS 实例等。

我正在使用模块方法,以便可以为我的每个环境“获取”这些内容:

apps:
  main.tf
  app.tf
  vars.tf
sec_groups:
  main.tf
  sec_group.tf
  vars.tf
:
:

对于我的每个环境(非产品、产品),我都在采购这些模块,并将 terraform 状态存储在远程 s3 存储桶中 - 每个环境一个存储桶。

我为每个环境提供必要的变量,例如子网cidrs、VPC 名称等,然后创建环境:VPC 有其相关的子网,其中包含相关的 EC2 实例......一切都很好!

当我添加安全组(我在各种类型的 EC2 实例和环境中有很多)及其各自的规则时,我的挑战就来了。

虽然我可以在合适的 sec_group.tf 文件中创建规则库并添加出口/入口规则(每个规则都有它们的 from_port、to_port、protocol、cidr_blocks..),但我想知道是否可以根据 ( json) 数据的哈希值?

我的想法是,这种全局数据层次结构可用于保存规则,并可进行处理以收集每个环境的相关规则,并仅应用与“terraform apply”正在运行的当前环境相关的规则,即有 2 或 200 条规则。像这样的:

non-prod-env:
  ssh:
    from_port: 22
    to_port: 22
    protocol: "tcp"
    cidr_blocks:
      - 10.1.1.1
      - 10.2.2.2
    :
    :
  smtp:
    from_port: 25
    to_port: 25
    protocol: "tcp"
    cidr_blocks:
      - 100.1.1.1
      - 100.2.2.2
   :
   :
prod-env:
  ssh:
    from_port: 22
    to_port: 22
    protocol: "tcp"
    cidr_blocks:
      - 11.1.1.1
      - 11.2.2.2
    :
    :

阅读了各种类型的变量(字符串、列表、映射)后,我不确定我所问的是否可能,但它允许所有环境都可以从中提取集中式(全局)数据源。

我很想知道以前是否有人考虑过/研究过这种方法,或者是否有一种我可能会遗漏的更简单的方法。

任何想法或cmets将不胜感激。

干杯

【问题讨论】:

  • 我想我应该在这个问题后面解释更多 - 想要考虑使用散列的原因(以某种方式)类似于你在 puppet 中使用 hiera 的方式:通用键值对系统,可以在哈希值较低的位置被覆盖。合并将允许单一数据源最大限度地减少变量重复的使用。

标签: amazon-ec2 terraform


【解决方案1】:

Terraform 尚不支持嵌套地图 (terraform#2114),但您或许可以使用 External Data Source 从全局 JSON 文件中读取数据。

这里完全是一个选项,但我已经确定逻辑操作超出了 HCL 的设计目标,应该将更复杂的编排放入自定义提供程序中。 HCL 计划应该明确说明它正在做什么,而不是从外部资源中获得。以下是我处理 ACL 和安全组规则的方法:

ACL:

其中变量 network_ssh_access 是此 VPC 允许的 cidr 块列表

variable network_ssh_access {
  type    = "list"
  default = []
}

resource "aws_network_acl" "main" {
  vpc_id = "${aws_vpc.main.id}"
}

resource "aws_network_acl_rule" "network_ssh_access" {
  count          = "${length(var.network_ssh_access)}"
  network_acl_id = "${aws_network_acl.main.id}"
  rule_number    = "${200 + count.index}"
  egress         = false
  protocol       = "tcp"
  rule_action    = "allow"
  cidr_block     = "${element(var.network_ssh_access, count.index)}"
  from_port      = 22
  to_port        = 22
}

安全组: 其中变量appname_ssh_access 是名为“appname”的应用程序允许的 cidr 块列表

variable appname_ssh_access {
  type    = "list"
  default = []
}

resource "aws_security_group" "appname" {
  name        = "appname"
}

resource "aws_security_group_rule" "allow_all" {
  count           = "${length(var.appname_ssh_access)}"
  type            = "ingress"
  from_port       = 22
  to_port         = 22
  protocol        = "tcp"
  cidr_blocks     = "${element(var.network_ssh_access, count.index)}"
  security_group_id = "${aws_security_group.appname.id}"
}

然后,您将为其余端口和协议(邮件、http、https 等)复制此模型。

【讨论】:

    猜你喜欢
    • 2011-09-23
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2016-05-14
    • 2011-08-04
    相关资源
    最近更新 更多