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