terraform-style-guide by hashicorp/agent-skills
npx skills add https://github.com/hashicorp/agent-skills --skill terraform-style-guide遵循 HashiCorp 官方风格约定和最佳实践来生成和维护 Terraform 代码。
生成 Terraform 代码时:
| 文件 | 用途 |
|---|---|
terraform.tf | Terraform 和提供程序版本要求 |
providers.tf | 提供程序配置 |
main.tf | 主要资源和数据源 |
variables.tf |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 输入变量声明(按字母顺序) |
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
}
}
main,前提是只存在一个实例# 错误示例
resource "aws_instance" "webAPI-aws-instance" {}
resource "aws_instance" "web_apis" {}
variable "name" {}
# 正确示例
resource "aws_instance" "web_api" {}
resource "aws_vpc" "main" {}
variable "application_name" {}
每个变量必须包含 type 和 description:
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
}
# 错误示例 - 使用 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 }
}
resource "aws_cloudwatch_metric_alarm" "cpu" {
count = var.enable_monitoring ? 1 : 0
alarm_name = "high-cpu-usage"
threshold = 80
}
生成代码时,应用安全加固:
sensitive = true 标记敏感输出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 标记每周安装量
2.1K
代码仓库
GitHub 星标数
477
首次出现
2026年1月26日
安全审计
安装于
opencode1.8K
github-copilot1.8K
codex1.7K
gemini-cli1.7K
amp1.5K
kimi-cli1.5K
Generate and maintain Terraform code following HashiCorp's official style conventions and best practices.
Reference: HashiCorp Terraform Style Guide
When generating Terraform code:
| File | Purpose |
|---|---|
terraform.tf | Terraform and provider version requirements |
providers.tf | Provider configurations |
main.tf | Primary resources and data sources |
variables.tf | Input variable declarations (alphabetical) |
outputs.tf | Output value declarations (alphabetical) |
locals.tf | Local value declarations |
# 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
}
Use two spaces per nesting level (no tabs)
Align equals signs for consecutive arguments
resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" subnet_id = "subnet-12345678"
tags = { Name = "web-server" Environment = "production" } }
Arguments precede blocks, with meta-arguments first:
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
}
}
Use lowercase with underscores for all names
Use descriptive nouns excluding the resource type
Be specific and meaningful
Resource names must be singular, not plural
Default to main for resources where a specific descriptive name is redundant or unavailable, provided only one instance exists
resource "aws_instance" "webAPI-aws-instance" {} resource "aws_instance" "web_apis" {} variable "name" {}
resource "aws_instance" "web_api" {} resource "aws_vpc" "main" {} variable "application_name" {}
Every variable must include type and 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
}
Every output must include 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
}
# 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 }
}
resource "aws_cloudwatch_metric_alarm" "cpu" {
count = var.enable_monitoring ? 1 : 0
alarm_name = "high-cpu-usage"
threshold = 80
}
When generating code, apply security hardening:
sensitive = trueresource "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
}
}
}
Version constraint operators:
= 1.0.0 - Exact version>= 1.0.0 - Greater than or equal~> 1.0 - Allow rightmost component to increment>= 1.0, < 2.0 - Version rangeprovider "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"
}
Never commit:
terraform.tfstate, terraform.tfstate.backup.terraform/ directory*.tfplan.tfvars files with sensitive dataAlways commit:
.tf configuration files.terraform.lock.hcl (dependency lock file)Run before committing:
terraform fmt -recursive
terraform validate
Additional tools:
tflint - Linting and best practicescheckov / tfsec - Security scanningterraform fmtterraform validatesensitive = trueBased on:HashiCorp Terraform Style Guide
Weekly Installs
2.1K
Repository
GitHub Stars
477
First Seen
Jan 26, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode1.8K
github-copilot1.8K
codex1.7K
gemini-cli1.7K
amp1.5K
kimi-cli1.5K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装