Terraform 不断破坏现有资源

Terraform keeps destroying existing resource

我正在尝试调试为什么我的 Terraform 脚本不起作用。由于未知原因 Terraform 不断破坏我的 MySQL 数据库并在之后重新创建它。

下面是执行计划的输出:

  # azurerm_mysql_server.test01 will be destroyed
  - resource "azurerm_mysql_server" "test01" {
      - administrator_login               = "me" -> null
      - auto_grow_enabled                 = true -> null
      - backup_retention_days             = 7 -> null
      - create_mode                       = "Default" -> null
      - fqdn                              = "db-test01.mysql.database.azure.com" -> null
      - geo_redundant_backup_enabled      = false -> null
      - id                                = "/subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/production-rg/providers/Microsoft.DBforMySQL/servers/db-test01" -> null
      - infrastructure_encryption_enabled = false -> null
      - location                          = "westeurope" -> null
      - name                              = "db-test01" -> null
      - public_network_access_enabled     = true -> null
      - resource_group_name               = "production-rg" -> null
      - sku_name                          = "B_Gen5_1" -> null
      - ssl_enforcement                   = "Disabled" -> null
      - ssl_enforcement_enabled           = false -> null
      - ssl_minimal_tls_version_enforced  = "TLSEnforcementDisabled" -> null
      - storage_mb                        = 51200 -> null
      - tags                              = {} -> null
      - version                           = "8.0" -> null

      - storage_profile {
          - auto_grow             = "Enabled" -> null
          - backup_retention_days = 7 -> null
          - geo_redundant_backup  = "Disabled" -> null
          - storage_mb            = 51200 -> null
        }

      - timeouts {}
    }

  # module.databases.module.test.azurerm_mysql_server.test01 will be created
  + resource "azurerm_mysql_server" "test01" {
      + administrator_login               = "me"
      + administrator_login_password      = (sensitive value)
      + auto_grow_enabled                 = true
      + backup_retention_days             = 7
      + create_mode                       = "Default"
      + fqdn                              = (known after apply)
      + geo_redundant_backup_enabled      = false
      + id                                = (known after apply)
      + infrastructure_encryption_enabled = false
      + location                          = "westeurope"
      + name                              = "db-test01"
      + public_network_access_enabled     = true
      + resource_group_name               = "production-rg"
      + sku_name                          = "B_Gen5_1"
      + ssl_enforcement                   = (known after apply)
      + ssl_enforcement_enabled           = false
      + ssl_minimal_tls_version_enforced  = "TLSEnforcementDisabled"
      + storage_mb                        = 51200
      + version                           = "8.0"

      + storage_profile {
          + auto_grow             = (known after apply)
          + backup_retention_days = (known after apply)
          + geo_redundant_backup  = (known after apply)
          + storage_mb            = (known after apply)
        }
    }

据我所知完全一样。为了防止这种情况,我还手动 terraform import 将状态与远程状态同步。

我的main.tf

中定义的实际资源
resource "azurerm_mysql_server" "test01" {
  name                = "db-test01"
  location            = "West Europe"
  resource_group_name = var.rg

  administrator_login          = "me"
  administrator_login_password = var.root_password

  sku_name   = "B_Gen5_1"
  storage_mb = 51200
  version    = "8.0"

  auto_grow_enabled                 = true
  backup_retention_days             = 7
  geo_redundant_backup_enabled      = false
  infrastructure_encryption_enabled = false
  public_network_access_enabled     = true
  ssl_enforcement_enabled           = false
}

另一个奇怪的事情是下面的命令会输出所有实际上是同步的?

➜  terraform git:(develop) ✗ terraform plan --refresh-only
azurerm_mysql_server.test01: Refreshing state... [id=/subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/firstklas-production-rg/providers/Microsoft.DBforMySQL/servers/db-test01]

No changes. Your infrastructure still matches the configuration.

在实际导入后,即使导入状态全部处于状态,同样的情况仍然会发生:

➜  terraform git:(develop) ✗ terraform import azurerm_mysql_server.test01 /subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/production-rg/providers/Microsoft.DBforMySQL/servers/db-test01
azurerm_mysql_server.test01: Importing from ID "/subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/production-rg/providers/Microsoft.DBforMySQL/servers/db-test01"...
azurerm_mysql_server.test01: Import prepared!
  Prepared azurerm_mysql_server for import
azurerm_mysql_server.test01: Refreshing state... [id=/subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/production-rg/providers/Microsoft.DBforMySQL/servers/db-test01]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

我能做些什么来防止这种破坏?或者甚至弄清楚为什么实际销毁会被触发?此时在多个 Azure 实例上都发生了这种情况。

注意:订阅 ID 是假冒的,所以不要担心

最好的, 皮姆

您的计划输出显示 Terraform 正在查看两个不同的资源地址:

  # azurerm_mysql_server.test01 will be destroyed
  # module.databases.module.test.azurerm_mysql_server.test01 will be created

注意要创建的是在嵌套模块中,而不是在根模块中。

如果您打算将此对象导入上面显示的需要创建的地址,则需要在 terraform import 命令中指定此完整地址:

terraform import 'module.databases.module.test.azurerm_mysql_server.test01' /subscriptions/8012-4035-b8f3-860f8cb1119e/resourceGroups/production-rg/providers/Microsoft.DBforMySQL/servers/db-test01

terraform import 命令告诉 Terraform 将现有的远程对象绑定到特定的 Terraform 地址,因此当您使用它时,您需要小心指定要绑定到的正确 Terraform 地址。

在你的例子中,你告诉 Terraform 将对象绑定到根模块中的一个假设的 resource "azurerm_mysql_server" "test01" 块,但是你的配置没有这样的块,所以当你 运行 terraform plan Terraform 假定您想要删除该对象,因为删除 resource 块是我们通常告诉 Terraform 我们打算删除某些内容的方式。