mcpField
T
terraform-style-guide

terraform-style-guide

github.com/hashicorp云与 DevOps90912.7k 次安装今天更新
代码仓库

关于 terraform-style-guide

terraform-style-guide 是一项指导按 HashiCorp 规范生成和维护 Terraform 配置的技能,面向 Terraform 编写者,涵盖文件组织、格式、命名及验证和安全实践。

主要功能

  1. 01Terraform 标准文件布局
  2. 02格式与命名约定
  3. 03变量和输出要求
  4. 04资源创建指导
  5. 05版本与安全指导
  6. 06验证和审查清单

适用场景

  1. 01开始编写 Terraform 配置
  2. 02提交前审查 Terraform 代码
  3. 03统一资源和变量命名

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hashicorp/agent-skills --skill terraform-style-guide

安装后在 Claude Code 中输入/terraform-style-guide确认已加载。

附带文件SECURITY.md

详细介绍

Terraform 风格指南

按照 HashiCorp 的官方风格规范和最佳实践生成并维护 Terraform 代码。

参考: HashiCorp Terraform 风格指南

代码生成策略

生成 Terraform 代码时:

  1. 从提供商配置和版本约束开始
  2. 在依赖资源之前创建数据源
  3. 按依赖顺序构建资源
  4. 为关键资源属性添加输出
  5. 对所有可配置值使用变量

文件组织

文件用途
terraform.tfTerraform 和提供商的版本要求
providers.tf提供商配置
main.tf主要资源和数据源
variables.tf输入变量声明(按字母顺序排列)
outputs.tf输出值声明(按字母顺序排列)
locals.tf本地值声明
结构示例
# terraform.tf
terraform {
  required_version = ">= 1.14"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

# variables.tf
variable "environment" {
  description = "Target deployment environment"
  type        = string

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}

# locals.tf
locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "Terraform"
  }
}

# main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true

  tags = merge(local.common_tags, {
    Name = "${var.project_name}-${var.environment}-vpc"
  })
}

# outputs.tf
output "vpc_id" {
  description = "ID of the created VPC"
  value       = aws_vpc.main.id
}

代码格式

缩进和对齐
  • 每个嵌套层级使用 两个空格(不使用制表符)
  • 连续参数的等号应对齐
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = "subnet-12345678"

  tags = {
    Name        = "web-server"
    Environment = "production"
  }
}
块组织

参数应位于块之前,元参数应放在最前面:

resource "aws_instance" "example" {
  # Meta-arguments
  count = 3

  # Arguments
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  # Blocks
  root_block_device {
    volume_size = 20
  }

  # Lifecycle last
  lifecycle {
    create_before_destroy = true
  }
}

命名约定

  • 所有名称均使用 小写字母和下划线
  • 使用描述性名词,不包含资源类型
  • 名称应具体且有意义
  • 资源名称必须为单数,不得使用复数
  • 如果特定描述性名称多余或不可用,且只存在一个实例,则资源名称默认使用 main
# Bad
resource "aws_instance" "webAPI-aws-instance" {}
resource "aws_instance" "web_apis" {}
variable "name" {}

# Good
resource "aws_instance" "web_api" {}
resource "aws_vpc" "main" {}
variable "application_name" {}

变量

每个变量都必须包含 type 和 description:

variable "instance_type" {
  description = "EC2 instance type for the web server"
  type        = string
  default     = "t2.micro"

  validation {
    condition     = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_type)
    error_message = "Instance type must be t2.micro, t2.small, or t2.medium."
  }
}

variable "database_password" {
  description = "Password for the database admin user"
  type        = string
  sensitive   = true
}

输出

每个输出都必须包含 description:

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.web.id
}

output "database_password" {
  description = "Database administrator password"
  value       = aws_db_instance.main.password
  sensitive   = true
}

动态创建资源

优先使用 for_each,而非 count
# Bad - count for multiple resources
resource "aws_instance" "web" {
  count = var.instance_count
  tags  = { Name = "web-${count.index}" }
}

# Good - for_each with named instances
variable "instance_names" {
  type    = set(string)
  default = ["web-1", "web-2", "web-3"]
}

resource "aws_instance" "web" {
  for_each = var.instance_names
  tags     = { Name = each.key }
}
使用 count 进行条件创建
resource "aws_cloudwatch_metric_alarm" "cpu" {
  count = var.enable_monitoring ? 1 : 0

  alarm_name = "high-cpu-usage"
  threshold  = 80
}

安全最佳实践

请参阅 SECURITY.md,其中包含有关加密资源、防止敏感数据进入状态文件以及安全配置的指导。

版本锁定

terraform {
  required_version = ">= 1.14"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

除非依赖锁定文件或配置使用的其他模块另有要求,否则使用每个提供商的最新主版本,以及 Terraform 的最新次版本。

版本约束运算符:

  • = 1.0.0 - 精确版本
  • >= 1.0.0 - 大于或等于
  • ~> 1.0 - 允许最右侧的部分递增
  • >= 1.0, < 2.0 - 版本范围

提供商配置

provider "aws" {
  region = "us-west-2"

  default_tags {
    tags = {
      ManagedBy = "Terraform"
      Project   = var.project_name
    }
  }
}

# Aliased provider for multi-region
provider "aws" {
  alias  = "east"
  region = "us-east-1"
}

版本控制

切勿提交:

  • terraform.tfstate、terraform.tfstate.backup
  • .terraform/ 目录
  • *.tfplan
  • 包含敏感数据的 .tfvars 文件

务必提交:

  • 所有 .tf 配置文件
  • .terraform.lock.hcl(依赖锁定文件)

验证工具

提交前运行:

terraform fmt -recursive
terraform validate

其他工具:

  • tflint - 代码检查和最佳实践
  • checkov / tfsec - 安全扫描

代码审查清单

  • 使用 terraform fmt 格式化代码
  • 使用 terraform validate 验证配置
  • 按照标准结构组织文件
  • 所有变量均包含类型和描述
  • 所有输出均包含描述
  • 资源名称使用带下划线的描述性名词
  • 明确锁定版本约束
  • 使用 sensitive = true 标记敏感值
  • 不含硬编码的凭据或密钥
  • 应用了安全最佳实践

基于:HashiCorp Terraform 风格指南

评论

支持 Markdown