flux-iac / tofu-controller

A GitOps OpenTofu and Terraform controller for Flux
https://flux-iac.github.io/tofu-controller/
Apache License 2.0
1.31k stars 137 forks source link

Support list when using outputs from another Terraform plan #1481

Open manicole opened 1 week ago

manicole commented 1 week ago

(Kind of reopening https://github.com/flux-iac/tofu-controller/issues/465, although supposingly fixed by https://github.com/flux-iac/tofu-controller/pull/504 @chanwit)

I am using a Terraform plan to spawn an Openstack instance, outputting:

output "instance_ips" {
  description = "list of openstack instances ips"
  value       = openstack_compute_instance_v2.instance.*.access_ip_v4
}

output "instance_names" {
  description = "list of openstack instances names"
  value       = openstack_compute_instance_v2.instance.*.name
}

output "instance_ssh_key" {
  description = "openstack instance ssh key"
  value       = tls_private_key.instance_ssh_key.private_key_pem
  sensitive   = true
}

I am using the output Secret as an input for my next Terraform plan (installing a k3s cluster):

apiVersion: infra.contrib.fluxcd.io/v1alpha2
kind: Terraform
metadata:
  name: ${service}
spec:
  [...]
  varsFrom:
  - kind: Secret
    name: ${previous}-output

and declare instance_ipsas a list of strings:

variable "instance_ips" {
  type        = list(string)
  description = "list of openstack instances ips"
  nullable    = false
}

I get the following error message:

│ Error: Invalid value for input variable                                                                                                                  │
│                                                                                                                                                          │
│   on generated.auto.tfvars.json line 1:                                                                                                                  │
│    1: {"instance_ips":"***","instance_ips__type":"***","instance_names":"***","instance_names__type":"***","instance_ssh_key":"***","previous":"***","se │
│ rvice":"***","target":"***"}                                                                                                                             │
│                                                                                                                                                          │
│ The given value is not suitable for var.instance_ips declared at                                                                                         │
│ variables.tf:27,1-24: list of string required.

Not sure how I should handle that ... I am mistaking somewhere ? Thanks

manicole commented 1 week ago

For anyone interested, my current dirty workaround is to declare in my k3s Terraform plan instance_ips as a string and use a local variable in my main.tf:

locals {
  tmp_instance_ips = split(",", var.instance_ips)
  instance_ips = [for instance_ip in local.tmp_instance_ips: element(split("\"", instance_ip), 1)]
}

It allows me to get back in local.instance_ips the list of IPs without brackets, quotes or spaces, exactly as written in my Secret ${previous}-output.

ilithanos commented 1 week ago

The fix never completely worked as intended in my experience. What I personally did as a workaround was using JSON strings for any output/input that wasn’t a simple string output and then decode than into a local.

it’s a workaround, not a real fix, but it works consistently.

manicole commented 6 days ago

Thanks for sharing @ilithanos!

@chanwit Any clue on what fails here / how to? Thanks!