install
source · Clone the upstream repo
git clone https://github.com/chaterm/terminal-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/chaterm/terminal-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/devops/terraform" ~/.claude/skills/chaterm-terminal-skills-terraform && rm -rf "$T"
manifest:
devops/terraform/SKILL.mdsource content
Terraform 基础设施即代码
概述
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] }
故障排查
| 问题 | 排查方法 |
|---|---|
| 状态锁定 | |
| Provider 错误 | |
| 状态不一致 | |
| 循环依赖 | 检查 |
# 调试模式 TF_LOG=DEBUG terraform plan # 查看详细计划 terraform plan -out=plan.tfplan terraform show -json plan.tfplan | jq # 验证配置 terraform validate