As a matter of hygiene we try to validate all our input variables, like
variable "account" {
default = null
type = string
description = "AWS account and corresponding environment into which this will be deployed"
validation {
condition = anytrue([for a in [null, "devops", "dev", "staging", "prod"] : var.account == a])
error_message = "Account can only be one of: devops, dev, staging, or prod."
}
}
data "aws_iam_account_alias" "this" {}
locals {
account_map = {
mycoeng = "dev"
mycoops = "devops"
myrootco = "mgmt"
mycoproduction = "prod"
mycostage = "staging"
}
account = (var.account == null) ? local.account_map[data.aws_iam_account_alias.this.account_alias] : var.account
}
In the Cloud UI for a new Variable Set I checked the Terraform variable and HCL boxes, put account in the Key and { default = null type = string description = "AWS account and corresponding environment into which this will be deployed" validation { condition = anytrue([for a in [null, "devops", "dev", "staging", "prod"] : var.account == a]) error_message = "Account can only be one of: devops, dev, staging, or prod." } }
(prettyprinted when editing) in the Value. That returned * Invalid HCL in variable "account": At 2:17: Unknown token: 2:17 IDENT null
What’s the right way to validate input values in Variable Sets?
If I’m following correctly what you described, it seems like you’ve placed a variable declaration into the Terraform Cloud variable UI, rather than a variable value.
The declaration of the variable (which includes its default value if any, its description, its type constraint, and validation rules) should remain in your .tf files as before when you adopt Terraform cloud.
What can move to Terraform Cloud is the value for each variable. Based on the declaration you showed in your first snippet, I would expect to set this up in Terraform Cloud’s variables UI like this:
Enter account as the “key”
Enter any one of devops, dev, staging, or prod as the “value”
Don’t check “HCL”, because this is just a plain string value and so there’s no need to write it using HCL syntax.
When Terraform Cloud is preparing to run Terraform CLI, the Terraform Cloud agent will automatically generate a terraform.tfvars file in the current working directory which specifies all of the values you entered. For this particular one, it might look like this:
account = "dev"
Then when Terraform CLI runs, it’ll find that file automatically and use it to populate the values of the variables you declared. Terraform CLI will then test whether the provided value matches all of the validation conditions, and would succeed for my above example because "dev" is one of the values allowed by your condition.
Thanks, that makes sense. For some reason I thought the shared Variable Sets could hold declarations, not just values like other variables. Maybe I was hoping they could, since the other parts of a declaration are useful to share too. I suppose we could bake the declarations into modules for sharing purposes.