首页 / 速查手册 / 在线

Terraform速查手册

Terraform HCL/state/模块/常用函数速查

速查手册 · 1 次 · 2026-10-04 · 分享 · 全屏

📝 HCL 基础语法

resource 资源块

最核心的块:资源类型.本地名称 构成唯一地址。

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name        = "${var.project}-web"
    Environment = var.env
  }
}
参数、注释与字符串插值

支持三种注释;${} 内可放任意表达式;<<- 是多行字符串。

# 井号行注释
// 双斜杠行注释
/* 块注释 */

locals {
  name  = "${var.project}-${var.env}"   # 插值
  count = 3
  raw   = <<-EOT
    line1 ${var.env}
    line2
  EOT
}
count 批量创建

count.index 从 0 开始;count=0 可不创建。

resource "aws_instance" "web" {
  count         = var.instance_count
  ami           = "ami-xxx"
  instance_type = "t3.micro"

  tags = {
    Name = "web-${count.index}"
  }
}

# 引用:aws_instance.web[0].id
# 全部 ID:aws_instance.web[*].id
for_each 按键创建

比 count 更稳:增删某键不影响其他资源的地址。

resource "aws_instance" "web" {
  for_each = {
    api = "t3.small"
    job = "t3.micro"
  }

  ami           = "ami-xxx"
  instance_type = each.value

  tags = {
    Name = "web-${each.key}"
  }
}

# 引用:aws_instance.web["api"].id
lifecycle 生命周期

控制创建/更新/销毁策略;ignore_changes 忽略外部变更。

resource "aws_instance" "web" {
  # ...
  lifecycle {
    create_before_destroy = true
    prevent_destroy       = false
    ignore_changes = [
      ami,
      tags["LastScaledAt"]
    ]
  }
}
dynamic 动态嵌套块

循环生成 ingress/rule 这类重复嵌套块。

resource "aws_security_group" "web" {
  name = "web-sg"

  dynamic "ingress" {
    for_each = var.allowed_ports
    content {
      from_port = ingress.value
      to_port   = ingress.value
      protocol  = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}

🔌 provider

required_providers 与版本锁定

~> 允许补丁与次版本升级;建议提交 .terraform.lock.hcl。

terraform {
  required_version = ">= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.5.0"
    }
  }
}

provider "aws" {
  region = "cn-north-1"
}
alias 多 provider 实例

同类型多地域/多账号时用 alias,资源上显式选择。

provider "aws" {
  region = "cn-north-1"
  alias  = "beijing"
}

provider "aws" {
  region = "cn-northwest-1"
  alias  = "ningxia"
}

resource "aws_instance" "bj" {
  provider = aws.beijing
  # ...
}

resource "aws_instance" "nx" {
  provider = aws.ningxia
  # ...
}

🔎 data 与资源引用

data 数据源(只读查询)

查询已有基础设施信息,不创建/修改资源。

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/*/22.04/*"]
  }
}

resource "aws_instance" "web" {
  ami = data.aws_ami.ubuntu.id
}

data "aws_caller_identity" "current" {}
output "account_id" {
  value = data.aws_caller_identity.current.account_id
}
引用资源属性与依赖

通过引用隐式建立依赖;显式依赖用 depends_on。

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "app" {
  vpc_id     = aws_vpc.main.id        # 隐式依赖
  cidr_block = "10.0.1.0/24"
}

resource "aws_s3_bucket" "logs" {
  depends_on = [aws_subnet.app]       # 显式依赖
  bucket     = "my-logs"
}

🎛 variable 变量

基础类型变量

string/number/bool;可给默认值、描述与校验规则。

variable "env" {
  type        = string
  description = "部署环境:dev / staging / prod"
  default     = "dev"

  validation {
    condition     = contains(["dev", "staging", "prod"], var.env)
    error_message = "env 必须是 dev/staging/prod 之一"
  }
}

variable "instance_count" {
  type    = number
  default = 1
}

variable "enable_https" {
  type    = bool
  default = true
}
复杂类型

list/map/set/object 组合表达结构化配置。

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

variable "tags" {
  type = map(string)
  default = {
    Project = "demo"
    Owner   = "ops"
  }
}

variable "app" {
  type = object({
    name     = string
    replicas = number
    envs     = map(string)
  })
}
nullable 与敏感变量

sensitive=true 后值不会出现在日志中。

variable "db_password" {
  type      = string
  sensitive = true
  nullable  = false
}

variable "endpoint" {
  type     = string
  default  = null          # 允许为空,代码中用条件判断
}

# 引用
resource "aws_db_instance" "main" {
  password = var.db_password
}
tfvars 与命令行赋值

terraform.tfvars 自动加载,其他文件用 -var-file 指定。

# prod.tfvars
env             = "prod"
instance_count  = 3
ports           = [80, 443, 8080]
tags = {
  Project = "demo"
}

# 命令行
terraform apply -var-file="prod.tfvars"
terraform apply -var="env=test" -var="instance_count=2"
TF_VAR_env=prod terraform plan

🧮 locals 与 output

locals 局部值

给重复表达式命名,类似常量/派生配置,不暴露给外部。

locals {
  name_prefix = "${var.project}-${var.env}"
  common_tags = {
    Project     = var.project
    Environment = var.env
    ManagedBy   = "terraform"
  }
  bucket_suffix = "abc123"
}

resource "aws_s3_bucket" "data" {
  bucket = "${local.name_prefix}-data-${local.bucket_suffix}"
  tags   = local.common_tags
}
output 输出

apply 后展示关键信息;sensitive 值会被打码;模块输出供外部引用。

output "public_ip" {
  value       = aws_instance.web.public_ip
  description = "Web 服务器公网 IP"
}

output "db_password" {
  value     = var.db_password
  sensitive = true
}

output "all_ips" {
  value = aws_instance.web[*].private_ip
}

⌨️ 常用命令

init / plan / apply

日常三件套;plan 落盘后 apply 同一计划可保证不漂移。

terraform init
terraform init -upgrade            # 升级 provider/模块版本
terraform plan
terraform plan -out=tfplan
terraform apply
terraform apply tfplan
terraform apply -auto-approve -var-file=prod.tfvars
destroy 与 state 管理

state 是“真实世界”的映射,改动前先备份。

terraform destroy
terraform destroy -target=aws_instance.web
terraform state list
terraform state show aws_instance.web
terraform state mv aws_s3_bucket.a aws_s3_bucket.b
terraform state rm aws_s3_bucket.old     # 解除托管但不删资源
terraform state pull > backup.tfstate
terraform state push backup.tfstate
import / replace / 0.15+ taint 替代

import 纳管已有资源;-replace 强制重建单个资源。

terraform import aws_instance.web i-1234567890abcdef0
terraform import 'aws_route53_record.dns["www"]' Z123 www_example_com_A

terraform plan -replace=aws_instance.web
terraform apply -replace=aws_instance.web

terraform fmt
terraform validate
terraform console
terraform show tfplan
workspace 多环境隔离

同一套代码在不同 state 间切换;大型项目也可用目录/后端分环境。

terraform workspace list
terraform workspace new dev
terraform workspace new prod
terraform workspace select prod
terraform workspace show          # 当前工作区

# 代码中区分
resource "aws_instance" "web" {
  tags = { Env = terraform.workspace }
}

🧱 模块 module

使用 registry 模块

source 指定来源,version 固定模块版本。

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.8.1"

  name = "main-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["cn-north-1a", "cn-north-1b"]
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnets = ["10.0.11.0/24", "10.0.12.0/24"]
}

output "vpc_id" {
  value = module.vpc.vpc_id
}
编写本地模块

模块就是一个 .tf 目录,通过 variables.tf / outputs.tf 定义输入输出。

# modules/s3/main.tf
resource "aws_s3_bucket" "this" {
  bucket = "${var.prefix}-${var.env}"
  tags   = var.tags
}

# 调用
module "data_bucket" {
  source = "./modules/s3"
  prefix = "demo"
  env    = var.env
  tags   = local.common_tags
}

# 其他 source 形式:
# source = "git::https://github.com/org/repo.git//modules/s3?ref=v1.0"
# source = "github.com/org/repo//modules/s3"

ƒ 常用内置函数

字符串函数

format/join/split/replace/lower/upper/chomp。

format("%s-%02d", "web", 1)        # "web-01"
join(",", ["a", "b", "c"])        # "a,b,c"
split(",", "a,b,c")               # ["a","b","c"]
replace("a-b-c", "-", "_")        # "a_b_c"
lower("ABC")                      # "abc"
trimspace("  x  ")                # "x"
substr("hello", 0, 3)             # "hel"
chomp("line\n")                   # "line"
集合与类型转换

merge/concat/lookup/element/flatten/zipmap 等。

merge({a=1}, {b=2}, {a=10})        # {a=10,b=2}
concat([1,2], [3,4])              # [1,2,3,4]
lookup({a="x"}, "b", "default")   # "default"
element(["a","b"], 1)             # "b"
flatten([[1,2],[3]])              # [1,2,3]
toset(["a","a","b"])              # ["a","b"]
keys({a=1, b=2})                  # ["a","b"]
values({a=1, b=2})                # [1,2]
zipmap(["a","b"], [1,2])          # {a=1,b=2}
tonumber("12")                    # 12
for 表达式

在 HCL 内做 map/list 转换与过滤。

[for s in ["a", "bb", "ccc"] : upper(s)]
# ["A","BB","CCC"]

[for k, v in var.tags : "${k}=${v}"]

{for k, v in var.users : k => v.name if v.active}

[for p in var.ports : p if p > 1024]    # 过滤
文件与编码函数

templatefile 渲染脚本模板;jsonencode/yamlencode 序列化。

file("${path.module}/conf/nginx.conf")
fileexists("${path.module}/conf/x.conf")

templatefile("${path.module}/userdata.sh", {
  name = "web"
  port = 8080
})

jsonencode({ name = "Tom", age = 18 })
jsondecode("{\"a\":1}")
yamlencode({ a = 1 })
base64encode("hello")
md5(file("data.txt"))
cidrsubnet("10.0.0.0/16", 8, 1)   # 划子网

📖 使用说明

全程在浏览器本地运行。

操作步骤:

  1. 搜索或浏览分类条目;
  2. 查看HCL示例;
  3. 点击复制代码块。

💬 用户评论 (0)

还没有评论,快来抢沙发!

请添加微信联系我