Terraform代码风格检查Skill terraform-style-check

这个技能用于生成和维护遵循 HashiCorp 官方风格约定和最佳实践的 Terraform HCL 代码,适用于编写、审核或生成标准化基础设施配置,提高代码质量和可维护性。关键词包括:Terraform、HCL、代码风格、最佳实践、DevOps、基础设施即代码、自动化、安全加固、版本控制、云原生。

DevOps 0 次安装 0 次浏览 更新于 3/15/2026

名称: terraform-风格检查 描述: 遵循 HashiCorp 官方风格约定和最佳实践生成 Terraform HCL 代码。适用于编写、审核或生成 Terraform 配置时使用。 许可证: MIT

Terraform 风格指南

遵循 HashiCorp 官方风格约定和最佳实践生成和维护 Terraform 代码。

参考: HashiCorp Terraform 风格指南

代码生成策略

当生成 Terraform 代码时:

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

文件组织

文件 用途
terraform.tf Terraform 和提供者版本要求
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 = "目标部署环境"
  type        = string

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "环境必须是 dev、staging 或 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 = "创建的 VPC 的 ID"
  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" {
  # 元参数
  count = 3

  # 参数
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  # 块
  root_block_device {
    volume_size = 20
  }

  # 生命周期最后
  lifecycle {
    create_before_destroy = true
  }
}

命名约定

  • 对所有名称使用 小写下划线
  • 使用 描述性名词,排除资源类型
  • 具体且有意义的命名
# 差
resource "aws_instance" "webAPI-aws-instance" {}
variable "name" {}

# 好
resource "aws_instance" "web_api" {}
variable "application_name" {}

变量

每个变量必须包含 typedescription

variable "instance_type" {
  description = "Web 服务器的 EC2 实例类型"
  type        = string
  default     = "t2.micro"

  validation {
    condition     = contains(["t2.micro", "t2.small", "t2.medium"], var.instance_type)
    error_message = "实例类型必须是 t2.micro、t2.small 或 t2.medium。"
  }
}

variable "database_password" {
  description = "数据库管理员用户的密码"
  type        = string
  sensitive   = true
}

输出

每个输出必须包含 description

output "instance_id" {
  description = "EC2 实例的 ID"
  value       = aws_instance.web.id
}

output "database_password" {
  description = "数据库管理员密码"
  value       = aws_db_instance.main.password
  sensitive   = true
}

动态资源创建

优先使用 for_each 而非 count

# 差 - 使用 count 用于多个资源
resource "aws_instance" "web" {
  count = var.instance_count
  tags  = { Name = "web-${count.index}" }
}

# 好 - 使用 for_each 并命名实例
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 = "高 CPU 使用率"
  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"  # 允许次要更新
    }
  }
}

版本约束运算符:

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

# 多区域别名提供者
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 风格指南