Allow YAML variable definition files; terraform.yml.tfvars
Current Terraform Version
Terraform v0.15.1
Use-cases
YAML has anchors and references, which are useful for reducing duplication and still allowing overrides of default values.
Would allow default values without having to use (currently experimental) optional fields in variable definitions paired with coalesce statements.
Example terraform.yml.tfvars
# "ignored", used to supply anchor
template:
probe: &probe
interval: 30
minimum_servers: 0
path: /
pick_host_name_from_backend_http_settings: false
port: 443
protocol: Https
timeout: 30
unhealthy_threshold: 3
success_status_codes:
- 200-404
probes:
# use references to anchors to pull default values
- <<: *probe
name: myProbe
path: /api
port: 80
protocol: http
- <<: *probe
name: myOtherProbe
path: /other
variables.tf
variable "probes" {
type = object({
name = string
interval = number
minimum_servers = number
path = string
pick_host_name_from_backend_http_settings = bool
port = number
protocol = string
timeout = number
unhealthy_threshold = number
success_status_codes = set(string)
})
}
Attempted Solutions
Yaml files can be loaded in as a local value, but this lacks the checking and safety of variable declarations.
Doesn't support custom validators or secret values.
(terraform docs on variables for reference)
locals {
probes = yamldecode(file("./probes.yml")).probes
}
Additionally, for optional fields, try must be used instead of coalesce due to undefined fields throwing errors rather than returning null.
Functions aren't allowed in variable defaults, so something like this doesn't work:
variable "probes" {
type = object({
name = string
interval = number
minimum_servers = number
path = string
pick_host_name_from_backend_http_settings = bool
port = number
protocol = string
timeout = number
unhealthy_threshold = number
success_status_codes = set(string)
})
default=yamldecode(file("terraform.yml.tfvars"))
}
Proposal
Terraform already supports terraform.json.tfvars files.
One hacky solution would be a preprocessor to convert the yaml to json with existing HCL functions before passing it to whatever mechanisms consume the normal json file.
jsonencode(yamldecode(file("terraform.yaml.tfvars"))
References
- https://github.com/hashicorp/packer/issues/9430
I did a hack solution of this here https://mohsiur.medium.com/terraform-yaml-%EF%B8%8F-3550a3642dd3 , I'm yet to try using anchors but also wondering if there's interest in using yaml files as .tfvars
Other advantages of YAML over JSON include:
- Multi line variables without escaped characters
- Comments
- Improved readability (no quotes on keys, trailing commas, etc.)