【问题标题】:terraform map and object variables as inputterraform 地图和对象变量作为输入
【发布时间】:2020-10-09 10:31:03
【问题描述】:

地图/对象变量内的任何字符串属性的命令行输入都存在问题。 以下配置适用于以下命令。但是当我在对象变量中使用任何字符串属性时。失败了

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
   }
      )
} 

以下配置不起作用。我刚刚将 administrator_login 作为字符串属性添加到对象变量中。 terraform plan 和 apply 使用默认值。

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 
   }
      )
}

错误信息

【问题讨论】:

  • 请分享您在失败时收到的错误消息。
  • 您在这里分享的内容并不是 100% 清楚,但这似乎是一个 shell 转义问题:我认为当 Terraform 看到您的论点时,shell 已经删除了所有引号 " 等等语法不再有效。它适用于您的第一种情况,因为巧合的是,在属性名称上省略引号是有效的,但普通表达式中未加引号的标识符被理解为引用,并且变量值中不允许引用。
  • 您在此处使用的引用应该适用于 Unix 样式的 shell,但如果您使用的是非 Unix 样式的 shell,例如 Windows 命令提示符或 PowerShell,它将无法正常工作。
  • @MartinAtkins。你说的对。它在转义双引号后起作用。我正在为此失去理智。谢谢。

标签: terraform terraform0.12+


【解决方案1】:

由于第二个配置使用变量的默认值,因此配置不是问题,terraform apply -var 一定是问题。正确处理是一件非常棘手的事情,并且与 shell 解析规则的交互存在许多问题,可能会让您大吃一惊。

我发现使用 .tfvars files 更加可靠,我不再尝试让 -var 为我的 Terraform 工作工作。

terraform.tfvars:

storageProfile2 = {
  storage_mb                      = 102400
  backup_retention_days           = 15
  geo_redundant_backup_enabled    = false
  administrator_login             = "pgadmin1223"
}

在同一个目录中创建 terraform.tfvars,然后在没有 -var 的情况下运行 terraform plan 和 terraform apply。它应该可以解决您的问题。

原答案

azurerm 提供程序中有几个旨在向后兼容的重大更改,但很可能会导致此处出现问题。

geo_redundant_backup 是从 v2.7.0 或 v2.10.0 开始弃用的属性,具体取决于您使用的数据库资源。您应该改用 geo_redundant_backup_enabled 并将其指定为布尔值(bool 类型)。我怀疑向后兼容性并不完全可靠。

storage_profile 块也已弃用,它们的所有属性现在都是相应的顶级属性。

azurerm 提供程序文档中使用 storage_profile 的示例不正确,并且:

storage_profile {
  storage_mb            = var.storageProfile2.storageMb
  backup_retention_days = var.storageProfile2.backupRetentionDays
  geo_redundant_backup  = var.storageProfile2.geoRedundantBackup
}

应该重写为(资源上的直接属性,而不是块内):

storage_mb                    = var.storageProfile2.storageMb
backup_retention_days         = var.storageProfile2.backupRetentionDays
geo_redundant_backup_enabled  = var.storageProfile2.geoRedundantBackup

您的 storageProfile2 变量声明应更新以将 geoRedundantBackup 的类型设置为 bool:

variable storageProfile2 {
  default = {
    storageMb = 102400
    backupRetentionDays = 15
    geoRedundantBackup  = false
  }
  type = object({ storageMb=number, backupRetentionDays=number, geoRedundantBackup=bool })
}

自 azurerm provider v2.7.0 于 2020 年 4 月 23 日发布以来,包括以下更改:

  • azurerm_postgres_server - storage_profile 块中的所有属性都已移至顶层 (#6459)
  • azurerm_postgres_server - 以下属性已重命名并更改为布尔类型:ssl_enforcement 到 ssl_enforcement_enabled、geo_redundant_backup 到 backup_geo_redundant_enabled 和 auto_grow 到 auto_grow_enabled (#6459)

自从 azurerm provider v2.10.0 于 2020 年 5 月 12 日发布以来,其他 storage_profile 已扁平化:

  • azurerm_mariadb_server - storage_profile 块中的所有属性都已移至顶层 (#6865)
  • azurerm_mysql_server - storage_profile 块中的所有属性都已移至顶层 (#6833)
  • azurerm_mariadb_server - 以下属性已重命名并更改为布尔类型:ssl_enforcement 到 ssl_enforcement_enabled、geo_redundant_backup 到 geo_redundant_backup_enabled 和 auto_grow azurerm_mysql_server - 支持 create_mode 属性,允许创建副本、时间点恢复和地理恢复 (#6833)
  • azurerm_mysql_server - 以下属性已重命名并更改为布尔类型:ssl_enforcement 到 ssl_enforcement_enabled、geo_redundant_backup 到 geo_redundant_backup_enabled 和 auto_grow 到 auto_grow_enabled (#6833)

旁白:代码风格

Terraform 中的常规代码样式:

  • 使用snake_case 而不是camelCase(未正式化,但每个提供者都遵循这一点,就像示例一样)
  • 引用资源和变量名称等顶级名称
  • 在组中对齐等号(它们之间没有多个换行符)
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
    }
  )
}

并按如下方式分配属性

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

Terraform 代码在全球范围内越一致,如果我们需要处理其他人的代码,我们所有从业者就越容易。

【讨论】:

  • 谢谢阿兰。我已经编辑了我的问题。我考虑了你的建议。我认为问题仍然在于输入参数。请检查已编辑的问题。
  • @karas27 我去看看。谢谢。
【解决方案2】:

正如马丁所指出的。问题是关于 power shell 上的 unix 样式 shell。 转义双引号后,它起作用了。 power shell 的正确语法是

terraform plan -var='postgress={"storage_mb":102400,"backup_retention_days":15,"geo_redundant_backup_enabled":false,"administrator_login":\"pgadmin1223\"}'

另外,我同意最好使用 tfvars 而不是输入参数,特别是如果您对 terraforms 有大量输入

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 2019-11-19
    • 1970-01-01
    • 2020-07-10
    • 2020-12-08
    • 2021-11-11
    • 2017-05-26
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多