Может быть связано: azurerm_resource_group_template_deployment игнорирует файл параметров
Я хотел бы использовать ресурс azurerm_resource_group_template_deployment
из Terraform версии 0.37. Но есть проблема, заключающаяся в том, что Terraform хочет повторно применять ресурс каждый месяц, поэтому я подумал, что могу сказать игнорировать изменения даты начала и окончания, но для этого (в отличие от устаревшего ресурса azurerm_template_deployment
) потребуется вычислительная операция, а именно jsondecode
, что не разрешено. т.е. следующий код не будет работать.
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://learn.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
. Взгляните на жизненный цикл ignore_changes
в для каждого ресурса. Это должно быть свойство ресурса, который вы хотите создать, а не значение. Кроме того, если вы хотите изменить ресурсы через шаблон Azure в Terraform, лучше использовать Incremental
deployment_mode
, а не изменять свойство, которое вы хотите игнорировать изменения.
@mgross В ссылке, которую я указал в ответе, есть пример тегов в ignore_changes.
@mgross Есть новости по этому вопросу? Это решает вашу проблему?
Я не уверен, что у нас возникло недопонимание: я просто хочу, чтобы дата начала и окончания не менялись для существующей группы ресурсов, пока она не будет прекращена. Вот почему я разместил ответ ниже о том, как я думаю, что решу это.
@mgross Как это работает, пока не объявлено устаревшим в azurerm_template_deployment
? Даты начала и окончания являются тегами для группы?
Нет, я могу использовать ignore_changes = [parameters["startDate"], parameters["endDate"] ], потому что параметры не обязательно должны быть закодированы в json.
@mgross Для свойств группы нет даты начала и окончания. Это должен быть тег для группы.
@mgross Я думаю, что раньше вы использовали игнорирование параметров в шаблоне, но если вы не хотите изменять теги существующей группы, вам нужно сделать это так, как я сказал.
Я прибегал к использованию тегов для даты окончания и начала бюджета. ignore_changes
будет работать для устаревшего 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://learn.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://learn.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.
@Charles Xu Это решение работает сейчас. Я понял, что не могу использовать ни теги бюджета, ни теги группы ресурсов. Поэтому я также открыл: github.com/terraform-providers/terraform-provider-azurerm/…. Поэтому мне пришлось выбрать другой ресурс, то есть рабочую область машинного обучения Azure. Использование тегов бюджета позволяет мне зафиксировать дату начала и окончания бюджета, как только они будут установлены.
Да, вы правы, к сожалению, я сделал ошибку копирования-вставки. Теперь все должно быть в порядке. Тем не менее, теперь я думаю, что лучший способ, вероятно, сохранить тег даты начала и даты окончания в Azure и использовать источник данных, чтобы увидеть, установлен ли тег уже или нет. Если он установлен, всегда используйте это значение. Или в terraform есть возможность не изменять значение переменной после ее установки? Вероятно, это противоречит принципам переменных, но в данном случае это было бы полезно...