Terraform 工作空间 #

什么是工作空间? #

工作空间(Workspace)是 Terraform 提供的一种机制,允许在同一配置目录下管理多个独立的状态文件。每个工作空间有自己独立的状态,适合管理多个环境。

text
┌─────────────────────────────────────────────────────────────┐
│                    工作空间概念                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  同一配置,多个状态:                                       │
│                                                             │
│  terraform.tfstate.d/                                      │
│  ├── dev/                                                   │
│  │   └── terraform.tfstate                                  │
│  ├── staging/                                               │
│  │   └── terraform.tfstate                                  │
│  └── prod/                                                  │
│      └── terraform.tfstate                                  │
│                                                             │
│  每个工作空间独立的状态文件                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

工作空间命令 #

列出工作空间 #

bash
terraform workspace list

输出:

text
  default
* dev
  staging
  prod

创建工作空间 #

bash
terraform workspace new dev

terraform workspace new staging

terraform workspace new prod

切换工作空间 #

bash
terraform workspace select dev

terraform workspace select staging

terraform workspace select prod

显示当前工作空间 #

bash
terraform workspace show

输出:

text
dev

删除工作空间 #

bash
terraform workspace delete dev

注意:只能删除状态为空的工作空间。

使用工作空间 #

基本使用 #

hcl
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  
  tags = {
    Name        = "example-${terraform.workspace}"
    Environment = terraform.workspace
  }
}

环境配置 #

hcl
locals {
  environment_config = {
    dev = {
      instance_type = "t2.micro"
      min_size      = 1
      max_size      = 2
    }
    staging = {
      instance_type = "t2.small"
      min_size      = 2
      max_size      = 4
    }
    prod = {
      instance_type = "t2.large"
      min_size      = 3
      max_size      = 6
    }
  }
  
  current_config = local.environment_config[terraform.workspace]
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = local.current_config.instance_type
  
  tags = {
    Environment = terraform.workspace
  }
}

条件配置 #

hcl
locals {
  is_production = terraform.workspace == "prod"
  
  enable_monitoring = local.is_production
  enable_backup     = local.is_production
  instance_count    = local.is_production ? 3 : 1
}

resource "aws_instance" "example" {
  count         = local.instance_count
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  monitoring    = local.enable_monitoring
}

命名约定 #

hcl
locals {
  name_prefix = "${var.project_name}-${terraform.workspace}"
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  
  tags = {
    Name = "${local.name_prefix}-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  
  tags = {
    Name = "${local.name_prefix}-public-subnet"
  }
}

工作空间与远程状态 #

S3 后端 #

hcl
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "my-app/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
    
    workspace_key_prefix = "environments"
  }
}

状态文件结构:

text
my-terraform-state/
├── environments/
│   ├── dev/
│   │   └── terraform.tfstate
│   ├── staging/
│   │   └── terraform.tfstate
│   └── prod/
│       └── terraform.tfstate
└── my-app/
    └── terraform.tfstate

Terraform Cloud #

hcl
terraform {
  cloud {
    organization = "my-organization"
    
    workspaces {
      name = "my-app"
    }
  }
}

工作空间 vs 目录分离 #

工作空间方式 #

text
project/
├── main.tf
├── variables.tf
├── outputs.tf
└── terraform.tfstate.d/
    ├── dev/
    ├── staging/
    └── prod/

优点:

  • 配置集中管理
  • 减少代码重复
  • 易于维护

缺点:

  • 状态文件在同一位置
  • 难以实现环境差异配置

目录分离方式 #

text
project/
├── modules/
│   └── vpc/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   └── terraform.tfstate
│   ├── staging/
│   │   ├── main.tf
│   │   └── terraform.tfstate
│   └── prod/
│       ├── main.tf
│       └── terraform.tfstate

优点:

  • 状态文件完全隔离
  • 可以有环境特定配置
  • 更好的权限控制

缺点:

  • 需要维护多个目录
  • 代码重复(可通过模块解决)

选择建议 #

text
┌─────────────────────────────────────────────────────────────┐
│                    选择指南                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  使用工作空间的场景:                                       │
│  ✅ 环境配置基本相同                                        │
│  ✅ 简单项目                                               │
│  ✅ 快速原型开发                                           │
│  ✅ 团队规模较小                                           │
│                                                             │
│  使用目录分离的场景:                                       │
│  ✅ 环境配置差异较大                                        │
│  ✅ 需要严格的权限控制                                      │
│  ✅ 大型项目                                               │
│  ✅ 需要独立的状态管理                                      │
│  ✅ 合规要求                                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

完整示例 #

多环境配置 #

hcl
locals {
  environment = terraform.workspace
  
  config = {
    dev = {
      vpc_cidr           = "10.0.0.0/16"
      availability_zones = ["us-east-1a"]
      instance_type      = "t2.micro"
      min_size           = 1
      max_size           = 2
      db_instance_class  = "db.t3.micro"
    }
    staging = {
      vpc_cidr           = "10.1.0.0/16"
      availability_zones = ["us-east-1a", "us-east-1b"]
      instance_type      = "t2.small"
      min_size           = 2
      max_size           = 4
      db_instance_class  = "db.t3.small"
    }
    prod = {
      vpc_cidr           = "10.2.0.0/16"
      availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
      instance_type      = "t2.large"
      min_size           = 3
      max_size           = 6
      db_instance_class  = "db.t3.medium"
    }
  }
  
  current = local.config[local.environment]
  
  common_tags = {
    Environment = local.environment
    Project     = var.project_name
    ManagedBy   = "terraform"
  }
}

module "vpc" {
  source = "./modules/vpc"
  
  vpc_cidr           = local.current.vpc_cidr
  availability_zones = local.current.availability_zones
  
  tags = local.common_tags
}

module "asg" {
  source = "./modules/asg"
  
  subnet_ids      = module.vpc.public_subnet_ids
  instance_type   = local.current.instance_type
  min_size        = local.current.min_size
  max_size        = local.current.max_size
  
  tags = local.common_tags
}

module "rds" {
  source = "./modules/rds"
  
  subnet_ids     = module.vpc.private_subnet_ids
  instance_class = local.current.db_instance_class
  
  tags = local.common_tags
}

工作空间管理脚本 #

bash
#!/bin/bash

WORKSPACE=$1

if [ -z "$WORKSPACE" ]; then
  echo "Usage: $0 <workspace>"
  echo "Available workspaces:"
  terraform workspace list
  exit 1
fi

terraform workspace select $WORKSPACE || terraform workspace new $WORKSPACE

terraform init
terraform plan
terraform apply

最佳实践 #

1. 使用默认工作空间 #

hcl
locals {
  workspace_name = terraform.workspace == "default" ? "dev" : terraform.workspace
}

2. 验证工作空间 #

hcl
locals {
  valid_workspaces = ["dev", "staging", "prod"]
  
  workspace_config = {
    dev     = local.dev_config
    staging = local.staging_config
    prod    = local.prod_config
  }
  
  current_config = local.workspace_config[terraform.workspace]
}

3. 使用变量文件 #

hcl
variable "environment_config" {
  type = map(object({
    instance_type = string
    min_size      = number
    max_size      = number
  }))
}
bash
terraform workspace select dev
terraform apply -var-file="dev.tfvars"

terraform workspace select prod
terraform apply -var-file="prod.tfvars"

4. CI/CD 集成 #

yaml
name: Terraform Apply

on:
  push:
    branches: [main]

jobs:
  terraform:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [dev, staging, prod]
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
      
      - name: Terraform Init
        run: terraform init
      
      - name: Select Workspace
        run: terraform workspace select ${{ matrix.environment }} || terraform workspace new ${{ matrix.environment }}
      
      - name: Terraform Apply
        run: terraform apply -auto-approve

下一步 #

掌握了工作空间后,接下来学习 AWS Provider,了解如何使用 Terraform 管理 AWS 资源!

最后更新:2026-03-29