mcpField
T
terraform-style-guide

terraform-style-guide

github.com/pedronauck云与 DevOps647185 次安装1 周前更新
代码仓库

关于 terraform-style-guide

为编写和维护 Terraform 配置提供遵循 HashiCorp 风格指南的规范,面向基础设施代码作者。涵盖文件组织、命名、格式、变量与输出,以及安全和版本约束。

主要功能

  1. 01Terraform 文件组织建议
  2. 02代码缩进与参数排序规范
  3. 03资源、变量和输出命名规则
  4. 04变量与输出文档要求
  5. 05安全配置与版本约束建议
  6. 06提交前验证清单

适用场景

  1. 01按统一结构创建 Terraform 配置
  2. 02检查变量和输出是否完整描述
  3. 03在生成配置时应用安全实践
  4. 04提交前格式化并验证 Terraform 代码

安装

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

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

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

详细介绍

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.7"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.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
}

安全最佳实践

生成代码时,请应用安全强化措施:

  • 默认启用静态加密
  • 在适用情况下配置私有网络
  • 对安全组应用最小权限原则
  • 启用日志记录和监控
  • 切勿硬编码凭据或机密
  • 使用 sensitive = true 标记敏感输出
示例:安全的 S3 存储桶
resource "aws_s3_bucket" "data" {
  bucket = "${var.project}-${var.environment}-data"
  tags   = local.common_tags
}

resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.data.id

  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
  bucket = aws_s3_bucket.data.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.s3.arn
    }
  }
}

resource "aws_s3_bucket_public_access_block" "data" {
  bucket = aws_s3_bucket.data.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

版本固定

terraform {
  required_version = ">= 1.7"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"  # Allow minor updates
    }
  }
}

版本约束运算符:

  • = 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