Open mark-rushakoff opened 2 years ago
Hi, many thanks for your feature request!
Your feature request is a valid one, and is technically possible with multipass
. One way to solve it is to have the provider write temporary files with the cloudinit content, and another is to use stdin to pass the content in directly, by using this feature: https://github.com/canonical/multipass/pull/628. Adding this feature is on my horizon. :-)
multipass
doesn't provide a way to see the cloudinit file after it has been launched, nor does it give any checksum value for the contents, so it will be impossible to check if any content has changed from its side. So, we can spot any content diffs by using the Terraform state file only.
One way you can work around this provider's lack of a cloudinit_data
parameter with Terraform is by using the hashicorp/local
provider[1]. It provides you with a local_file
resource that you can use to write files.
data "cloudinit_config" "cloudinit_ubuntu" {
part {
content = file("./cloudinit/groups.yml")
}
part {
content = file("./cloudinit/users.yml")
}
# etc.
}
resource "local_file" "cloudinit_ubuntu" {
filename = "ubuntu-cloudinit.yml"
content = data.cloudinit_config.cloudinit_ubuntu.rendered
}
resource "multipass_instance" "ubuntu" {
name = "ubuntu"
disk = "3072MiB"
memory = "512MiB"
cloudinit_file = local_file.cloudinit_ubuntu.filename
}
[1] https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file
Thanks for teaching me how to use the local_file
resource properly. That approach correctly passes the rendered file to multipass, but unfortunately, multipass does not (yet) support multipart/mime cloudinit files: https://github.com/canonical/multipass/issues/1892
I can find another way to combine the YAML segments, which will be sufficient if I end up only needing to combine plain cloud config data.
This is how I solved this (adjacent cloud-init template yaml inside of ./template/cloud-init.yaml.tpl
)
edit: Just realized it's fairly similar to @larstobi, but this features variable interpolation using template files, so slightly different.
I think passing this in via stdin would be awesome and happy to work on that PR if you haven't already!
resource "local_file" "cloudinit" {
for_each = { for i, name in var.instance_names : name => {
ip_address = var.ip_addresses[i]
} }
filename = "${path.module}/cloud-init-${each.key}.yaml"
content = templatefile("${path.module}/templates/cloud-init.yaml.tpl", {
ip_address = each.value.ip_address
})
}
resource "multipass_instance" "dev_vm" {
for_each = { for i, name in var.instance_names : name => {
ip_address = var.ip_addresses[i]
} }
name = each.key
cpus = var.cpus
memory = var.memory
disk = var.disk
image = var.image
cloudinit_file = local_file.cloudinit[each.key].filename
}
I am trying to use
cloudinit_config
with manypart
blocks to compose a MIME document to use for cloudinit against a multipass resource.The
cloudinit_config
resource only exposes arendered
value. I am new to terraform, so maybe I'm missing something, but I don't see a way to write that rendered value to a file, and then provide the path of the file to the multipass resource.I would like to be able to write:
AFAICS, it should be okay to hold
cloudinit_data
in memory, and then pass it as stdin tomultipass launch --cloud-init=-
, but it could just as well go into a temporary file managed by the multipass provider if necessary.