使用 Terraform 以编程方式删除恢复服务保管库时出错

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

我有以下 Terraform 代码:

  • 创作:

    1. 存储账户
    2. 1 Azure 文件共享
    3. 1 Azure Blob 容器
    4. 1 个恢复服务库
  • 设置:

    1. Azure 文件共享的备份策略
  • 启用 Azure 文件共享和 Azure Blob 容器的备份

resource "azurerm_storage_account" "stg" {
  name                     = local.storage_name
  resource_group_name      = azurerm_resource_group.ws.name
  location                 = azurerm_resource_group.ws.location
  account_tier             = "Standard"
  account_replication_type = "GRS"
  is_hns_enabled           = true
  tags                     = local.tre_workspace_tags

  lifecycle { ignore_changes = [tags] }
}

resource "azurerm_storage_share" "shared_storage" {
  name                 = local.shared_storage_name
  storage_account_name = azurerm_storage_account.stg.name
  quota                = var.shared_storage_quota
}

resource "azurerm_storage_container" "stgcontainer" {
  name                  = local.blob_container_name
  storage_account_name  = azurerm_storage_account.stg.name
  container_access_type = "private"
}

resource "azurerm_recovery_services_vault" "recovery_services_vault" {
  name                = local.recovery_services_vault_name
  location            = azurerm_storage_account.stg.location
  resource_group_name = azurerm_storage_account.stg.resource_group_name
  sku                 = "Standard"
  tags                = local.tre_workspace_tags

  lifecycle { ignore_changes = [tags] }

  depends_on = [azurerm_storage_account.stg]
}

resource "azurerm_backup_policy_file_share" "vault_policy" {
  name                = "rsv-policy-${local.workspace_resource_name_suffix}"
  resource_group_name = azurerm_recovery_services_vault.recovery_services_vault.resource_group_name
  recovery_vault_name = azurerm_recovery_services_vault.recovery_services_vault.name

  backup {
    frequency = "Daily"
    time      = "23:00"
  }

  retention_daily {
    count = 30
  }

  retention_weekly {
    count    = 4
    weekdays = ["Saturday"]
  }

  retention_monthly {
    count    = 2
    weekdays = ["Sunday"]
    weeks    = ["Last"]
  }

  depends_on = [azurerm_recovery_services_vault.recovery_services_vault]
}

resource "azurerm_backup_container_storage_account" "shared_storage_register" {
  resource_group_name = azurerm_backup_policy_file_share.vault_policy.resource_group_name
  recovery_vault_name = azurerm_backup_policy_file_share.vault_policy.recovery_vault_name
  storage_account_id  = azurerm_storage_account.stg.id

  depends_on = [
    azurerm_backup_policy_file_share.vault_policy,
    azurerm_storage_account.stg
  ]
}

resource "azurerm_backup_protected_file_share" "shared_storage_backup" {
  resource_group_name       = azurerm_backup_container_storage_account.shared_storage_register.resource_group_name
  recovery_vault_name       = azurerm_backup_container_storage_account.shared_storage_register.recovery_vault_name
  source_storage_account_id = azurerm_backup_container_storage_account.shared_storage_register.storage_account_id
  source_file_share_name    = azurerm_storage_share.shared_storage.name
  backup_policy_id          = azurerm_backup_policy_file_share.vault_policy.id

  depends_on = [
    azurerm_backup_container_storage_account.shared_storage_register,
    azurerm_backup_policy_file_share.vault_policy
  ]
}

# This code is executed on destroy-time before removing the Recovery Service Vault.
resource "terraform_data" "disable_rsv_configurations" {
  input = {
    subscription_id     = data.azurerm_client_config.current.subscription_id
    resource_group_name = azurerm_resource_group.ws.name
    rsv_name            = local.recovery_services_vault_name
    container_name      = local.storage_name
    item_name           = local.shared_storage_name
  }
  provisioner "local-exec" {
    when       = destroy
    on_failure = continue
    command    = <<EOT
      az login --identity &&
      az backup vault backup-properties set \
        --subscription ${self.input.subscription_id} \
        --resource-group ${self.input.resource_group_name} \
        --name ${self.input.rsv_name} \
        --soft-delete-feature-state Disable \
        --hybrid-backup-security-features Disable &&
      az backup protection disable \
        --subscription ${self.input.subscription_id} \
        --resource-group ${self.input.resource_group_name} \
        --vault-name ${self.input.rsv_name} \
        --container-name ${self.input.container_name} \
        --backup-management-type AzureStorage \
        --item-name ${self.input.item_name} \
        --delete-backup-data true \
        --yes &&
      az backup container unregister \
        --resource-group ${self.input.resource_group_name} \
        --vault-name ${self.input.rsv_name} \
        --container-name ${self.input.container_name} \
        --backup-management-type AzureStorage \
        --yes
    EOT
  }

  depends_on = [azurerm_backup_container_storage_account.shared_storage_register]
}

所有资源都在毫无问题地创建。包括 terraform_data 资源。

但是,当我必须删除资源时,就会出现问题。我一直在使用

depends_on
,以便我可以强制执行特定的删除顺序。根据 Azure 文档,在删除恢复服务保管库之前,我必须:

  1. 禁用软删除
  2. 删除备份项目(Azure 文件共享是唯一的备份项目)
  3. 取消注册存储帐户(创建的存储帐户是唯一可用的)

我可以毫无问题地通过Azure Portal执行上述步骤,然后成功销毁所有内容。我在控制台中研究、发现并测试了

terraform_data
中定义的命令。这意味着如果我手动运行并销毁资源,一切都会顺利。另一方面,如果我尝试自动销毁资源,则会失败。错误信息是:

Error: deleting Azure File Share backups item StorageContainer;storage;<RESOURCE_GROUP_NAME>;<STORAGE_ACCOUNT_NAME> (Vault <RECOVERY_SERVICE_VAULT_NAME>): Location header missing or empty

有什么建议吗?这个错误来自哪里?

azure terraform
1个回答
0
投票

使用 Terraform 删除 Recovery Service Vault 之前删除依赖项

在此方法中,terraform-data用于获取或查询现有信息,但不执行操作,即 Terraform 数据源无法执行

az backup protection disable
az backup container unregister
等操作。

即使当我尝试使用它时,我也遇到了如下所述的拦截器

enter image description here

我尝试使用空资源本地执行更新配置,我们可以在销毁恢复保管库之前实现上述所有要求,例如禁用软删除、删除备份项目和取消注册存储帐户等依赖项。

我在门户中的初始设置

enter image description here

配置:

resource "azurerm_recovery_services_vault" "recovery_services_vault" {
  name                = "evksb-recovery-vault"
  location            = azurerm_storage_account.stg.location
  resource_group_name = azurerm_resource_group.ws.name
  sku                 = "Standard"
}

resource "azurerm_backup_policy_file_share" "vault_policy" {
  name                = "rsv-policy-example"
  resource_group_name = azurerm_recovery_services_vault.recovery_services_vault.resource_group_name
  recovery_vault_name = azurerm_recovery_services_vault.recovery_services_vault.name

  backup {
    frequency = "Daily"
    time      = "23:00"
  }

  retention_daily {
    count = 30
  }

  retention_weekly {
    count    = 4
    weekdays = ["Saturday"]
  }

  retention_monthly {
    count    = 2
    weekdays = ["Sunday"]
    weeks    = ["Last"]
  }
}

resource "azurerm_backup_container_storage_account" "shared_storage_register" {
  resource_group_name = azurerm_backup_policy_file_share.vault_policy.resource_group_name
  recovery_vault_name = azurerm_backup_policy_file_share.vault_policy.recovery_vault_name
  storage_account_id  = azurerm_storage_account.stg.id
}

resource "azurerm_backup_protected_file_share" "shared_storage_backup" {
  resource_group_name       = azurerm_backup_container_storage_account.shared_storage_register.resource_group_name
  recovery_vault_name       = azurerm_backup_container_storage_account.shared_storage_register.recovery_vault_name
  source_storage_account_id = azurerm_backup_container_storage_account.shared_storage_register.storage_account_id
  source_file_share_name    = azurerm_storage_share.shared_storage.name
  backup_policy_id          = azurerm_backup_policy_file_share.vault_policy.id
}

resource "null_resource" "disable_rsv_configurations" {
  provisioner "local-exec" {
    interpreter = ["pwsh", "-Command"]
    when        = destroy
    command     = <<EOT
     
      $env:AZURE_CLIENT_ID = "yourclientid";
      $env:AZURE_CLIENT_SECRET = "yourclientsecret";
      $env:AZURE_TENANT_ID = "yourtenentid";
      az login --service-principal --username $env:AZURE_CLIENT_ID --password $env:AZURE_CLIENT_SECRET --tenant $env:AZURE_TENANT_ID

     
      az backup protection disable `
        --resource-group ${self.triggers.resource_group} `
        --vault-name ${self.triggers.recovery_vault_name} `
        --container-name ${self.triggers.storage_account} `
        --backup-management-type AzureStorage `
        --item-name ${self.triggers.file_share_name} `
        --delete-backup-data true `
        --yes
      
   
      az backup container unregister `
        --resource-group ${self.triggers.resource_group} `
        --vault-name ${self.triggers.recovery_vault_name} `
        --container-name ${self.triggers.storage_account} `
        --backup-management-type AzureStorage `
        --yes
      
      Start-Sleep -Seconds 10

      
      az backup vault backup-properties set `
        --resource-group ${self.triggers.resource_group} `
        --name ${self.triggers.recovery_vault_name} `
        --soft-delete-feature-state Disable

      Start-Sleep -Seconds 10
      
      # Delete the Recovery Services Vault after backups are cleaned up
      az resource delete `
        --resource-group ${self.triggers.resource_group} `
        --name ${self.triggers.recovery_vault_name} `
        --resource-type "Microsoft.RecoveryServices/vaults"
    EOT
  }

  triggers = {
    resource_group      = azurerm_resource_group.ws.name
    recovery_vault_name = azurerm_recovery_services_vault.recovery_services_vault.name
    storage_account     = azurerm_storage_account.stg.name
    file_share_name     = azurerm_storage_share.shared_storage.name
  }

  depends_on = [
    azurerm_backup_protected_file_share.shared_storage_backup
  ]
}

部署:

enter image description here

参考:

https://learn.microsoft.com/en-us/azure/backup/

https://learn.microsoft.com/en-us/cli/azure/backup?view=azure-cli-latest

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_protected_file_share

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