Reputation: 609
I am looking for a way to pass data template_cloudinit_config to another module. I am clear about how to pass variables to module for various data types including object, but I am not sure how to do this with data.
In this setup, I have a vm-basic module that will define all the virtual hardware configuration, and postgres Terraform script that will define service related information including cloud init scripts. The intention is to have vm virtual hardware configuration to be highly reusable as module, to allow me focusing only on service related info i.e. postgres, nginx etc.
This is my vm-basic vars.tf
file that will accept parameters that will be used in virtual hardware configuration.
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 }) }
How custom data will be used in vm-basic module
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
...
...
}
How the other script will pass parameter to vm-basic module
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}" }
)
}
}
How can I pass data object to another Terraform module?
Upvotes: 2
Views: 5863
Reputation: 74739
The meaning of the error you saw is that Terraform is expecting the argument to the object
type constraint to be name = type
pairs, but you only wrote data
and so Terraform is reporting that there's a missing =
.
To make this work, you'll need to write a valid type constraint. It's not clear to me from your question exactly what custom_data
represents, but I do see your later example includes var.custom_data.rendered
and so from that I can tell that the type constraint should at least include a rendered
attribute in order to make that valid, and the custom_data
argument to azurerm_linux_virtual_machine
expects a string so I'll match that:
variable "custom_data" {
type = object({
rendered = string
})
}
This means that Terraform will accept any object value which has a rendered
attribute that can convert to string
, and thus your later reference to var.custom_data.rendered
is guaranteed to work and always produce a string value.
Upvotes: 1
Reputation: 609
In the variable vars.tf file, it's enough to just do
variable "custom_data" {}
In the vm-basic module, refer to the variable through var, similar to others.
custom_data = var.custom_data.rendered
Upvotes: 3