terraform icon indicating copy to clipboard operation
terraform copied to clipboard

Allow YAML variable definition files; terraform.yml.tfvars

Open TeamDman opened this issue 4 years ago • 2 comments

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

TeamDman avatar Jun 11 '21 14:06 TeamDman

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

mohsiur avatar Jul 06 '21 10:07 mohsiur

Other advantages of YAML over JSON include:

  • Multi line variables without escaped characters
  • Comments
  • Improved readability (no quotes on keys, trailing commas, etc.)

Tomy8s avatar Oct 29 '25 16:10 Tomy8s