Короткий ответ
Workspaces дают один и тот же код конфигурации с разными state-файлами, переключаемыми командой terraform workspace select, что удобно для небольших различий (например, разный count/var.environment), но плохо подходит, когда окружения должны отличаться структурно (разные ресурсы, разные провайдеры, разный доступ), — для таких случаев лучше отдельные директории (или отдельные корневые модули) с явно разным backend key на каждое окружение.
Как это работает подробнее
workspace — это просто именованный префикс для state внутри одного backend (например, отдельный файл или путь в S3 на каждый workspace), конфигурация .tf-файлов остаётся общей, а различия между окружениями выражаются через terraform.workspace в выражениях или через переменные, подставляемые отдельно для каждого workspace.
Пример кода
$ terraform workspace new staging
$ terraform workspace select staging
$ terraform apply -var-file=staging.tfvars
resource "aws_s3_bucket" "logs" {
bucket = "acme-logs-${terraform.workspace}"
}Что использовать на практике
- Практика. workspaces хорошо работают, когда окружения действительно похожи (например, несколько feature-веток одного и того же набора ресурсов для review), но для prod/staging/dev с разным уровнем доступа и разными политиками безопасности рекомендуют отдельные корневые конфигурации с общими модулями, чтобы можно было применять разные права IAM, разные approval-процессы и избегать ситуации, когда разработчик по ошибке применяет prod-конфигурацию, забыв переключить workspace.
Подводные камни
- Ошибка. частая ошибка — положиться только на
terraform workspace select prodкак единственную защиту от применения кода к прод-окружению, без отдельного backend/разных учётных данных, из-за чего забытыйworkspace selectприводит к применению тестовых изменений к production state; ещё одна ошибка — использоватьterraform.workspaceв именах ресурсов без проверки, что это не приводит к превышению лимитов на длину имён у облачного провайдера.