← Все руководства
Мультиокружения с Terraform workspaces
Workspace позволяет хранить один набор конфигураций и управлять несколькими окружениями (dev, staging, prod) из одного каталога. Каждый workspace хранит собственный state.
Шаг 1: Структура каталогов
terraform/
├── environments/
│ ├── dev.tfvars
│ ├── staging.tfvars
│ └── prod.tfvars
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── ec2/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── main.tf
├── variables.tf
├── outputs.tf
└── backend.tf
Шаг 2: Основная конфигурация
# main.tf
provider "aws" {
region = var.aws_region
}
module "vpc" {
source = "./modules/vpc"
cidr_block = var.vpc_cidr
environment = terraform.workspace
}
module "ec2" {
source = "./modules/ec2"
instance_type = var.instance_type
subnet_id = module.vpc.subnet_id
environment = terraform.workspace
}
Шаг 3: Переменные и tfvars
# variables.tf
variable "aws_region" {
type = string
default = "eu-central-1"
}
variable "vpc_cidr" {
type = string
}
variable "instance_type" {
type = string
}
variable "environment" {
type = string
}
# environments/dev.tfvars
vpc_cidr = "10.0.1.0/24"
instance_type = "t3.micro"
aws_region = "eu-central-1"
# environments/prod.tfvars
vpc_cidr = "10.0.0.0/16"
instance_type = "m5.large"
aws_region = "eu-central-1"
Шаг 4: Работа с workspace
Создайте и переключайтесь между workspace:
# Просмотр текущего workspace
terraform workspace list
# Создание нового workspace
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# Переключение
terraform workspace select dev
# Удаление (нельзя удалить текущий)
terraform workspace select staging
terraform workspace delete dev
Шаг 5: Plan и Apply для каждого окружения
# Dev
terraform workspace select dev
terraform plan -var-file="environments/dev.tfvars"
terraform apply -var-file="environments/dev.tfvars"
# Prod
terraform workspace select prod
terraform plan -var-file="environments/prod.tfvars"
terraform apply -var-file="environments/prod.tfvars"
Для удобства создайте скрипт:
#!/bin/bash
# deploy.sh
set -euo pipefail
ENV=${1:?Usage: ./deploy.sh [dev|staging|prod]}
ACTION=${2:-plan}
if [ "$ENV" = "prod" ] && [ "$ACTION" = "apply" ]; then
echo "Applying to PROD - confirm? [y/N]"
read -r confirm
[ "$confirm" = "y" ] || exit 1
fi
terraform workspace select "$ENV"
terraform plan -var-file="environments/${ENV}.tfvars" -out=tfplan
if [ "$ACTION" = "apply" ]; then
terraform apply tfplan
fi
Шаг 6: Backend для state
Для команды используйте S3-backend с разными путями:
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "terraform.tfstate"
region = "eu-central-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Workspace хранит каждый state отдельно в одном S3-ключе. Ключ формируется как: env:/dev/terraform.tfstate.
Шаг 7: CI/CD для plan/apply
Пример GitLab CI:
stages:
- plan
- apply
.terraform:
image: hashicorp/terraform:1.7
before_script:
- terraform init
plan:
extends: .terraform
stage: plan
script:
- terraform workspace select $CI_ENVIRONMENT_NAME || terraform workspace new $CI_ENVIRONMENT_NAME
- terraform plan -var-file="environments/${CI_ENVIRONMENT_NAME}.tfvars" -out=tfplan
artifacts:
paths:
- tfplan
apply:
extends: .terraform
stage: apply
script:
- terraform apply -auto-approve tfplan
dependencies:
- plan
when: manual
only:
- main
Шаг 8: Вывод workspace в outputs
Полезно видеть текущий workspace:
# outputs.tf
output "current_workspace" {
value = terraform.workspace
}
output "instance_ip" {
value = module.ec2.public_ip
}
# Просмотр текущего workspace
terraform output current_workspace
Для простых проектов workspace — хороший выбор. Для сложных инфраструктур лучше использовать отдельные каталоги с общими модулями или Terragrunt.