3

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

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

错误信息

在此处输入图像描述

4

2 回答 2

2

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

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

terraform.tfvars:

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

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

原始答案

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

从 v2.7.0 或 v2.10.0 开始, geo_redundant_backup是一个已弃用的属性,具体取决于您使用的数据库资源。您应该改用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_enforcementto ssl_enforcement_enabledgeo_redundant_backuptobackup_geo_redundant_enabledauto_growto auto_grow_enabled( #6459 )

由于azurerm 提供程序 v2.10.0于 2020 年 5 月 12 日发布,额外的storage_profile已扁平化:

  • azurerm_mariadb_server -storage_profile块中的所有属性都已移至顶层 ( #6865 )
  • azurerm_mysql_server -storage_profile块中的所有属性都已移至顶层 ( #6833 )
  • azurerm_mariadb_server - 以下属性已重命名并更改为布尔类型:ssl_enforcementto ssl_enforcement_enabledgeo_redundant_backuptogeo_redundant_backup_enabledauto_grow azurerm_mysql_server- 支持create_mode允许创建副本、时间点恢复和地理恢复的属性 ( #6833 )
  • azurerm_mysql_server - 以下属性已重命名并更改为布尔类型:ssl_enforcementto ssl_enforcement_enabledgeo_redundant_backuptogeo_redundant_backup_enabledauto_growto 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 代码在全球范围内越一致,如果我们需要处理其他人的代码,对我们所有从业者来说就越容易。

于 2020-06-19T10:09:51.317 回答
0

正如马丁所指出的那样。问题是关于 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 有很多输入

于 2020-06-25T10:48:33.013 回答