terraform
Scannednpx machina-cli add skill chaterm/terminal-skills/terraform --openclawTerraform 基础设施即代码
概述
HCL 编写、状态管理、模块开发等技能。
基础命令
# 初始化
terraform init
terraform init -upgrade # 升级 provider
# 格式化
terraform fmt
terraform fmt -recursive
# 验证
terraform validate
# 计划
terraform plan
terraform plan -out=plan.tfplan
# 应用
terraform apply
terraform apply plan.tfplan
terraform apply -auto-approve
# 销毁
terraform destroy
terraform destroy -auto-approve
# 查看状态
terraform show
terraform state list
terraform state show resource_type.name
# 输出
terraform output
terraform output -json
HCL 语法
Provider 配置
# providers.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
}
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
}
变量定义
# variables.tf
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}
variable "environment" {
description = "Environment name"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "tags" {
description = "Resource tags"
type = map(string)
default = {}
}
variable "subnets" {
description = "Subnet configuration"
type = list(object({
cidr_block = string
az = string
}))
}
资源定义
# main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "${var.environment}-vpc"
}
}
resource "aws_subnet" "public" {
count = length(var.subnets)
vpc_id = aws_vpc.main.id
cidr_block = var.subnets[count.index].cidr_block
availability_zone = var.subnets[count.index].az
tags = {
Name = "${var.environment}-public-${count.index + 1}"
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.public[0].id
tags = merge(var.tags, {
Name = "${var.environment}-web"
})
}
数据源
# data.tf
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
data "aws_availability_zones" "available" {
state = "available"
}
输出
# outputs.tf
output "vpc_id" {
description = "VPC ID"
value = aws_vpc.main.id
}
output "instance_public_ip" {
description = "Public IP of web instance"
value = aws_instance.web.public_ip
}
output "subnet_ids" {
description = "Subnet IDs"
value = aws_subnet.public[*].id
}
状态管理
状态命令
# 列出资源
terraform state list
# 查看资源
terraform state show aws_instance.web
# 移动资源
terraform state mv aws_instance.web aws_instance.app
# 删除资源(从状态中)
terraform state rm aws_instance.web
# 导入现有资源
terraform import aws_instance.web i-1234567890abcdef0
# 拉取远程状态
terraform state pull > state.json
# 推送状态
terraform state push state.json
远程后端
# S3 后端
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# 初始化后端
terraform init -backend-config="bucket=my-bucket"
模块
模块结构
modules/
└── vpc/
├── main.tf
├── variables.tf
├── outputs.tf
└── README.md
模块定义
# modules/vpc/main.tf
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
tags = merge(var.tags, {
Name = var.name
})
}
# modules/vpc/variables.tf
variable "name" {
type = string
}
variable "cidr_block" {
type = string
}
variable "enable_dns_hostnames" {
type = bool
default = true
}
variable "tags" {
type = map(string)
default = {}
}
# modules/vpc/outputs.tf
output "vpc_id" {
value = aws_vpc.this.id
}
使用模块
# 本地模块
module "vpc" {
source = "./modules/vpc"
name = "my-vpc"
cidr_block = "10.0.0.0/16"
tags = var.tags
}
# 远程模块
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
}
# 引用模块输出
resource "aws_subnet" "public" {
vpc_id = module.vpc.vpc_id
# ...
}
工作区
# 列出工作区
terraform workspace list
# 创建工作区
terraform workspace new dev
terraform workspace new prod
# 切换工作区
terraform workspace select dev
# 删除工作区
terraform workspace delete dev
# 在配置中使用
locals {
environment = terraform.workspace
}
常见场景
场景 1:条件创建资源
variable "create_instance" {
type = bool
default = true
}
resource "aws_instance" "web" {
count = var.create_instance ? 1 : 0
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
}
场景 2:for_each 循环
variable "instances" {
type = map(object({
instance_type = string
ami = string
}))
}
resource "aws_instance" "this" {
for_each = var.instances
ami = each.value.ami
instance_type = each.value.instance_type
tags = {
Name = each.key
}
}
场景 3:动态块
resource "aws_security_group" "this" {
name = "my-sg"
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
}
}
}
场景 4:依赖管理
resource "aws_instance" "web" {
# 隐式依赖
subnet_id = aws_subnet.public.id
# 显式依赖
depends_on = [aws_internet_gateway.main]
}
故障排查
| 问题 | 排查方法 |
|---|---|
| 状态锁定 | terraform force-unlock LOCK_ID |
| Provider 错误 | terraform init -upgrade |
| 状态不一致 | terraform refresh |
| 循环依赖 | 检查 depends_on |
# 调试模式
TF_LOG=DEBUG terraform plan
# 查看详细计划
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan | jq
# 验证配置
terraform validate
Source
git clone https://github.com/chaterm/terminal-skills/blob/main/devops/terraform/SKILL.mdView on GitHub Overview
Terraform 是一款基础设施即代码工具,允许你用 HCL 编写云资源的配置、通过 provider 与资源实现声明式部署、并借助后端管理状态。你可以在一个统一的工作流中定义、计划、应用和销毁资源,支持多云和本地资源,同时通过模块实现高可复用的基础设施组件。
How This Skill Works
你把资源、变量、数据源和模块写入 .tf 文件,配置 provider 与后端。执行 terraform plan 生成执行计划,确认后执行 terraform apply 以创建或更新资源。状态文件存放在本地或远端后端,确保团队对同一状态的可见性和并发保护。你可以使用数据源获取外部信息、通过模块实现复用、借助工作区隔离环境,并利用命令如 terraform state、terraform import 等管理现有资源与状态。
When to Use It
- 在 AWS、Azure、GCP 等云环境中定义、部署和变更基础设施并实现可重复部署
- 需要与团队共享基础设施状态并锁定并发修改,采用远程后端和状态锁
- 希望把基础设施拆分为模块以实现可复用和版本化
- 需要在同一配置中管理开发、测试、生产等环境,或跨账户/区域部署
- 需要将现有资源纳入 IaC 流程并使用 Terraform 进行治理与持续交付
Quick Start
- 创建并配置 provider 与后端(如 AWS 与 S3/ DynamoDB 远端后端)
- 编写变量、资源和模块(如 VPC、子网、EC2)并运行 terraform init
- 执行 terraform plan -out=plan.tfplan 以查看将执行的变更
- 执行 terraform apply plan.tfplan 以应用变更并创建/更新资源
Best Practices
- 将后端配置为远端存储并启用锁(如 S3 + DynamoDB)以实现团队协作与并发保护
- 固定 provider 版本并使用具体版本号,避免意外升级
- 将基础设施拆分为模块,根模块保持简洁,利于复用与版本控制
- 对环境使用工作区(workspace)或变量进行区分,避免环境混淆
- 使用 terraform fmt + terraform validate 在合并前确保代码规范与正确性
- 把敏感信息和机密数据从代码中分离,使用外部化的证书和参数管理机制
Example Use Cases
- 场景 1:在 AWS 上通过 VPC、子网、互联网网关等资源搭建一个可用的网络架构,并部署一台 Web 服务器,输出 VPC ID、子网 ID、Web 服务器公有 IP 等。
- 场景 2:配置远端后端(如 S3 + DynamoDB 锁)以实现团队协作和状态一致性,并通过 terraform state 子命令进行状态查看、移动与导入。
- 场景 3:使用模块化的 VPC 模块(如 modules/vpc)在不同账户/区域复用基础网络组件,并通过远程模块引用实现版本化部署。
- 场景 4:将现有的云资源(如已存在的 EC2、RDS 等)通过 terraform import 纳入 Terraform 管理,以统一的 IaC 工作流进行后续变更。
- 场景 5:结合数据源获取最新的 Ubuntu AMI 与可用区信息,动态配置实例与子网,提升自动化部署的可靠性。
Frequently Asked Questions
Related Skills
precommit-setup
athola/claude-night-market
Configure three-layer pre-commit system with linting, type checking, and testing hooks. Use for quality gate setup and code standards. Skip if pre-commit is optimally configured.
error-patterns
athola/claude-night-market
'Standardized error handling patterns with classification, recovery,
risk-classification
athola/claude-night-market
'Inline risk classification for agent tasks using a 4-tier model. Hybrid
CI/CD Pipeline Security Expert
martinholovsky/claude-skills-generator
Expert in CI/CD pipeline design with focus on secret management, code signing, artifact security, and supply chain protection for desktop application builds
workflow-setup
athola/claude-night-market
Configure GitHub Actions CI/CD workflows for automated testing, linting, and deployment. Use for CI/CD setup and quality automation. Skip if CI/CD configured or using different platform.
circleci-automation
davepoon/buildwithclaude
Automate CircleCI tasks via Rube MCP (Composio): trigger pipelines, monitor workflows/jobs, retrieve artifacts and test metadata. Always search tools first for current schemas.