如何将 azurerm_resource_group_template_deployment 用于 azure budget 资源但忽略开始和结束日期的更改?

How can I use azurerm_resource_group_template_deployment for azure budget resource but ignore changes in start and end date?

可能相关:

我想使用 Terraform 版本 0.37 中的资源 azurerm_resource_group_template_deployment。但问题是 Terraform 每个月都想重新申请资源,所以我想我可以告诉我忽略对开始日期和结束日期的更改,但这将(与已弃用的资源相反 azurerm_template_deployment)需要计算操作,即 jsondecode,这是不允许的。 IE。以下代码将不起作用。

terraform {
  required_version = "~> 0.13.0"
  required_providers {
    azurerm = "~> 2.37.0"
  }
}

provider azurerm {
  features {}
}

locals {
  budget_start_date = formatdate("YYYY-MM-01", timestamp())
  budget_end_date = formatdate("YYYY-MM-01", timeadd(timestamp(), "17568h"))
  budget_params = jsonencode({
    "budgetName" = "budgettest",
    "amount" = "4000",
    "timeGrain" = "Annually",
    "startDate" = local.budget_start_date,
    "endDate" = local.budget_end_date,
    "firstThreshold" = "75",
    "secondThreshold" = "100",
    "thirdThreshold" = "50",
    "contactGroups" = ""
  }) 
  }

resource "azurerm_resource_group" "rg" {
  # A subscription cannot have more than 980 resource groups:
  # https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits
  name = "example-rg"
  location = "westeurope"
}

resource "azurerm_resource_group_template_deployment" "dsw_budget" {
  name = "test-budget-template"
  resource_group_name = azurerm_resource_group.rg[0].name
  deployment_mode = "Incremental"

  template_content = file("${path.module}/arm/budget_deploy.json")

  parameters_content = local.budget_params
  
  lifecycle {
    ignore_changes = [
      jsondecode(parameters_content)["startDate"],
      jsondecode(parameters_content)["endDate"]
    ]
  }

}

为了完整起见,budget_deploy.json的内容:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "budgetName": {
      "type": "string",
      "defaultValue": "MyBudget"
    },
    "amount": {
      "type": "string",
      "defaultValue": "1000"
    },
    "timeGrain": {
      "type": "string",
      "defaultValue": "Monthly",
      "allowedValues": [
        "Monthly",
        "Quarterly",
        "Annually"
      ]
    },
    "startDate": {
      "type": "string"
    },
    "endDate": {
      "type": "string"
    },
    "firstThreshold": {
      "type": "string",
      "defaultValue": "90"
    },
    "secondThreshold": {
      "type": "string",
      "defaultValue": "110"
    },
    "thirdThreshold": {
      "type": "string",
      "defaultValue": "80"
    },
    "contactEmails": {
      "type": "string",
      "defaultValue": ""
    },
    "contactGroups": {
      "type": "string",
      "defaultValue": ""
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "variables": {
    "groups": "[split(parameters('contactGroups'),',')]"
  },
  "resources": [
    {
      "name": "[parameters('budgetName')]",
      "type": "Microsoft.Consumption/budgets",
      "location": "[parameters('location')]",
      "apiVersion": "2019-10-01",
      "properties": {
        "timePeriod": {
          "startDate": "[parameters('startDate')]",
          "endDate": "[parameters('endDate')]"
        },
        "timeGrain": "[parameters('timeGrain')]",
        "amount": "[parameters('amount')]",
        "category": "Cost",
        "notifications": {
          "NotificationForExceededBudget1": {
            "enabled": true,
            "operator": "GreaterThan",
            "threshold": "[parameters('firstThreshold')]",
            "contactGroups": "[variables('groups')]"
          },
          "NotificationForExceededBudget2": {
            "enabled": true,
            "operator": "GreaterThan",
            "threshold": "[parameters('secondThreshold')]",
            "contactGroups": "[variables('groups')]"
          },
          "NotificationForExceededBudget3": {
            "enabled": true,
            "operator": "GreaterThan",
            "threshold": "[parameters('thirdThreshold')]",
            "contactGroups": "[variables('groups')]"
          }
        }
      }
    }
  ]
}

还有什么方法可以实现我的目标吗? - 谢谢!

我认为您使用 ignore_changes 的方式不对。查看每个资源的 lifecycle 中的 ignore_changes。它应该是您要创建的资源的 属性,而不是值。另外,如果你想通过Terraform中的Azure模板更改资源,最好使用Incremental deployment_mode,不要更改你想忽略更改的属性 .

我求助于为预算的结束和开始日期使用标签。 ignore_changes 将适用于 deprecated azurerm_template_deployment 因为在这种情况下参数是 map 类型而不是 json 类型,比如所以:

terraform {
  required_version = "~> 0.13.0"
  required_providers {
    azurerm = "~> 2.37.0"
  }
}

provider azurerm {
  features {}
}

locals {
  budget_start_date = formatdate("YYYY-MM-01", timestamp())
  budget_end_date = formatdate("YYYY-MM-01", timeadd(timestamp(), "17568h"))
  budget_params = {
    "budgetName" = "budgettest",
    "amount" = "4000",
    "timeGrain" = "Annually",
    "startDate" = local.budget_start_date,
    "endDate" = local.budget_end_date,
    "firstThreshold" = "75",
    "secondThreshold" = "100",
    "thirdThreshold" = "50",
    "contactGroups" = ""
  }
  }

resource "azurerm_resource_group" "rg" {
  # A subscription cannot have more than 980 resource groups:
  # https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits
  name = "example-rg"
  location = "westeurope"
}

resource "azurerm_template_deployment" "dsw_budget" {
  name = "test-budget-template"
  resource_group_name = azurerm_resource_group.rg[0].name
  deployment_mode = "Incremental"

  template_content = file("${path.module}/arm/budget_deploy.json")

  parameters_content = local.budget_params
  
  lifecycle {
    ignore_changes = [
      parameters["startDate"],
      parameters["endDate"]
    ]
  }

}

现在 azurerm_resource_group_template_deployment 不再可能了,因为必须传递 json 内容,因此在 ignore_changes 中有一个 json 解码,这是一个计算操作必须做,这是不允许的。

因此,为了解决固定开始日期和结束日期的问题,我使用了开始日期和结束日期的标签以及查询它们的数据源:

terraform {
  required_version = "~> 0.13.0"
  required_providers {
    azurerm = "~> 2.37.0"
  }
}

provider azurerm {
  features {
    template_deployment {
      delete_nested_items_during_deletion = false
    }
  }
}

data "azurerm_resources" "aml" {
  resource_group_name = "${var.tk_name_id}-${local.stage}-rg"
  type = "Microsoft.MachineLearningServices/workspaces"
}


locals {
  budget_start_date_tag = try(element(data.azurerm_resources.aml.resources[*].tags.budget_start_date, 0), "NA")
  budget_end_date_tag = try(element(data.azurerm_resources.aml.resources[*].tags.budget_end_date, 0), "NA")
  should_test_budget = local.is_test_stage_boolean && var.test_budget
  budget_start_date = local.budget_start_date_tag != "NA" ? local.budget_start_date_tag : (local.should_test_budget ? "START DATE FAIL!" : formatdate("YYYY-MM-01", timestamp()))
  budget_end_date = local.budget_end_date_tag != "NA" ? local.budget_end_date_tag : (local.should_test_budget ? "END DATE FAIL!" : formatdate("YYYY-MM-01", timeadd(timestamp(), "17568h")))
  budget_date_tags = {
     "budget_start_date" : local.budget_start_date,
     "budget_end_date" : local.budget_end_date
  }
}

#--------------------------------------------------------------------------------------------------------------------
# DSW: Resource Group 
# --------------------------------------------------------------------------------------------------------------------
resource "azurerm_resource_group" "rg" {
  # A subscription cannot have more than 980 resource groups:
  # https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits
  count = local.no_addresses_available_boolean ? 0 : 1
  name = "test-rg"
  location = var.location
  tags = local.budget_date_tags
}

resource "azurerm_machine_learning_workspace" "aml_workspace" {
  name = local.aml_ws_name
  resource_group_name = azurerm_resource_group.rg[0].name
  location = azurerm_resource_group.rg[0].location
  application_insights_id = azurerm_application_insights.aml_insights.id
  key_vault_id = azurerm_key_vault.aml_kv.id
  storage_account_id = azurerm_storage_account.aml_st.id
  container_registry_id = azurerm_container_registry.aml_acr.id
  sku_name = "Basic"
  tags = merge(var.azure_tags, local.budget_date_tags)
  identity {
    type = "SystemAssigned"
  }
}

@Charles Xu 我还没有完全测试过,我也不确定这是不是最好的解决方案?

编辑:现在我实际上 运行 进入了循环依赖,因为在创建资源组之前数​​据源显然不存在:https://github.com/hashicorp/terraform/issues/16380.