创建 VM 后如何在 Azure 中更新 WinRM 证书信息,而无需替换/重新创建 VM

问题描述 投票:0回答:1

我们现有的 Azure VM 通过 Terraform 创建。 WinRM 证书已过期,现在当我们运行 Terraform 时,它想要替换虚拟机的证书。

我们可以在 Key Vault 中生成新证书,并直接在 VM 上更新证书和 WinRM 侦听器,但这些更改不会反映在 Azure 配置中,因此如果我们运行 terraform plan,Terraform 仍然希望替换 VM。

我们迄今为止发现的所有信息似乎都表明,在 Azure 中更新此信息的唯一方法是重新创建 VM,并且 Terraform 注册表文档还指出必须更换 VM。

有没有办法在不更换 VM 的情况下更新 Azure 中 VM 的 WinRM 证书/侦听器信息?我们希望能够在虚拟机上运行 Terraform,而无需更换虚拟机。由于 Terraform 从 Azure 提取信息,因此一旦证书过期,您就无法再使用 Terraform,除非您更换机器。

注意:我们的 Terraform 每次运行时都会从 Key Vault 获取最新的 WinRM 证书信息。如果 Azure VM 配置具有最新的 WinRM 证书信息,则 Terraform 会将其视为不需要更改。这就是为什么我们希望更新 Azure 中的信息。

任何有关此问题的帮助将不胜感激。

谢谢。

azure terraform certificate listener winrm
1个回答
0
投票

我通过更新 Azure 中现有 VM 的 WinRM 证书信息成功配置了要求,而没有使用生命周期模块来替换或重新创建它。

如果要更新 Azure VM 的 WinRM 证书信息而不替换 Terraform 中的 VM,您可能会遇到一些困难。当 Terraform 管理 VM 的配置并且证书存储在 Azure Key Vault 中时尤其如此。主要挑战来自 Terraform 如何管理其状态并对基础设施变化做出反应。

Terraform 跟踪其管理的资源并将其与其状态文件进行比较。如果实际基础设施和状态文件之间存在任何差异,Terraform 会尝试通过更改来修复它们。例如,如果 VM 在 Terraform 的配置中具有 WinRM 证书,并且有人在 Terraform 外部更改了证书,Terraform 将注意到此更改,并可能重新创建 VM 以匹配其状态文件。

为了避免这个问题,我们可以应用生命周期模块,它允许虚拟机忽略指定参数的变化并保持稳定,而不会根据应该排除的参数的变化重新创建或修改。

我的地形配置:

provider "azurerm" {
    features {}
}

data "azurerm_client_config" "current" {}


resource "azurerm_resource_group" "example" {
  name     = "demorg-resources"
  location = "West Europe"
}


resource "azurerm_key_vault" "example" {
  name                        = "vksbKeyVault"
  location                    = azurerm_resource_group.example.location
  resource_group_name         = azurerm_resource_group.example.name
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  sku_name                    = "standard"
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false

  network_acls {
    default_action             = "Allow"
    bypass                     = "AzureServices"
  }
}


resource "azurerm_key_vault_access_policy" "example" {
  key_vault_id = azurerm_key_vault.example.id

    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

  key_permissions = [
    "Get",
    "List",
    "Update",
    "Create",
    "Import",
    "Delete",
    "Recover",
    "Backup",
    "Restore",
    "Decrypt",
    "Encrypt",
    "UnwrapKey",
    "WrapKey",
    "Verify",
    "Sign",
    "Purge",
    "Release",
    "Rotate",
    "GetRotationPolicy",
    "SetRotationPolicy"
  ]

  secret_permissions = [
    "Get",
    "List",
    "Set",
    "Delete",
    "Recover",
    "Backup",
    "Restore",
    "Purge"
  ]

  certificate_permissions = [
    "Get",
    "List",
    "Update",
    "Create",
    "Import",
    "Delete",
    "Recover",
    "Backup",
    "Restore",
    "ManageContacts",
    "ManageIssuers",
    "GetIssuers",
    "ListIssuers",
    "SetIssuers",
    "DeleteIssuers",
    "Purge"
  ]
}



resource "azurerm_key_vault_certificate" "example" {
  name         = "WinRMvkCertificate"
  key_vault_id = azurerm_key_vault.example.id

  certificate_policy {
    issuer_parameters {
      name = "Self"
    }

    key_properties {
      exportable = true
      key_type   = "RSA"
      key_size   = 2048
      reuse_key  = true
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      subject            = "CN=example.com"
      validity_in_months = 12

      key_usage = [
        "digitalSignature",
        "keyEncipherment"
      ]
    }
  }
}


resource "azurerm_virtual_network" "example" {
  name                = "demovk-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}


resource "azurerm_subnet" "example" {
  name                 = "demovk-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}


resource "azurerm_network_interface" "example" {
  name                = "demovk-nic"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address_allocation = "Dynamic"
  }
}


resource "azurerm_windows_virtual_machine" "example" {
  name                = "demovk-vm"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  size                = "Standard_F2"
  admin_username      = "adminuser"
  admin_password      = "yourPassword123!"
  network_interface_ids = [azurerm_network_interface.example.id]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }

  computer_name  = "example-vm"
  enable_automatic_updates = true

     lifecycle {
    ignore_changes = [
      winrm_listener
    ]
  }

}

# Azure VM Extension for WinRM Configuration
resource "azurerm_virtual_machine_extension" "winrm_config" {
  name                 = "winrm-config"
  virtual_machine_id   = azurerm_windows_virtual_machine.example.id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.10"

  settings = jsonencode({
    "commandToExecute": "powershell -ExecutionPolicy Unrestricted -File configure-winrm.ps1"
  })

  # Assuming the script is uploaded to a location accessible by the VM
  protected_settings = jsonencode({
    "fileUris": ["https://demovkstor.blob.core.windows.net/democont/configure-winrm.ps1"]
  })
}


# Outputs
output "vm_id" {
  value = azurerm_windows_virtual_machine.example.id
}

要使用 Terraform 在 Azure 中的 Windows 虚拟机上配置 WinRM 侦听器,我们可以使用 Azure VM 扩展

Powershell 的扩展文件将上传到 blob 存储。

enter image description here

输出:

enter image description here

enter image description here

enter image description here

我已在 WinVMvkcertificate 中进行了必要的更改,以将证书替换为新版本,并通过重新运行 terraform 命令检查这些更改是否会导致虚拟机重新创建。

enter image description here

此处唯一的更改是更新证书信息,而不是以任何方式重新创建或修改虚拟机。

© www.soinside.com 2019 - 2024. All rights reserved.