如何阻止Terraform在更改密钥保管库后销毁虚拟机?

huangapple go评论54阅读模式
英文:

How do I prevent Terraform from destroying the virtual machine after changing keyvault.?

问题

The secret password of the existing KeyVault has expired and has been changed. Then my VM is destroyed and recreated. Is there any way to stop this? All codes are written in terraform.

keyvault.tf

## Keyvault Creation
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "kv" {
  name                = var.kv_name
  location            = var.location
  resource_group_name = var.system_rg
  tenant_id           = data.azurerm_client_config.current.tenant_id
  sku_name            = var.sku_name

  soft_delete_retention_days      = var.soft_delete_retention_days
  enabled_for_deployment          = var.enabled_for_deployment
  enabled_for_disk_encryption     = var.enabled_for_disk_encryption
  enabled_for_template_deployment = var.enabled_for_template_deployment
  purge_protection_enabled        = var.purge_protection_enabled
}

resource "azurerm_key_vault_access_policy" "access_policy" {
  for_each     = var.access_policy
  key_vault_id = azurerm_key_vault.kv.id

  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = each.value.object_id

  secret_permissions      = each.value.secret_permissions
  key_permissions         = each.value.key_permissions
  certificate_permissions = each.value.certificate_permissions
  storage_permissions     = each.value.storage_permissions
}

## Create Key Vault Secret
resource "azurerm_key_vault_secret" "password" {
  name         = var.kv_secret_name
  value        = var.password_value
  key_vault_id = azurerm_key_vault.kv.id
  depends_on   = [azurerm_key_vault.kv]
}

vm.tf

resource "azurerm_resource_group" "system_rg" {
  name     = "${var.system_rg}"
  location = "${var.location}"
}

data "azurerm_resource_group" "system_rg_name" {
  name = azurerm_resource_group.system_rg.name
}

data "azurerm_subnet" "network-subnet" {
  name                 = "${var.network_subnet}"
  virtual_network_name = "${var.network_vnet}"
  resource_group_name  = "${var.network_rg}"
}

data "azurerm_key_vault" "kv" {
  name = var.kv_name
  resource_group_name = var.kv_rg
}

data "azurerm_key_vault_secret" "password" {
  name = var.kv_secret_name
  key_vault_id = data.azurerm_key_vault.kv.id
}

resource "azurerm_network_interface" "nic" {
  for_each                      = "${var.vm_template}"
  name                          = "${each.value.vm_name}-${each.value.nic}"
  location                      = "${var.location}"
  resource_group_name           = data.azurerm_resource_group.system_rg_name.name
  enable_accelerated_networking = true
  ip_configuration {
    name                          = "internal"
    subnet_id                     = data.azurerm_subnet.network-subnet.id
    private_ip_address_allocation = "${var.private-ip-type}"
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  for_each = var.vm_template
  name                = each.value.vm_name
  location            = "${var.location}"
  resource_group_name = data.azurerm_resource_group.system_rg_name.name
  size = each.value.vm_type
  source_image_id     = each.value.source_image_id
  network_interface_ids = [
    azurerm_network_interface.nic[each.key].id,
  ]

  identity {
    type = "SystemAssigned"
  }
  
  os_disk {
    name                 = "${each.value.vm_name}-${each.value.os_disk}"
    caching              = "ReadWrite"
    storage_account_type = each.value.osdisk_type
    disk_size_gb         = each.value.osdisk_size
  }

  plan {
    name      = each.value.os_sku
    publisher = each.value.os_publisher
    product   = each.value.os_offer
  }

  computer_name  = each.value.hostname
  admin_username = "${var.adminid}"
  admin_password = data.azurerm_key_vault_secret.password.value  
  disable_password_authentication = false

}
英文:

The secret password of the existing KeyVault has expired and has been changed. Then my VM is destroyed and recreated. Is there any way to stop this? All codes are written in terraform.

keyvault.tf

## Keyvault Creation
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "kv" {
name                = var.kv_name
location            = var.location
resource_group_name = var.system_rg
tenant_id           = data.azurerm_client_config.current.tenant_id
sku_name            = var.sku_name
soft_delete_retention_days      = var.soft_delete_retention_days
enabled_for_deployment          = var.enabled_for_deployment
enabled_for_disk_encryption     = var.enabled_for_disk_encryption
enabled_for_template_deployment = var.enabled_for_template_deployment
purge_protection_enabled        = var.purge_protection_enabled
}
resource "azurerm_key_vault_access_policy" "access_policy" {
for_each     = var.access_policy
key_vault_id = azurerm_key_vault.kv.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = each.value.object_id
secret_permissions      = each.value.secret_permissions
key_permissions         = each.value.key_permissions
certificate_permissions = each.value.certificate_permissions
storage_permissions     = each.value.storage_permissions
}
## Create Key Vault Secret
resource "azurerm_key_vault_secret" "password" {
name         = var.kv_secret_name
value        = var.password_value
key_vault_id = azurerm_key_vault.kv.id
depends_on   = [azurerm_key_vault.kv]
}

vm.tf

resource "azurerm_resource_group" "system_rg" {
name     = "${var.system_rg}"
location = "${var.location}"
}
data "azurerm_resource_group" "system_rg_name" {
name = azurerm_resource_group.system_rg.name
}
data "azurerm_subnet" "network-subnet" {
name                 = "${var.network_subnet}"
virtual_network_name = "${var.network_vnet}"
resource_group_name  = "${var.network_rg}"
}
data "azurerm_key_vault" "kv" {
name = var.kv_name
resource_group_name = var.kv_rg
}
data "azurerm_key_vault_secret" "password" {
name = var.kv_secret_name
key_vault_id = data.azurerm_key_vault.kv.id
}
resource "azurerm_network_interface" "nic" {
for_each                      = "${var.vm_template}"
name                          = "${each.value.vm_name}-${each.value.nic}"
location                      = "${var.location}"
resource_group_name           = data.azurerm_resource_group.system_rg_name.name
enable_accelerated_networking = true
ip_configuration {
name                          = "internal"
subnet_id                     = data.azurerm_subnet.network-subnet.id
private_ip_address_allocation = "${var.private-ip-type}"
}
}
resource "azurerm_linux_virtual_machine" "vm" {
for_each = var.vm_template
name                = each.value.vm_name
location            = "${var.location}"
resource_group_name = data.azurerm_resource_group.system_rg_name.name
size = each.value.vm_type
source_image_id     = each.value.source_image_id
network_interface_ids = [
azurerm_network_interface.nic[each.key].id,
]
identity {
type = "SystemAssigned"
}
os_disk {
name                 = "${each.value.vm_name}-${each.value.os_disk}"
caching              = "ReadWrite"
storage_account_type = each.value.osdisk_type
disk_size_gb         = each.value.osdisk_size
}
plan {
name      = each.value.os_sku
publisher = each.value.os_publisher
product   = each.value.os_offer
}
computer_name  = each.value.hostname
admin_username = "${var.adminid}"
admin_password = data.azurerm_key_vault_secret.password.value  
disable_password_authentication = false
}

If I apply Terraform in this state, I'm going to destroy my Virtual Machine and recreate it as shown below.

 # azurerm_windows_virtual_machine.vm["vm1"] must be replaced
-/+ resource "azurerm_windows_virtual_machine" "vm" {
~ admin_password             = (sensitive value) # forces replacement
- encryption_at_host_enabled = false -> null
~ id                         = "/subscriptions/.../vm-testwindows" -> (known after apply)
name                       = "vm-testwindows"
+ public_ip_address          = (known after apply)
~ public_ip_addresses        = [] -> (known after apply)
- secure_boot_enabled        = false -> null
- tags                       = {} -> null
~ virtual_machine_id         = ""xxxxx-xxx-xxxxx-xxxx-xxxxxxx" " -> (known after apply)
- vtpm_enabled               = false -> null
# (18 unchanged attributes hidden)
~ identity {
- identity_ids = [] -> null
~ principal_id = "xxxxx-xxx-xxxxx-xxxx-xxxxxxx" -> (known after apply)
~ tenant_id    = "xxxxx-xxx-xxxxx-xxxx-xxxxxxx" -> (known after apply)
# (1 unchanged attribute hidden)
}
# (3 unchanged blocks hidden)
}
Plan: 3 to add, 0 to change, 3 to destroy.

The first time I applied Keyvault secret password, I only got a "change" state, but I don't know why I'm trying to recreate Virtual Machine like this when I apply it after the secret password expires.

I ask for your help.

答案1

得分: 3

通常,您会使用lifecycle元参数中的ignore_changes

resource "azurerm_linux_virtual_machine" "vm" {
#...
lifecycle {
ignore_changes = [
admin_password,
]
}
}
英文:

Usually you would use lifecycle Meta-Argument of ignore_changes:

resource "azurerm_linux_virtual_machine" "vm" {
#...
lifecycle {
ignore_changes = [
admin_password,
]
}
}

huangapple
  • 本文由 发表于 2023年4月20日 09:29:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76059912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定