Terraform 速查表
常用命令
基础命令
| 命令 | 说明 |
|---|---|
terraform init | 初始化工作目录,下载 Provider 插件 |
terraform validate | 验证配置文件的语法 |
terraform plan | 预览将要执行的变更 |
terraform apply | 应用配置,创建或更新资源 |
terraform destroy | 销毁所有管理的资源 |
terraform refresh | 刷新状态文件,同步实际资源状态 |
terraform show | 显示当前状态或计划详情 |
terraform version | 显示 Terraform 版本 |
状态管理命令
| 命令 | 说明 |
|---|---|
terraform state list | 列出所有管理的资源 |
terraform state show <资源> | 显示特定资源的详细状态 |
terraform state rm <资源> | 从状态中移除资源(不销毁实际资源) |
terraform state mv <旧名> <新名> | 重命名或移动状态中的资源 |
terraform state pull | 下载并输出当前状态 |
terraform state push <文件> | 上传状态文件 |
terraform import <资源> <ID> | 将现有资源导入 Terraform 管理 |
terraform force-unlock <ID> | 强制解锁状态 |
工作区命令
| 命令 | 说明 |
|---|---|
terraform workspace list | 列出所有工作区 |
terraform workspace new <名称> | 创建新工作区 |
terraform workspace select <名称> | 切换到指定工作区 |
terraform workspace show | 显示当前工作区 |
terraform workspace delete <名称> | 删除工作区 |
格式化命令
| 命令 | 说明 |
|---|---|
terraform fmt | 格式化当前目录的配置文件 |
terraform fmt -recursive | 递归格式化所有配置文件 |
terraform fmt -check | 检查格式是否正确(不修改文件) |
terraform fmt -diff | 显示格式变更的差异 |
HCL 语法速查
基本语法
# 单行注释
/* 多行注释 */
# 块定义
block_type "label1" "label2" {
argument_name = argument_value
}
# 变量引用
var.variable_name
local.local_name
module.module_name.output_name
resource.resource_type.resource_name.attribute
数据类型
# 字符串
"hello world"
"hello ${var.name}"
<<EOF
多行
字符串
EOF
# 数字
42
3.14
# 布尔值
true
false
# 列表
["a", "b", "c"]
# 映射
{
key1 = "value1"
key2 = "value2"
}
# null
null
常用函数
字符串函数
upper("hello") # "HELLO"
lower("WORLD") # "world"
substr("hello", 0, 3) # "hel"
join("-", ["a", "b"]) # "a-b"
split(",", "a,b,c") # ["a", "b", "c"]
replace("hello", "l", "x") # "hexxo"
format("%s-%d", "test", 1) # "test-1"
数字函数
max(1, 5, 3) # 5
min(1, 5, 3) # 1
ceil(1.2) # 2
floor(1.8) # 1
abs(-10) # 10
集合函数
length(["a", "b"]) # 2
concat(["a"], ["b"]) # ["a", "b"]
distinct(["a", "a", "b"]) # ["a", "b"]
contains(["a", "b"], "a") # true
keys({a=1, b=2}) # ["a", "b"]
values({a=1, b=2}) # [1, 2]
merge({a=1}, {b=2}) # {a=1, b=2}
类型转换函数
tostring(123) # "123"
tonumber("123") # 123
tobool("true") # true
tolist([1, 2, 3]) # [1, 2, 3]
tomap({a=1}) # {a=1}
文件函数
file("script.sh") # 读取文件内容
filebase64("file") # Base64 编码文件内容
fileexists("file") # 检查文件是否存在
filemd5("file") # 计算文件 MD5
templatefile("template.tmpl", {var = "value"})
编码函数
jsonencode({a=1}) # '{"a":1}'
jsondecode('{"a":1}') # {a=1}
yamlencode({a=1}) # "a: 1\n"
yamldecode("a: 1") # {a=1}
base64encode("text") # "dGV4dA=="
base64decode("dGV4dA==") # "text"
路径函数
path.module # 当前模块路径
path.root # 根模块路径
path.cwd # 当前工作目录
时间和哈希函数
timestamp() # 当前时间戳
uuid() # 生成 UUID
md5("text") # 计算 MD5
sha256("text") # 计算 SHA256
配置块速查
terraform 块
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
provider 块
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Environment = "Production"
}
}
}
# 别名 Provider
provider "aws" {
alias = "west"
region = "us-west-2"
}
resource 块
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
lifecycle {
create_before_destroy = true
prevent_destroy = false
ignore_changes = [tags]
}
}
data 块
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-*"]
}
}
variable 块
variable "instance_type" {
description = "EC2 实例类型"
type = string
default = "t2.micro"
sensitive = false
validation {
condition = contains(["t2.micro", "t2.small"], var.instance_type)
error_message = "无效的实例类型。"
}
}
output 块
output "instance_ip" {
description = "实例 IP 地址"
value = aws_instance.web.public_ip
sensitive = false
}
locals 块
locals {
common_tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
name_prefix = "${var.project}-${var.environment}"
}
module 块
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
}
表达式速查
字符串插值
name = "${var.project}-${var.environment}"
条件表达式
instance_type = var.environment == "prod" ? "t2.large" : "t2.micro"
count = var.enabled ? 1 : 0
for 表达式
# 列表推导
[for s in var.subnets : s.cidr_block]
[for s in var.subnets : s.name if s.public]
# 映射推导
{for s in var.subnets : s.name => s.cidr_block}
{for s in var.subnets : s.name => s.cidr_block if s.public}
解构表达式
# 展开操作符
security_groups = [aws_security_group.web.id, aws_security_group.app.id]
all_groups = concat(local.base_groups, var.additional_groups)
# 星号操作符
instance_ips = aws_instance.web[*].public_ip
版本约束
| 约束 | 含义 |
|---|---|
= 1.2.3 | 精确匹配 1.2.3 |
!= 1.2.3 | 排除 1.2.3 |
> 1.2.3 | 大于 1.2.3 |
>= 1.2.3 | 大于或等于 1.2.3 |
< 1.2.3 | 小于 1.2.3 |
<= 1.2.3 | 小于或等于 1.2.3 |
~> 1.2.3 | 兼容版本(>= 1.2.3, < 1.3.0) |
~> 1.2 | 兼容版本(>= 1.2.0, < 2.0.0) |
>= 1.0, < 2.0 | 版本范围 |
变量类型
# 基本类型
string
number
bool
# 集合类型
list(<TYPE>)
set(<TYPE>)
map(<TYPE>)
object({<ATTR_NAME> = <TYPE>, ...})
tuple([<TYPE>, ...])
# 示例
variable "tags" {
type = map(string)
}
variable "subnets" {
type = list(object({
name = string
cidr = string
public = bool
}))
}
环境变量
| 变量 | 说明 |
|---|---|
TF_LOG | 日志级别(TRACE, DEBUG, INFO, WARN, ERROR) |
TF_LOG_PATH | 日志文件路径 |
TF_VAR_<name> | 设置变量值 |
TF_CLI_ARGS | 全局 CLI 参数 |
TF_CLI_ARGS_<command> | 特定命令的 CLI 参数 |
TF_DATA_DIR | 数据目录(默认 .terraform) |
TF_WORKSPACE | 当前工作区 |
TF_IN_AUTOMATION | 自动化模式标志 |
常用 Provider 配置
AWS
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}
}
阿里云
provider "alicloud" {
region = "cn-hangzhou"
}
Azure
provider "azurerm" {
features {}
}
Google Cloud
provider "google" {
project = "my-project"
region = "us-central1"
}
Kubernetes
provider "kubernetes" {
config_path = "~/.kube/config"
}
Docker
provider "docker" {
host = "unix:///var/run/docker.sock"
}
生命周期元参数
resource "aws_instance" "web" {
lifecycle {
# 创建新资源后再销毁旧资源
create_before_destroy = true
# 防止资源被销毁
prevent_destroy = true
# 忽略特定属性的变更
ignore_changes = [
tags,
user_data
]
# 替换资源时触发的条件
replace_triggered_by = [
aws_security_group.web.id
]
}
}
动态块
resource "aws_security_group" "example" {
name = "example-sg"
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}
远程状态数据源
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = "terraform-state"
key = "vpc/terraform.tfstate"
region = "us-east-1"
}
}
# 使用远程状态
vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id
故障排除
启用调试日志
export TF_LOG=DEBUG
export TF_LOG_PATH=terraform.log
terraform apply
常见错误处理
# 状态锁定
terraform force-unlock <LOCK_ID>
# 资源导入
terraform import aws_instance.web i-1234567890abcdef0
# 状态修复
terraform state rm aws_instance.web
terraform import aws_instance.web i-1234567890abcdef0
# 刷新状态
terraform refresh
推荐工具
| 工具 | 用途 | 安装 |
|---|---|---|
| tflint | 代码检查 | brew install tflint |
| tfsec | 安全扫描 | brew install tfsec |
| checkov | 合规性检查 | pip install checkov |
| terraform-docs | 文档生成 | brew install terraform-docs |
| terragrunt | Terraform 包装器 | brew install terragrunt |
| tfenv | 版本管理 | brew install tfenv |