将数据作为变量传递给 Terraform 模块

时间:2021-07-02 16:03:50

标签: terraform terraform-provider-azure

我正在寻找一种将数据 template_cloudinit_config 传递给另一个模块的方法。我很清楚如何将变量传递给包括对象在内的各种数据类型的模块,但我不确定如何处理数据。

在这个设置中,我有一个 vm-basic 模块,它将定义所有虚拟硬件配置,以及 postgres Terraform 脚本,它将定义服务相关信息,包括云初始化脚本。目的是让 vm 虚拟硬件配置作为模块高度可重用,让我只关注与服务相关的信息,即 postgres、nginx 等。

这是我的 vm-basic vars.tf 文件,它将接受将在虚拟硬件配置中使用的参数。

variable "prefix" {}

variable "rg" { type = object({ 
    name = string
    location = string 
}) } 

variable "vm_size" {}
variable "private_ip_address" {}
variable "subnet" { type = object({ id = string }) } 
variable "data_disk_size_gb" { type = number }

variable "service_name" { type = string }
variable "admin_username" { type = string }
variable "admin_public_key_path" { type = string }

variable "nsg_allow_tcp_ports" { type = list(string) }

locals {
  nsg_allow_tcp_ports = {for p in var.nsg_allow_tcp_ports: index(var.nsg_allow_tcp_ports, p) => p}
}


#### DOES NOT WORK ######
#### Expected an equals sign ("=") to mark the beginning of the attribute value. ######
variable "custom_data" { type = object({ data }) }

如何在 vm-basic 模块中使用自定义数据

resource "azurerm_linux_virtual_machine" "vm" {
    name                  = "${var.prefix}-${var.service_name}-vm"
    location              = var.rg.location
    resource_group_name   = var.rg.name
    ...
    ...
    custom_data = var.custom_data.rendered
    ...
    ...
}

其他脚本如何将参数传递给 vm-basic 模块

module "vm-basic" { 
  source = "../../base/vm"
  service_name = var.service_name

  prefix = var.prefix
  rg = var.rg
  vm_size = var.vm_size
  private_ip_address = var.private_ip_address
  subnet = var.subnet
  data_disk_size_gb = var.data_disk_size_gb

  admin_username = var.admin_username
  admin_public_key_path = var.admin_public_key_path

  nsg_allow_tcp_ports = var.nsg_allow_tcp_ports
}

data "template_cloudinit_config" "config" {
  gzip = true
  base64_encode = true
  part {
      filename = "init-cloud-config"
      content_type = "text/cloud-config"
      content = file("init.yaml")
  }
  part {
      filename = "init-shellscript"
      content_type = "text/x-shellscript"
      content = templatefile("init.sh",
        { hostname = "${var.prefix}-${var.service_name}" }
      )
  }
}

如何将数据对象传递给另一个 Terraform 模块?

2 个答案:

答案 0 :(得分:1)

在变量vars.tf文件中,做就够了

variable "custom_data" {}

在vm-basic模块中,通过var引用变量,和其他类似。

custom_data = var.custom_data.rendered

答案 1 :(得分:0)

您看到的错误的含义是 Terraform 期望 object 类型约束的参数为 name = type 对,但您只写了 data,因此 Terraform 报告缺少一个 =

要完成这项工作,您需要编写一个有效的类型约束。从你的问题中我不清楚 custom_data 到底代表什么,但我确实看到你的后面的例子包括 var.custom_data.rendered,因此我可以看出类型约束应该至少 包含一个 rendered 属性以使其有效,并且 custom_dataazurerm_linux_virtual_machine 参数需要一个字符串,因此我将匹配它:

variable "custom_data" {
  type = object({
    rendered = string
  })
}

这意味着 Terraform 将接受具有可以转换为 renderedstring 属性的任何对象值,因此您以后对 var.custom_data.rendered 的引用保证有效并始终产生一个字符串值。