Terraform 变量 #

什么是变量? #

变量(Variable)允许你参数化 Terraform 配置,使配置更加灵活和可复用。通过变量,你可以在不修改代码的情况下改变配置行为。

text
┌─────────────────────────────────────────────────────────────┐
│                    变量的作用                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────┐     ┌─────────────┐     ┌─────────────┐   │
│  │ 环境区分     │     │ 配置复用     │     │ 敏感信息    │   │
│  └─────────────┘     └─────────────┘     └─────────────┘   │
│                                                             │
│  - dev/staging/prod 使用相同代码                           │
│  - 同一模块不同参数                                        │
│  - 密码、密钥等敏感数据                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

变量定义 #

基本语法 #

hcl
variable "<NAME>" {
  <ARGUMENT> = <VALUE>
}

变量参数 #

hcl
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t2.micro"
  nullable    = false
  sensitive   = false
  
  validation {
    condition     = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_type)
    error_message = "Instance type must be t2.micro, t2.small, or t2.medium."
  }
}

参数说明 #

text
┌─────────────────────────────────────────────────────────────┐
│                    变量参数                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  description   变量描述,用于文档                           │
│  type          变量类型                                     │
│  default       默认值                                       │
│  nullable      是否允许 null(默认 true)                   │
│  sensitive     是否敏感(默认 false)                       │
│  validation    输入验证                                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

变量类型 #

基本类型 #

hcl
variable "name" {
  type    = string
  default = "my-instance"
}

variable "count" {
  type    = number
  default = 3
}

variable "enabled" {
  type    = bool
  default = true
}

variable "any_value" {
  type    = any
  default = "can be anything"
}

列表类型 #

hcl
variable "availability_zones" {
  type    = list(string)
  default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}

variable "ports" {
  type    = list(number)
  default = [80, 443, 8080]
}

variable "mixed_list" {
  type    = list(any)
  default = ["string", 123, true]
}

映射类型 #

hcl
variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Project     = "my-project"
  }
}

variable "instance_types" {
  type = map(string)
  default = {
    dev     = "t2.micro"
    staging = "t2.small"
    prod    = "t2.medium"
  }
}

variable "config" {
  type = map(any)
  default = {
    name = "example"
    size = 10
  }
}

集合类型 #

hcl
variable "unique_ports" {
  type    = set(number)
  default = [80, 443, 8080]
}

variable "unique_names" {
  type    = set(string)
  default = ["web", "api", "db"]
}

对象类型 #

hcl
variable "server_config" {
  type = object({
    name          = string
    instance_type = string
    volume_size   = number
    tags          = map(string)
  })
  default = {
    name          = "web-server"
    instance_type = "t2.micro"
    volume_size   = 20
    tags = {
      Environment = "dev"
    }
  }
}

元组类型 #

hcl
variable "mixed_tuple" {
  type    = tuple([string, number, bool])
  default = ["hello", 42, true]
}

复杂嵌套类型 #

hcl
variable "servers" {
  type = list(object({
    name          = string
    instance_type = string
    ports         = list(number)
    tags          = map(string)
  }))
  default = [
    {
      name          = "web"
      instance_type = "t2.micro"
      ports         = [80, 443]
      tags = {
        Role = "web"
      }
    },
    {
      name          = "api"
      instance_type = "t2.small"
      ports         = [8080]
      tags = {
        Role = "api"
      }
    }
  ]
}

变量验证 #

基本验证 #

hcl
variable "instance_type" {
  type    = string
  default = "t2.micro"
  
  validation {
    condition     = can(regex("^t2\\.", var.instance_type))
    error_message = "Instance type must be t2 family."
  }
}

多条件验证 #

hcl
variable "environment" {
  type = string
  
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}

variable "port" {
  type = number
  
  validation {
    condition     = var.port > 0 && var.port <= 65535
    error_message = "Port must be between 1 and 65535."
  }
}

复杂验证 #

hcl
variable "vpc_cidr" {
  type = string
  
  validation {
    condition     = can(cidrhost(var.vpc_cidr, 0))
    error_message = "Must be a valid CIDR block."
  }
}

variable "domain_name" {
  type = string
  
  validation {
    condition     = can(regex("^[a-z0-9]+([\\-\\.][a-z0-9]+)*\\.[a-z]{2,}$", var.domain_name))
    error_message = "Must be a valid domain name."
  }
}

自定义错误消息 #

hcl
variable "instance_count" {
  type = number
  
  validation {
    condition     = var.instance_count > 0
    error_message = "Instance count must be greater than 0. Got: ${var.instance_count}"
  }
}

变量使用 #

在配置中使用 #

hcl
variable "instance_type" {
  default = "t2.micro"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type
}

在表达式中使用 #

hcl
variable "environment" {
  default = "dev"
}

variable "instance_types" {
  default = {
    dev     = "t2.micro"
    staging = "t2.small"
    prod    = "t2.medium"
  }
}

resource "aws_instance" "example" {
  instance_type = var.instance_types[var.environment]
  
  tags = {
    Name = "server-${var.environment}"
  }
}

在模块中使用 #

hcl
module "vpc" {
  source = "./modules/vpc"
  
  vpc_cidr     = var.vpc_cidr
  environment  = var.environment
  project_name = var.project_name
}

变量赋值 #

命令行赋值 #

bash
terraform apply -var="instance_type=t2.small"

terraform apply -var="instance_type=t2.small" -var="region=us-west-2"

变量文件 #

创建 terraform.tfvars

hcl
instance_type = "t2.small"
region        = "us-west-2"
environment   = "staging"

使用变量文件:

bash
terraform apply -var-file="terraform.tfvars"

terraform apply -var-file="custom.tfvars"

自动加载 #

Terraform 自动加载以下文件:

text
┌─────────────────────────────────────────────────────────────┐
│                    自动加载文件                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  terraform.tfvars          自动加载                        │
│  terraform.tfvars.json     自动加载(JSON 格式)            │
│  *.auto.tfvars             自动加载                        │
│  *.auto.tfvars.json        自动加载(JSON 格式)            │
│                                                             │
│  加载顺序:                                                 │
│  自动加载文件 -> -var-file 参数 -> -var 参数               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

环境变量 #

bash
export TF_VAR_instance_type="t2.small"
export TF_VAR_region="us-west-2"

terraform apply

交互式输入 #

如果变量没有默认值且没有提供值,Terraform 会提示输入:

bash
terraform apply

var.instance_type
  Enter a value: t2.small

禁用交互式输入:

bash
terraform apply -input=false

敏感变量 #

标记敏感变量 #

hcl
variable "db_password" {
  type      = string
  sensitive = true
}

variable "api_key" {
  type      = string
  sensitive = true
}

使用敏感变量 #

hcl
resource "aws_db_instance" "example" {
  engine          = "mysql"
  instance_class  = "db.t3.micro"
  
  username = "admin"
  password = var.db_password
}

敏感变量注意事项 #

text
┌─────────────────────────────────────────────────────────────┐
│                    敏感变量注意事项                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ✅ 日志中不会显示敏感值                                    │
│  ✅ terraform output 默认不显示                             │
│  ⚠️ 状态文件中仍会存储明文                                  │
│  ⚠️ 敏感变量用于非敏感属性时可能泄露                        │
│                                                             │
│  推荐:                                                     │
│  - 使用密钥管理服务(Vault、AWS Secrets Manager)           │
│  - 加密状态文件                                             │
│  - 使用环境变量传递敏感信息                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

可选属性 #

基本用法 #

hcl
variable "server_config" {
  type = object({
    name          = string
    instance_type = optional(string, "t2.micro")
    volume_size   = optional(number, 20)
    tags          = optional(map(string), {})
  })
}

嵌套可选 #

hcl
variable "network_config" {
  type = object({
    vpc_cidr = string
    subnets = optional(list(object({
      cidr_block = string
      name       = optional(string)
      public     = optional(bool, false)
    })), [])
  })
}

变量最佳实践 #

文件组织 #

text
project/
├── variables.tf      变量定义
├── terraform.tfvars  变量值
├── dev.tfvars        开发环境
├── staging.tfvars    预发布环境
└── prod.tfvars       生产环境

命名规范 #

hcl
variable "vpc_cidr" {
  
}

variable "instance_type" {
  
}

variable "enable_monitoring" {
  
}

variable "db_password" {
  
}

描述文档 #

hcl
variable "instance_type" {
  description = <<-EOT
    EC2 instance type for the web servers.
    Must be a valid EC2 instance type.
    Default: t2.micro
  EOT
  type        = string
  default     = "t2.micro"
}

类型定义 #

hcl
variable "tags" {
  description = "Tags to apply to all resources"
  type = map(string)
  default = {
    Environment = "dev"
    ManagedBy   = "terraform"
  }
}

验证规则 #

hcl
variable "environment" {
  description = "Deployment environment"
  type        = string
  
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be one of: dev, staging, prod."
  }
}

变量示例 #

完整示例 #

hcl
variable "environment" {
  description = "Deployment environment"
  type        = string
  
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}

variable "vpc_config" {
  description = "VPC configuration"
  type = object({
    cidr_block           = string
    enable_dns_hostnames = optional(bool, true)
    enable_dns_support   = optional(bool, true)
    public_subnets  = optional(list(object({
      cidr_block = string
      az         = string
    })), [])
    private_subnets = optional(list(object({
      cidr_block = string
      az         = string
    })), [])
  })
}

variable "instance_config" {
  description = "EC2 instance configuration"
  type = map(object({
    instance_type = string
    ami           = optional(string)
    volume_size   = optional(number, 20)
  }))
}

variable "db_password" {
  description = "Database password"
  type        = string
  sensitive   = true
}

variable "allowed_ports" {
  description = "List of allowed ports"
  type        = list(number)
  default     = [22, 80, 443]
  
  validation {
    condition     = alltrue([for port in var.allowed_ports : port > 0 && port <= 65535])
    error_message = "All ports must be between 1 and 65535."
  }
}

下一步 #

掌握了变量后,接下来学习 输出值,了解如何导出资源属性信息!

最后更新:2026-03-29