Overview
Terraform enforces code style through automated checks that run on all pull requests. Following these guidelines ensures your contributions pass CI checks and maintain consistency with the codebase.Code Formatting
Go Format (gofmt)
All Go code must be formatted withgofmt.
Check Formatting
Apply Formatting
Import Organization (goimports)
Import statements must be organized withgoimports.
Check Imports
The imports check only applies to files changed relative to the
main branch, allowing gradual consistency improvements.Fix Import Organization
Import Grouping
Imports should be grouped in this order:- Standard library packages
- External packages
- Terraform internal packages
Static Analysis
go vet
Basic static analysis withgo vet:
staticcheck
Advanced static analysis with staticcheck:staticcheck Configuration
Terraform’s staticcheck configuration (staticcheck.conf) enables most checks but excludes:
- ST*: Style-related checks (Terraform intentionally breaks some conventions)
- SA1019: Deprecation warnings (updated locally during nearby changes)
- SA4003: Unsigned comparison checks (conflicts with generated code)
staticcheck.conf
The goal is finding issues that reduce code clarity or may result in bugs, not enforcing arbitrary style preferences.
Exhaustiveness Checking
Check that switch statements cover all enum cases:Copyright Headers
All source files must include proper copyright headers.Check Copyright Headers
Fix Copyright Headers
Copyright headers are automatically managed by the
copywrite tool. Don’t manually edit the SPDX headers.Naming Conventions
Packages
- Use short, lowercase names
- No underscores or mixed caps
- Avoid generic names like
utilorcommon
addrs, configs, command
Files
- Lowercase with underscores:
config_build.go - Test files:
config_build_test.go - Platform-specific:
file_unix.go,file_windows.go
Types and Functions
- Use MixedCaps (PascalCase) for exported names
- Use mixedCaps (camelCase) for unexported names
- Acronyms should be consistent:
HTTPServerorhttpServer, notHttpServer
Variables
- Short names for limited scope:
i,n,err - Descriptive names for larger scope:
resourceAddress,configBody - Avoid stuttering:
config.Bodynotconfig.ConfigBody
Code Organization
File Structure
Organize each file in this order:- Copyright header
- Package declaration
- Import statements
- Package documentation (on
packagestatement) - Type definitions
- Constants and variables
- Function implementations
Function Length
Keep functions focused and reasonably sized:- Prefer smaller, focused functions
- Extract complex logic into helper functions
- If a function is too long, consider breaking it up
Comments
Package Comments
Function Comments
Exported functions must have comments starting with the function name:Inline Comments
Use inline comments to explain “why”, not “what”:Error Handling
Error Messages
- Start with lowercase (errors are usually embedded in other messages)
- No trailing punctuation
- Be specific and actionable
Error Wrapping
Use%w for wrapping errors (Go 1.13+):
Testing Style
Test Function Names
Follow theTestXxx convention:
Table-Driven Tests
Prefer table-driven tests:Test Helpers
Prefix test helper functions withtest:
Generated Code
Some files are generated and should not be manually edited.Identify Generated Files
Generated files include a comment:Regenerate Code
Pre-Commit Checks
Run all checks before committing:CI Checks
Pull requests run these automated checks:- gofmt: Code formatting
- goimports: Import organization
- go vet: Basic static analysis
- staticcheck: Advanced static analysis
- copyright: Copyright header validation
- tests: Unit and acceptance tests
Editor Configuration
VS Code
Recommended settings for.vscode/settings.json:
GoLand
- Enable “gofmt” in Settings → Go → Fmt
- Enable “Optimize imports” in Settings → Tools → Actions on Save
- Install the staticcheck plugin
Best Practices
Next Steps
Pull Requests
Learn how to submit well-formatted PRs
Testing
Write tests that follow style guidelines
Building
Build Terraform to test your changes