Terraform 不断破坏现有资源

问题描述

我正在尝试调试我的 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 我们打算删除某些内容的方式。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...