terraform map and object variables as input
Since the second config works with the defaults for the variable, the config isn't the issue, the terraform apply -var
must be the issue. It's a very tricky thing to get right and has a number of problematic interactions with shell parsing rules that can trip you up.
I find using .tfvars files far more reliable and I no longer try to get -var working for my Terraform work.
terraform.tfvars:
storageProfile2 = {
storage_mb = 102400
backup_retention_days = 15
geo_redundant_backup_enabled = false
administrator_login = "pgadmin1223"
}
Ceate terraform.tfvars as above in the same directory and then run terraform plan
and terraform apply
without -var. It should resolve your issue.
Original answer
There are several significant changes in the azurerm provider that are intended to be backwards compatible, but are likedly causing the issue here.
geo_redundant_backup is a deprecated attribute as of v2.7.0 or v2.10.0 depending on which database resource you are using. You should use geo_redundant_backup_enabled instead and specify it as boolean (bool type). I suspect the backwards-compatibility isn't completely reliable.
storage_profile blocks are also deprecated and all of their attributes are now top-level on the corresponding.
The examples in the azurerm provider documentation using storage_profile
are incorrect and this:
storage_profile {
storage_mb = var.storageProfile2.storageMb
backup_retention_days = var.storageProfile2.backupRetentionDays
geo_redundant_backup = var.storageProfile2.geoRedundantBackup
}
Should be rewritten as (direct properties on the resource, not inside a block):
storage_mb = var.storageProfile2.storageMb
backup_retention_days = var.storageProfile2.backupRetentionDays
geo_redundant_backup_enabled = var.storageProfile2.geoRedundantBackup
And your storageProfile2 variable declaration should be updated to set the type of geoRedundantBackup to bool:
variable storageProfile2 {
default = {
storageMb = 102400
backupRetentionDays = 15
geoRedundantBackup = false
}
type = object({ storageMb=number, backupRetentionDays=number, geoRedundantBackup=bool })
}
Since azurerm provider v2.7.0 was released on April 23rd, 2020 including these changes:
- azurerm_postgres_server - all properties in the
storage_profile
block have been moved to the top level (#6459)- azurerm_postgres_server - the following properties were renamed and changed to a boolean type:
ssl_enforcement
tossl_enforcement_enabled
,geo_redundant_backup
tobackup_geo_redundant_enabled
, andauto_grow
toauto_grow_enabled
(#6459)
Since azurerm provider v2.10.0 was released on May 12th, 2020 additional storage_profile were flattened:
- azurerm_mariadb_server - all properties in the
storage_profile
block have been moved to the top level (#6865)- azurerm_mysql_server - all properties in the
storage_profile
block have been moved to the top level (#6833)- azurerm_mariadb_server - the following properties were renamed and changed to a boolean type:
ssl_enforcement
tossl_enforcement_enabled
,geo_redundant_backup
togeo_redundant_backup_enabled
, andauto_grow
azurerm_mysql_server
- support for thecreate_mode
property allowing the creation of replicas, point in time restores, and geo restors (#6833)- azurerm_mysql_server - the following properties were renamed and changed to a boolean type:
ssl_enforcement
tossl_enforcement_enabled
,geo_redundant_backup
togeo_redundant_backup_enabled
, andauto_grow
toauto_grow_enabled
(#6833)
Aside: Code Style
Conventional code style in Terraform:
- Use
snake_case
instead ofcamelCase
(not formalized, but every provider follows this as do the examples) - Quote top-level names like resource and variable names
- Align equals signs in groups (those without multiple line breaks between them)
variable "storage_profile_2" {
default = {
storage_mb = 102400
backup_retention_days = 15
geo_redundant_backup_enabled = false
}
type = object(
{
storage_mb = number
backup_retention_days = number
geo_redundant_backup_enabled = bool
}
)
}
And assign attributes as follows
storage_mb = var.storage_profile_2.storage_mb
backup_retention_days = var.storage_profile_2.backup_retention_days
geo_redundant_backup_enabled = var.storage_profile_2.geo_redundant_backup_enabled
The more consistent Terraform code is globally, the easier it will be for all of us practitioners should we ever need to work on someone else's code.
karas27
Updated on June 23, 2022Comments
-
karas27 almost 2 years
There is issue with command line input for any string attribute inside a map/object variable. the below configuration works with below command. But the moment I use any string attribute inside the object variable. it fails
terraform plan -var='storageProfile2={"storage_mb":102400,"backup_retention_days":15,"geo_redundant_backup_enabled":false}'
//main.tf resource "azurerm_postgresql_server" "dmcdevops_postgress" { name = "pstgressdb101" location = azurerm_resource_group.dmc_rg_creation.location resource_group_name = azurerm_resource_group.dmc_rg_creation.name sku_name = "GP_Gen5_4" backup_retention_days = var.storageProfile2.backup_retention_days storage_mb = var.storageProfile2.storage_mb geo_redundant_backup_enabled = var.storageProfile2.geo_redundant_backup_enabled administrator_login = "sdfgsgfsg" administrator_login_password = "H@Sh1CoR3!" version = "11" ssl_enforcement_enabled = true } //variables.tf variable "storageProfile2" { default = { storage_mb = 102400 backup_retention_days = 15 geo_redundant_backup_enabled = false } type = object( { storage_mb = number backup_retention_days = number geo_redundant_backup_enabled = bool } ) }
Below config doesn't work. I just added administrator_login as string attribute to the object variable. terraform plan and apply works with default values tho.
terraform plan -var='storageProfile2={"storage_mb":102400,"backup_retention_days":15,"geo_redundant_backup_enabled":false,"administrator_login":"pgadmin1223"}'
//main.tf resource "azurerm_postgresql_server" "dmcdevops_postgress" { name = "pstgressdb101" location = azurerm_resource_group.dmc_rg_creation.location resource_group_name = azurerm_resource_group.dmc_rg_creation.name sku_name = "GP_Gen5_4" backup_retention_days = var.storageProfile2.backup_retention_days storage_mb = var.storageProfile2.storage_mb geo_redundant_backup_enabled = var.storageProfile2.geo_redundant_backup_enabled administrator_login = var.storageProfile2.administrator_login administrator_login_password = "H@Sh1CoR3!" version = "11" ssl_enforcement_enabled = true } //varibale.tf variable "storageProfile2" { default = { storage_mb = 102400 backup_retention_days = 15 geo_redundant_backup_enabled = false administrator_login = "pgadmin" } type = object( { storage_mb = number backup_retention_days = number geo_redundant_backup_enabled = bool administrator_login = string } ) }
Error message