NPV-AM

← Все руководства

Мультиокружения с Terraform workspaces

16 июля 2026 · 10 мин чтения · Средний

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.