You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform-provider-dynamix/wiki/1.2.0/05.05-Удаление-ресурсов.md

12 KiB

Ресурсы в terraform можно как создавать, редактировать, так и удалять. При удалении ресурса, terraform провайдер производит необходимые действия на платформе, после чего очищает эти ресурсы из своего .tfstate - файла, в котором хранится состояние инфраструктуры.
В данном разделе рассмотрены различные способы удаления ресурсов, проблемы, которые могут возникнуть, их причины, а так же способы их решить.

Команда destroy

Для удаления ресурса, в terraform имеется команда

terraform destroy

По умолчанию, эта команда производит удаление всей инфраструктуры, описанной и сохраненной в .tfstate-файле.

Влияние конфигурационного параметра permanently

В некоторых ресурсах terraform провайдера имеется параметр permanently, который регулирует удаление ресурса:

  • Если флаг имеет значение - true (используется по умолчанию), то ресурс будет мгновенно удален с платформы и восстановить его будет невозможно.
  • Если флаг имеет значение - false, то ресурс будет помещен в корзину, с возможностью дальнейшего восстановления. Ресурс будет удален автоматически из корзины через 7 дней (зависит от настроек платформы).

Возможные проблемы

Так как terraform, при удалении ресурса, производит удаление .tfstate-файла, то при использовании фдага permanently = false, ресурс невозможно будет восстановить из конфигурационного файла инфраструктуры - при использовании terraform apply - будет создана новая инфраструктура. Поэтому, старую инфраструктуру необходимо импортировать, чтобы сформировать .tfstate - файл, а потом применить terraform apply - тогда ресурс будет восстановлен из корзины.

Команда destroy с флагом target

Как и было сказано выше, команда terraform destroy производит удаление всей инфраструктуры. Для того, чтобы произвести удаление определенных ресурсов, используется флаг -target. Флаг, в качестве параметра, принимает название ресурса для удаления, вида

<тип-ресурса>.<имя-ресурса>

либо

<модуль>.<имя-ресурса>

для ресурсов, содержащихся в модулях. Таким образом, общая команда выглядит так:

terraform destroy -target <тип-ресурса>.<имя-ресурса>

или

terraform destroy -target <модуль>.<имя-ресурса>

В примерах не используется модуль, поэтому, далее, в качестве примера, будет взята команда terraform destroy -target <тип-ресурса>.<имя-ресурса>

Способы передачи параметра

  1. terraform destroy -target <тип-ресурса>.<имя-ресурса>
  2. terraform destroy -target="<тип-ресурса>.<имя-ресурса>"

Пример использования target

В качестве примера возьмем пример конфигурации из прошлой статьи:

resource "dynamix_disk" "disk1" {
  account_id  = 777
  disk_name   = "disk-1"
  size_max    = 10
  gid         = 212
}

resource "dynamix_disk" "disk2" {
  account_id  = 777
  disk_name   = "disk-2"
  size_max    = 10
  gid         = 212
}
  • Чтобы удалить всю инфраструктуру, необходимо просто выполнить в терминале команду
terraform destroy
  • Чтобы удалить "disk2", можно воспользоваться командой:
terraform destroy -target dynamix_disk.disk2
  • Чтобы удалить "disk1", можно воспользоваться другим способом удаления:
terraform destroy -target="dynamix_disk.disk1"

Таким образом, определенный ресурс можно удалить с помощью флага target.

Использование флага target при работе с ресурсами, созданными с помощью мета аргументов.

При создании ресурсов с помощью мета аргументов, первые получают дополнительные символы в именах ресурсов, что может привести к некоторым проблемам при работе с такими ресурсами.

Работа с for_each

При работе с for_each, ресурс получается имя вида: <тип-ресурса>.<общее-имя-ресурса>["<название>"] Таким образом, обращение к такому ресурсу будет выглядит следующим образом:

terraform destroy -target='<тип-ресурса>.<общее-имя-ресурса>[\"<название>\"]'

или

terraform destroy -target '<тип-ресурса>.<общее-имя-ресурса>[\"<название>\"]'

Пример:
Для примера рассмотрим создание ресурса с помощью мета аргумента for_each из предыдущей статьи:

locals {
  disk_names = [
    "disk-1",
    "disk-2",
  ]
}

resource "dynamix_disk" "disks" {
  for_each   = toset(local.disk_names)
  account_id = 777
  disk_name  = each.key
  size_max   = 10
  gid        = 212
}

В результате применения команды terrafrom apply, будут созданы ресурсы с именами:

  • dynamix_disk.disks["disk-1"]
  • dynamix_disk.disks["disk-2"] Чтобы удалить определенный ресурс, можно воспользоваться одной из команд:
#для удаления disk-1
terraform destroy -target='dynamix_disk.disks[\"disk-1\"]'
#для удаления disk-2
terraform destroy -target 'dynamix_disk.disks[\"disk-2\"]'

Либо:

#для удаления всей инфраструктуры
terraform destroy

Такая запись с экранирование кавычек обуславливается работой терминальной оболочки, через которую будет производится вызов данной команды, а так же то, что terraform в качестве параметра флага ожидает строку. Так же, есть еще одно правило - в terraform в квадратных скобках указывается либо строка в двойных кавычках (в качестве имени ключа для объекта, используется для for_each), либо число - в качестве индекса для массива (используется для count)

Работа с count

При работе с count, ресурс получается имя вида: <тип-ресурса>.<общее-имя-ресурса>[<индекс>] Таким образом, обращение к такому ресурсу будет выглядит следующим образом:

terraform destroy -target="<тип-ресурса>.<общее-имя-ресурса>[<индекс>]"

или

terraform destroy -target <тип-ресурса>.<общее-имя-ресурса>[<индекс>]

Пример:
Для примера рассмотрим создание ресурса с помощью мета аргумента for_each из предыдущей статьи:

locals {
  disk_names = [
    "disk-1",
    "disk-2",
  ]
}

resource "dynamix_disk" "disks" {
  count      = length(local.disk_names)
  account_id = 777
  disk_name  = local.disk_names[count.index]
  size_max   = 10
  gid        = 212
}

В результате применения команды terrafrom apply, будут созданы ресурсы с именами:

  • dynamix_disk.disks[0]
  • dynamix_disk.disks[1] Чтобы удалить определенный ресурс, можно воспользоваться одной из команд:
#для удаления disk-1
terraform destroy -target="dynamix_disk.disks[0]"
#для удаления disk-2
terraform destroy -target dynamix_disk.disks[1]

Либо:

#для удаления всей инфраструктуры
terraform destroy

Удаление ресурса из состояния

В ходе работы, могут возникать случаи, когда состояние (state, стейт) terraform имеет ресурсы, которые были удалены с платформы. В таком случае, можно, при выполнении команд terraform plan/apply получить ошибку:

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: The resource cannot be updated because it has been destroyed
│
│   with dynamix_kvmvm.instances["pgsmonsietc03"],
│   on main.tf line 33, in resource "dynamix_kvmvm" "instances":
│   33: resource "dynamix_kvmvm" "instances" {

Либо, в ходе неверного выполнения может возникнуть подобная ошибка:

╷
│ Error: Failed to read the given file as a state or plan file
│
│ State read error: Error loading statefile: open data.dynamix_cb_vins.vins: no such file or directory
│
│ Plan read error: open data.dynamix_cb_vins.vins: no such file or directory

Для того, чтобы этого избежать, необходимо удалить отсутствующий ресурс из стейта, выполнив команду terraform state rm <res>.<name> Например, terraform state rm dynamix_kvmvm.vm1

В случае, если ресурс был создан путен работы генераторов count/for_each, работают те же правила, что и для команды terraform destroy.

Возможные проблемы

Были обнаружены проблемы при использовании oh my zsh, которые заключались в том, что не считывались данные, переданные, при экранировании строки. Рекомендация: использовать bash.

Заключение

Таким образом, terraform позволяет выполнять удаление:

  • всей инфраструктуры, хранящейся в файле .tfstate с помощью terraform destroy
  • части инфраструктуры, используя флаг target. ОБщий вид команды такой: terraform destroy -target <тип-ресурса>.<имя-ресурса>