Перейти к содержанию

s3e22

Птица Феникс

Иногда возникает необходимость пересоздать какой-то ресурс, то есть полностью его удалить и затем создать заново. Но твой код на это не рассчитан. Либо удаляем всё, либо ничего.

Допустим у меня крутятся в продакшене 3 сервера, которые созданы через terraform. И один из серверов по каким-то причинам встал раком и его нужно пересоздать, а 2 остальных не трогать.

В манифестах это описано так:

Чтобы провернуть эту аферу, можно сделать так:

То есть закомментировать проблемный сервер и выполнить terraform apply, сервер удалится, затем снимаешь комментарии в коде и снова запускаешь terraform apply, создается новый сервер. Это логично.

Но что если…

В таком случае оно тебе не даст ничего удалить, потому что есть зависимость через depends_on, сервер vm3 зависим от vm2. И таких зависимостей может быть масса. Не бегать же по всему коду и не искать всё это, правильно? Правильно!

Если выполнить код выше, получишь ошибку:

Чтобы пересоздать сервер vm2 без танцев с бубном, в terraform есть прекрасная команда:

terraform taint openstack_compute_instance_v2.vm2

В этом случае тебе ничего не нужно комментировать в коде и плевать на все зависимости. После запуска, ресурс vm2 будет отмечен: Resource instance openstack_compute_instance_v2.vm2 has been marked as tainted.

Ну а далее, тебе просто нужно выполнить terraform apply.

Как видишь, terraform написал — replaced. Чего мы и добивались. Хорошо, усложняем.

resource "openstack_compute_instance_v2" "vm" {
  count      = 3
  name       = "linuxfactory-${count.index+1}"
  image_name = "Ubuntu 24.04 LTS 64-bit"
  flavor_id  = openstack_compute_flavor_v2.flavors["micro_server"].id
}

Хм, сервера создаются через count, теперь мы не можем указать конкретный ресурс, который будет помечен tainted Как быть? Всё просто. У нас есть индексы.

У каждого сервера есть индекс:

openstack_compute_instance_v2.vm[0]
openstack_compute_instance_v2.vm[1]
openstack_compute_instance_v2.vm[2]

Чтобы пересоздать 2й сервер, нам нужно указать индекс [1]. Выставляем метку tainted:

terraform taint 'openstack_compute_instance_v2.vm[1]'

И наслаждаемся результатом:

Если ты накосячил, можно снять метку tainted есть обратная команда untaint:

terraform untaint 'openstack_compute_instance_v2.vm[2]' 

Вот и вся наука. А еще если у тебя есть user_data, то можешь и через нее пересоздавать сервера, как мы знаем — если user_data изменилась, то сервер будет пересоздан, но это костыль.

Новый способ

Всё что я тебе показал с taint было раньше:

Теперь в тренде:

terraform apply -replace='openstack_compute_instance_v2.vm[2]'

Домашнее задание

  • Повторяй всё что прочитал, важно это потыкать на практике и сложить картинку в голове.