Что такое workspace
Workspace, это именованный slot, в котором живёт отдельный state-файл. Один и тот же HCL-конфиг с двумя workspace'ами создаёт две независимые инфраструктуры, по одной на workspace.
В каждый момент времени активен ровно один workspace. Команды
plan, apply, destroy работают только в нём.
По умолчанию у проекта всегда есть workspace с именем default. Его
нельзя удалить.
Команды:
terraform workspace list # перечислить
terraform workspace new staging # создать
terraform workspace select staging # переключиться
terraform workspace show # показать текущий
terraform workspace delete staging # удалить (после переключения на другой)
Где лежат state-файлы
С локальным backend (см. tf-init-backends) state каждого
workspace хранится в подкаталоге terraform.tfstate.d/:
myproject/
├── main.tf
├── terraform.tfstate # default workspace
└── terraform.tfstate.d/
├── staging/
│ └── terraform.tfstate
└── prod/
└── terraform.tfstate
С remote backend (S3, GCS, Terraform Cloud) workspace становится
префиксом ключа: env:/staging/myproject и т.п.
Как использовать имя workspace в HCL
Доступно через terraform.workspace:
resource "aws_s3_bucket" "logs" { bucket = "logs-${terraform.workspace}-acme"▸"logs-default-acme", "logs-staging-acme", ...
}
Это удобно для нейминга, но и опасно: одна и та же конфигурация
может в разных workspace создать разное число ресурсов через
count = terraform.workspace == "prod" ? 3 : 1. Без чёткой
дисциплины через два месяца никто не помнит, чем prod-workspace
отличается от staging-workspace.
Когда workspace оправдан
- Очень похожие копии одного и того же. Пер-PR review-окружения, тестовые ephemeral-стенды.
- Когда инфра реально идентична и единственное различие, имена ресурсов.
- Когда команда понимает, что workspace: just one state per config, а не «изолированный аккаунт».
Когда workspace, анти-паттерн
- Prod / staging / dev. Эти окружения обычно отличаются
параметрами (размеры инстансов, нагрузка), кредами, политиками
доступа. В одном HCL легко выстрелить себе в ногу: ошибся в
переменной
terraform.workspace == "prod", и в prod уехало то, что предназначалось dev. Лучшее решение, отдельная директория под каждое окружение со своим backend и своим state. - Когда нужны разные права доступа к state. Workspace в одном backend == один и тот же набор кредов на доступ к state. Изолировать кто может читать prod-state, а кто, staging, нельзя.
- Изоляция blast radius. Один кривой apply в workspace
prodпри включённом backend без блокировки может покалечить и сам state, и соседние workspace.
Это причина, по которой курс использует обычные директории, а не workspace. Workspace, рабочий инструмент в нишевых сценариях.
Workspace и backend remote/local
- Local backend: workspace меняет подпапку в
terraform.tfstate.d/. Всё локально. - S3 backend: workspace становится префиксом ключа.
- Terraform Cloud: workspace, это first-class сущность с своим UI, RBAC, run history. Тут он действительно даёт изоляцию.
То есть «workspace» в TF Cloud и «workspace» в локальном CLI, два разных понятия с общим именем. Это путает многих.
Подводные камни
- Default удалить нельзя. Если хочется чистоты, заведи новый workspace и работай в нём, default останется пустым.
workspace deleteне удаляет ресурсы. Только state. Если в workspace что-то развёрнуто, сначалаdestroy, потомdelete, иначе останутся сиротские ресурсы в облаке.terraform.workspaceдоступен внутри HCL только после select. При обращении через UI терраформ-облака может быть nuance, workspace задаётся не CLI, а контекстом запуска.- Имена окружений не зашиваются в код. В HCL почти никогда
нельзя писать
if terraform.workspace == "prod". Лучше через переменнуюenvironment = "prod"и обычные условные выражения.