Terraform 表达式与条件 #
表达式概述 #
表达式是 Terraform 配置中用于计算值的核心语法。它可以引用变量、资源属性、函数调用等,是构建动态配置的基础。
text
┌─────────────────────────────────────────────────────────────┐
│ 表达式类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 字面量 字符串、数字、布尔值 │
│ 引用 变量、资源属性、模块输出 │
│ 运算符 算术、比较、逻辑 │
│ 条件 三元条件表达式 │
│ for 循环转换 │
│ splat 展开表达式 │
│ 动态块 动态生成配置块 │
│ │
└─────────────────────────────────────────────────────────────┘
条件表达式 #
基本语法 #
hcl
condition ? true_value : false_value
简单条件 #
hcl
variable "environment" {
default = "prod"
}
locals {
instance_type = var.environment == "prod" ? "t2.large" : "t2.micro"
}
resource "aws_instance" "example" {
instance_type = local.instance_type
}
嵌套条件 #
hcl
locals {
instance_type = var.environment == "prod" ? "t2.large" : (
var.environment == "staging" ? "t2.medium" : "t2.micro"
)
}
条件创建资源 #
hcl
variable "create_instance" {
default = true
}
resource "aws_instance" "example" {
count = var.create_instance ? 1 : 0
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
条件属性 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
monitoring = var.enable_monitoring ? true : false
}
使用 coalesce #
hcl
locals {
name = coalesce(var.name, "default-name")
}
locals {
tags = coalesce(var.tags, {})
}
for 表达式 #
基本语法 #
hcl
[for item in list : expression]
[for item in list : expression if condition]
{for key, value in map : key => value}
列表转换 #
hcl
variable "names" {
default = ["alice", "bob", "charlie"]
}
locals {
upper_names = [for name in var.names : upper(name)]
}
output "upper_names" {
value = local.upper_names
}
带过滤 #
hcl
variable "numbers" {
default = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
locals {
even_numbers = [for n in var.numbers : n if n % 2 == 0]
}
output "even_numbers" {
value = local.even_numbers
}
带索引 #
hcl
variable "items" {
default = ["a", "b", "c"]
}
locals {
indexed = [for i, item in var.items : "${i}: ${item}"]
}
output "indexed" {
value = local.indexed
}
映射转换 #
hcl
variable "users" {
default = {
alice = 30
bob = 25
charlie = 35
}
}
locals {
user_list = [for name, age in var.users : "${name} is ${age}"]
age_map = {for name, age in var.users : name => age * 365}
}
output "user_list" {
value = local.user_list
}
对象列表转换 #
hcl
variable "servers" {
default = [
{
name = "web-1"
type = "t2.micro"
},
{
name = "web-2"
type = "t2.small"
}
]
}
locals {
server_names = [for s in var.servers : s.name]
server_map = {for s in var.servers : s.name => s.type}
filtered_servers = [for s in var.servers : s.name if s.type == "t2.micro"]
}
分组 #
hcl
variable "items" {
default = [
{ name = "a", type = "web" },
{ name = "b", type = "api" },
{ name = "c", type = "web" }
]
}
locals {
by_type = {
for item in var.items : item.type => item.name...
}
}
output "by_type" {
value = local.by_type
}
splat 表达式 #
全属性展开 #
hcl
resource "aws_instance" "web" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
output "instance_ids" {
value = aws_instance.web[*].id
}
output "instance_ips" {
value = aws_instance.web[*].public_ip
}
嵌套属性 #
hcl
resource "aws_instance" "web" {
count = 2
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "web-${count.index}"
}
}
output "instance_names" {
value = aws_instance.web[*].tags.Name
}
条件展开 #
hcl
variable "create_instances" {
default = true
}
resource "aws_instance" "web" {
count = var.create_instances ? 3 : 0
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
output "instance_ids" {
value = aws_instance.web[*].id
}
动态块 #
基本语法 #
hcl
resource "aws_security_group" "example" {
name = "example"
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}
完整示例 #
hcl
variable "ingress_rules" {
default = [
{
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
{
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
{
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
]
}
resource "aws_security_group" "web" {
name = "web-sg"
description = "Web server security group"
vpc_id = aws_vpc.main.id
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
使用迭代器 #
hcl
resource "aws_security_group" "example" {
name = "example"
dynamic "ingress" {
for_each = var.ingress_rules
iterator = rule
content {
from_port = rule.value.from_port
to_port = rule.value.to_port
protocol = rule.value.protocol
cidr_blocks = rule.value.cidr_blocks
}
}
}
嵌套动态块 #
hcl
variable "rules" {
default = [
{
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
]
}
resource "aws_security_group" "example" {
name = "example"
dynamic "ingress" {
for_each = [for r in var.rules : r if r.type == "ingress"]
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
dynamic "egress" {
for_each = [for r in var.rules : r if r.type == "egress"]
content {
from_port = egress.value.from_port
to_port = egress.value.to_port
protocol = egress.value.protocol
cidr_blocks = egress.value.cidr_blocks
}
}
}
动态标签 #
hcl
variable "tags" {
default = {
Environment = "production"
Project = "my-project"
}
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
dynamic "tags" {
for_each = var.tags
content {
key = tags.key
value = tags.value
}
}
}
运算符 #
算术运算符 #
hcl
locals {
sum = 1 + 2
difference = 10 - 5
product = 3 * 4
quotient = 15 / 3
modulo = 10 % 3
negation = -5
}
比较运算符 #
hcl
locals {
equal = 5 == 5
not_equal = 5 != 3
greater = 10 > 5
less = 3 < 5
greater_eq = 5 >= 5
less_eq = 3 <= 5
}
逻辑运算符 #
hcl
locals {
and_op = true && false
or_op = true || false
not_op = !true
}
复杂表达式示例 #
环境配置 #
hcl
variable "environment" {
default = "prod"
}
locals {
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.config[var.environment]
}
resource "aws_autoscaling_group" "web" {
min_size = local.current_config.min_size
max_size = local.current_config.max_size
launch_template {
id = aws_launch_template.web.id
}
}
子网 CIDR 计算 #
hcl
variable "vpc_cidr" {
default = "10.0.0.0/16"
}
variable "availability_zones" {
default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
locals {
public_subnet_cidrs = [
for i, az in var.availability_zones : cidrsubnet(var.vpc_cidr, 8, i)
]
private_subnet_cidrs = [
for i, az in var.availability_zones : cidrsubnet(var.vpc_cidr, 8, i + 10)
]
}
resource "aws_subnet" "public" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = local.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
}
标签合并 #
hcl
variable "default_tags" {
default = {
ManagedBy = "terraform"
}
}
variable "extra_tags" {
default = {}
}
locals {
common_tags = merge(
var.default_tags,
{
Environment = var.environment
Project = var.project_name
},
var.extra_tags
)
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = merge(local.common_tags, {
Name = "${var.project_name}-${var.environment}"
})
}
条件资源创建 #
hcl
variable "create_vpc" {
default = true
}
variable "vpc_id" {
default = null
}
data "aws_vpc" "existing" {
count = var.create_vpc ? 0 : 1
id = var.vpc_id
}
resource "aws_vpc" "main" {
count = var.create_vpc ? 1 : 0
cidr_block = "10.0.0.0/16"
}
locals {
vpc_id = var.create_vpc ? aws_vpc.main[0].id : data.aws_vpc.existing[0].id
}
下一步 #
掌握了表达式与条件后,接下来学习 Provisioners,了解如何在资源创建后执行操作!
最后更新:2026-03-29