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

s3e24

Не беспокодить

Сегодня пройдем сразу две небольших темы, а следующий урок (s3e25) будет не уроком, а контрольной работой. В этой контрольной работе ты применишь все полученные знания, начиная с первого сезона.

Там то мы и поставим точку. Всех полученных знаний в этом сезоне тебе хватит с головой. Само собой использовать в работе ты будешь лишь небольшой процент, но это ничего не меняет.

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

Ethemeral Blocks

Одним словом — это одноразовые ресурс-блоки. Применяются в моменте и не попадают в state. Их удобно использовать при работе с критичными данными, например с паролями, секретами, токенами и т.п.

Возьмём такой код:

resource "random_password" "consul" {
  length = 21
  special = true
  override_special = "!@#$%^&*"
}

Ты его раньше уже видел, с помощью него мы создавали пароли. НО когда пароль создан, пароль будет храниться в state файле, в открытом виде. С одной стороны нормально, с другой стороны — ну такое себе.

Вот для этого и существует Ethemeral Blocks, его кстати недавно завезли, в старых версиях terraform этой штуки нет, так что имей в виду.

ephemeral "random_password" "consul" {
  length = 21
  special = true
  override_special = "!@#$%^&*"
}

Теперь пароль не попадёт в state Аналогично можно применять и для других ресурсов, например для переменных:

locals {
  password = ephemeral.random_password.consul
}

Мы говорим terraform - Вот тебе данные, которые нужны только во время apply, не надо сохранять их в state

Еще один пример:

variable "db_password" {
  sensitive = true
}

resource "null_resource" "example" {
  provisioner "local-exec" {
    command = "echo ${var.db_password}"
  }
}

Даже если будет sensitive = true, пароль всё равно попадет в state. А вот так уже не попадёт:

variable "db_password" {
  sensitive = true
}

ephemeral "null_resource" "example" {
  provisioner "local-exec" {
    command = "echo ${var.db_password}"
  }
}

Но не заиграйся, в таком кейсе нельзя ссылаться на него как на ресурс:

resource "aws_instance" "vm" {
  user_data = ephemeral.example.output
}

Ну и в ephemeral нельзя делать depends_on как на инфраструктуру.


Workspaces

Workspace — это отдельное состояние state для одного и того же кода terraform. Если совсем просто - Один код → несколько окружений.

Применяется в основном для тестирования. Чтобы не деплоить изменения на продакшен, можно создать специальный workspace и на нем прогнать все манифесты. При этом продакшен не пострадает.

Для того чтобы посмотреть, в каком workspace ты находишься, есть команда:

terraform workspace show

По умолчанию у тебя выведется default, так и должно быть.

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

terraform workspace show

Увидишь список всех доступных workspaces и рядом символ звездочки, он указывает на тот workspace в котором ты сейчас находишься. Опять же пока будет * default.

Ну и давай создадим workspaces:

terraform workspace new production
terraform workspace new dev

У нас будет 2 workspaces, это production и dev. Как только ты создаешь workspace, то terraform автоматически переключается на эту «ветку».

Чтобы переключаться между workspaces есть команда:

terraform workspace select production

В конце указываешь нужную «ветку», сейчас я переключаюсь на production workspaces.

Ну и есть удаление:

terraform workspace delete production

Основные методы управления рассмотрели, давай потыкаем. Сейчас я нахожусь в «ветке» production.

Возьмем болванку:

resource "openstack_compute_instance_v2" "vm1" {
  name       = "linuxfactory"
  image_name = "Ubuntu 24.04 LTS 64-bit"
  flavor_id  = "1312"
}

И выполним terraform apply, по итогу в Selectel создастся новый сервер. После этого повторно выполни terrafown apply и убедись что ничего не будет создано.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Ну а теперь переключаемся на workspace == dev:

terraform workspace select dev

Запускаем terraform apply и видим:

Plan: 2 to add, 0 to change, 0 to destroy.

Вот это ничего себе! По итогу у нас как бы создался дубликат, но наши tf файлы не изменены, всё осталось по-прежнему, единственное мы работаем в разных workspaces. Причем state примет такой вид. Он разделится на папки и в каждой папке будет отдельный state:

Если сейчас ввести YES в workspace dev, то будет создан еще один сервер. Но нет!

Наступили на грабли. Оно говорит, что проект уже существует. Так и есть, «ветка» production уже создала проект и «ветка» dev логично упала с ошибкой. Сейчас решим!

А решается просто:

resource "selectel_vpc_project_v2" "vpc" {
  name = "linuxfactory-${terraform.workspace}"
}

Добавляем системную переменную в name, которая называется ${terraform.workspace}, эта переменная сама определена terraform, что-то вроде системной переменной. Теперь если в ветке dev снова запустить terraform apply то все пройдет отлично.

Давай сейчас переключимся на production и посмотрим что произойдет:

terraform workspace select production && terraform apply

Опа, проект с production переименовался. Ну теперь точно все отлично. Получается сейчас у нас две абсолютно одинаковых инфраструктуры. Одна для тестирования, другая для продакшена.

Тут самый важный момент — не запарится и перед запуском apply убедиться, что ты находишься в нужном workspaces. Ну и не вздумай брякнуть в обществе уважаемых людей, что workspaces это для разделения инфраструктур по окружениям. Workspaces предназначен ТОЛЬКО для тестирования.

Как правильно разделять инфраструктуру на dev/stage/prod мы с тобой рассмотрели на прошлых уроках.

Вот и всё что тебе нужно знать про Ethemeral Blocks и Workspaces.


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

  • Потыкай workspaces, сложи пазл в голове.
  • Набирайся сил, впереди тебя ждет «Дипломная работа».