У меня есть файл Terraform, который я хочу запретить кому-либо запускать terraform destroy
.
Обычный способ сделать это — включить блок lifecycle
, содержащий prevent_destroy = true
в один или несколько ресурсов в файле. Но я не могу этого сделать. Файл содержит только module
, которые не принимают жизненный цикл.
Я подумал о том, чтобы изменить сами модули, чтобы они содержали блок lifecycle
, который можно было бы настроить с помощью аргумента. Но и это не сработает, потому что блок принимает только буквальные значения, а не переменные.
Другой альтернативой может быть добавление в файл ничего не делающего ресурса, который будет принимать блок lifecycle
. Я думаю, не так уж важно, что это за ресурс? Любого ресурса, содержащего блок с установленным prevent_destroy
, должно быть достаточно, чтобы остановить команду уничтожения. Верно?
Итак, какой тип ресурса мне наиболее экономично использовать, чтобы ничего не делать, кроме как удерживать этот блок? В идеале тот, который не требует дополнительных затрат на поставщика облачных услуг или риска безопасности.
Поставщик — Cloud Foundry. Версия Терраформа — 1.7.5.
Я думаю, вы можете использовать здесь ресурсы «Ничего не делать».
null_resource
: Это что-то вроде пустой карточки, специально созданной для ситуаций, когда вам просто нужно заполнить пространство.
local_value
: Несмотря на то, что он предназначен для определения местных ценностей, в крайнем случае он также может выступать в качестве бездействующего ресурса.
Добавьте блок ресурсов и жизненного цикла:
В основной файл Terraform (тот, который содержит модули) добавьте выбранный ресурс и блок жизненного цикла с помощью prevent_destroy = true
:
resource "null_resource" "prevent_destroy" {
lifecycle {
prevent_destroy = true
}
}
Этот код просто определяет null_resource
с именем prevent_destroy
и сообщает Terraform избегать этого, если кто-то попытается запустить terraform destroy
.
Надеюсь это поможет!
Мне было бы любопытно увидеть пример выполнения этого с локальным значением.
Расширение Ответ Амита Ядава:
Да, terraform destroy
не удастся при использовании ресурса «Ничего не делать» с prevent_destroy = true
НО
Вы все равно можете уничтожить отдельные ресурсы без prevent_destroy = true
, используя terraform destroy -target ...
Пример:
resource "null_resource" "a" {
triggers = {
description = "This is resource A"
}
}
resource "null_resource" "b" {
triggers = {
description = "This is resource B"
}
}
resource "null_resource" "c" {
triggers = {
description = "This is resource C, that cannot be destroyed"
}
lifecycle {
prevent_destroy = true
}
}
Бегу terraform apply
:
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# null_resource.a will be created
+ resource "null_resource" "a" {
+ id = (known after apply)
+ triggers = {
+ "description" = "This is resource A"
}
}
# null_resource.b will be created
+ resource "null_resource" "b" {
+ id = (known after apply)
+ triggers = {
+ "description" = "This is resource B"
}
}
# null_resource.c will be created
+ resource "null_resource" "c" {
+ id = (known after apply)
+ triggers = {
+ "description" = "This is resource C, that cannot be destroyed"
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
null_resource.c: Creating...
null_resource.b: Creating...
null_resource.a: Creating...
null_resource.c: Creation complete after 0s [id=9037144392933681267]
null_resource.a: Creation complete after 0s [id=3131749863575336651]
null_resource.b: Creation complete after 0s [id=2968146761042792979]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Запуск terraform destroy
не удался, как и ожидалось:
Error: Instance cannot be destroyed
on main.tf line 13:
13: resource "null_resource" "c" {
Resource null_resource.c has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue
with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target option.
Но запуск terraform destroy -target null_resource.a -auto-approve
удался:
null_resource.a: Refreshing state... [id=3131749863575336651]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# null_resource.a will be destroyed
- resource "null_resource" "a" {
- id = "3131749863575336651" -> null
- triggers = {
- "description" = "This is resource A"
} -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
null_resource.a: Destroying... [id=3131749863575336651]
null_resource.a: Destruction complete after 0s
# Other log lines
Destroy complete! Resources: 1 destroyed.
Снова запускаем terraform plan
:
null_resource.c: Refreshing state... [id=9037144392933681267]
null_resource.b: Refreshing state... [id=2968146761042792979]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# null_resource.a will be created
+ resource "null_resource" "a" {
+ id = (known after apply)
+ triggers = {
+ "description" = "This is resource A"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
В некоторых случаях для указанного провайдера также существуют параметры API, которые позволяют защитить некоторые ресурсы, например, LB в AWS может иметь аргумент
enable_deletion_protection
, установленный вtrue
, что будет эквивалентом использования жизненного цикла.