Terraform 资源管理 #
什么是资源? #
资源(Resource)是 Terraform 配置中最重要的组成部分,用于描述基础设施对象,如虚拟机、网络、存储等。每个资源块描述一个或多个基础设施对象。
text
┌─────────────────────────────────────────────────────────────┐
│ 资源结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ resource "<PROVIDER>_<TYPE>" "<NAME>" { │
│ <CONFIG> │
│ } │
│ │
│ 示例: │
│ resource "aws_instance" "web_server" { │
│ ami = "ami-0c55b159cbfafe1f0" │
│ instance_type = "t2.micro" │
│ } │
│ │
│ 组成: │
│ - PROVIDER: aws │
│ - TYPE: instance │
│ - NAME: web_server │
│ - CONFIG: 配置参数 │
│ │
└─────────────────────────────────────────────────────────────┘
资源语法 #
基本语法 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
资源地址 #
text
<资源类型>.<资源名称>
aws_instance.example
aws_security_group.web
aws_subnet.public
资源引用 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
subnet_id = aws_subnet.public.id
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
output "instance_ip" {
value = aws_instance.example.public_ip
}
资源生命周期 #
生命周期阶段 #
text
┌─────────────────────────────────────────────────────────────┐
│ 资源生命周期 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Create │ -> │ Update │ -> │ Delete │ │
│ │ 创建 │ │ 更新 │ │ 删除 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 创建:资源不存在时创建新资源 │
│ 更新:资源存在但配置发生变化 │
│ 删除:资源从配置中移除 │
│ │
└─────────────────────────────────────────────────────────────┘
生命周期配置 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
prevent_destroy = false
ignore_changes = [tags]
replace_triggered_by = [aws_security_group.example.id]
}
}
create_before_destroy #
hcl
lifecycle {
create_before_destroy = true
}
text
┌─────────────────────────────────────────────────────────────┐
│ 创建后销毁模式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 默认模式: │
│ 销毁旧资源 → 创建新资源 │
│ (可能导致服务中断) │
│ │
│ create_before_destroy 模式: │
│ 创建新资源 → 销毁旧资源 │
│ (减少服务中断时间) │
│ │
│ 适用场景: │
│ - 需要最小化停机时间 │
│ - 资源有依赖关系 │
│ │
└─────────────────────────────────────────────────────────────┘
prevent_destroy #
hcl
lifecycle {
prevent_destroy = true
}
防止资源被意外销毁,当执行 terraform destroy 时会报错。
ignore_changes #
hcl
lifecycle {
ignore_changes = [
tags,
instance_type,
]
}
忽略指定属性的变更:
hcl
lifecycle {
ignore_changes = [
tags["Environment"],
]
}
lifecycle {
ignore_changes = all
}
replace_triggered_by #
hcl
resource "aws_security_group" "example" {
name = "example-sg"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
lifecycle {
replace_triggered_by = [
aws_security_group.example.id
]
}
}
资源依赖 #
隐式依赖 #
hcl
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
resource "aws_instance" "web" {
subnet_id = aws_subnet.public.id
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
Terraform 自动检测依赖关系:
text
aws_vpc.main
│
└── aws_subnet.public
│
└── aws_instance.web
显式依赖 #
hcl
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
depends_on = [
aws_security_group.web
]
}
resource "aws_security_group" "web" {
name = "web-sg"
}
depends_on 使用场景 #
hcl
resource "aws_s3_bucket" "logs" {
bucket = "my-logs-bucket"
}
resource "aws_iam_role_policy" "instance_policy" {
name = "instance-policy"
role = aws_iam_role.instance.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["s3:PutObject"]
Effect = "Allow"
Resource = "${aws_s3_bucket.logs.arn}/*"
}
]
})
}
resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
iam_instance_profile = aws_iam_instance_profile.app.name
depends_on = [
aws_iam_role_policy.instance_policy
]
}
资源元参数 #
count #
hcl
resource "aws_instance" "server" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "Server ${count.index + 1}"
}
}
访问 count 创建的资源:
hcl
output "instance_ids" {
value = aws_instance.server[*].id
}
output "first_instance_ip" {
value = aws_instance.server[0].public_ip
}
使用 count 条件创建:
hcl
resource "aws_instance" "server" {
count = var.create_instance ? 1 : 0
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
for_each #
hcl
variable "servers" {
default = {
web = {
instance_type = "t2.micro"
name = "Web Server"
}
api = {
instance_type = "t2.small"
name = "API Server"
}
db = {
instance_type = "t2.medium"
name = "Database Server"
}
}
}
resource "aws_instance" "server" {
for_each = var.servers
ami = "ami-0c55b159cbfafe1f0"
instance_type = each.value.instance_type
tags = {
Name = each.value.name
}
}
访问 for_each 创建的资源:
hcl
output "instance_ids" {
value = {
for k, v in aws_instance.server : k => v.id
}
}
output "web_instance_ip" {
value = aws_instance.server["web"].public_ip
}
count vs for_each #
text
┌─────────────────────────────────────────────────────────────┐
│ count vs for_each │
├─────────────────────────────────────────────────────────────┤
│ │
│ count: │
│ - 创建相同类型的多个资源 │
│ - 资源通过索引访问 │
│ - 删除中间元素会影响后续索引 │
│ │
│ for_each: │
│ - 创建有差异的多个资源 │
│ - 资源通过键访问 │
│ - 删除元素不影响其他资源 │
│ │
│ 推荐:需要创建多个相似资源时优先使用 for_each │
│ │
└─────────────────────────────────────────────────────────────┘
provider #
hcl
provider "aws" {
region = "us-east-1"
alias = "east"
}
provider "aws" {
region = "us-west-2"
alias = "west"
}
resource "aws_instance" "east_server" {
provider = aws.east
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
resource "aws_instance" "west_server" {
provider = aws.west
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
资源行为 #
创建行为 #
text
┌─────────────────────────────────────────────────────────────┐
│ 资源创建 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 检查状态文件,确认资源不存在 │
│ 2. 调用 Provider API 创建资源 │
│ 3. 获取资源属性 │
│ 4. 更新状态文件 │
│ │
└─────────────────────────────────────────────────────────────┘
更新行为 #
text
┌─────────────────────────────────────────────────────────────┐
│ 资源更新 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 就地更新(In-place update): │
│ - 修改资源属性而不重建 │
│ - 如修改 tags │
│ │
│ 重建更新(Destroy and create): │
│ - 必须删除旧资源,创建新资源 │
│ - 如修改 ami、instance_type │
│ │
└─────────────────────────────────────────────────────────────┘
删除行为 #
text
┌─────────────────────────────────────────────────────────────┐
│ 资源删除 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 检查依赖关系 │
│ 2. 按依赖顺序删除 │
│ 3. 调用 Provider API 删除资源 │
│ 4. 从状态文件中移除 │
│ │
└─────────────────────────────────────────────────────────────┘
资源导入 #
导入现有资源 #
bash
terraform import aws_instance.example i-1234567890abcdef0
导入配置 #
hcl
resource "aws_instance" "example" {
}
bash
terraform import aws_instance.example i-1234567890abcdef0
批量导入 #
hcl
import {
to = aws_instance.example
id = "i-1234567890abcdef0"
}
import {
to = aws_security_group.web
id = "sg-1234567890abcdef0"
}
resource "aws_instance" "example" {
}
resource "aws_security_group" "web" {
}
资源标记 #
taint 标记 #
bash
terraform taint aws_instance.example
terraform plan
terraform apply
untaint 取消标记 #
bash
terraform untaint aws_instance.example
使用场景 #
text
┌─────────────────────────────────────────────────────────────┐
│ taint 使用场景 │
├─────────────────────────────────────────────────────────────┤
│ │
│ - 资源配置正确但运行状态异常 │
│ - 需要重建资源以应用某些变更 │
│ - 测试重建流程 │
│ │
│ 注意:taint 不会立即重建资源,需要在下次 apply 时重建 │
│ │
└─────────────────────────────────────────────────────────────┘
资源定位 #
移动资源 #
bash
terraform state mv aws_instance.old aws_instance.new
在配置中使用 moved 块:
hcl
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
moved {
from = aws_instance.example
to = aws_instance.web_server
}
删除资源(从状态中移除) #
bash
terraform state rm aws_instance.example
资源最佳实践 #
命名规范 #
hcl
resource "aws_instance" "web_server" {
}
resource "aws_security_group" "web_alb" {
}
resource "aws_s3_bucket" "log_storage" {
}
使用标签 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = merge(
var.common_tags,
{
Name = "example-instance"
Type = "web-server"
}
)
}
模块化 #
hcl
module "web_server" {
source = "./modules/ec2"
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
subnet_id = module.vpc.public_subnet_id
}
文档注释 #
hcl
resource "aws_instance" "web_server" {
ami = var.ami_id
instance_type = var.instance_type
user_data = <<-EOF
#!/bin/bash
# Install and configure web server
yum install -y httpd
systemctl start httpd
EOF
}
下一步 #
掌握了资源管理后,接下来学习 变量,了解如何使用变量使配置更加灵活!
最后更新:2026-03-29