File extensions and naming conventions
Use the standard Terraform file extensions so tooling (IDEs, linters, formatters, CI) recognizes your configuration automatically.| File type | Purpose | Example |
|---|---|---|
.tf | Primary Terraform configuration (HCL) | main.tf, network.tf |
.tfvars | Variable definition files for environment-specific values | dev.tfvars, prod.tfvars |
.tf.json | JSON equivalent of Terraform configuration (less common) | main.tf.json |
.tfvars.json | JSON variable definitions | dev.tfvars.json |
.tf / HCL) ensures consistent editor support, syntax highlighting, and integration with tools like terraform fmt.
Formatting
Consistent formatting improves readability and reduces merge conflicts. Use Terraform’s canonical formatter:- Run
terraform fmtlocally or in CI to apply HashiCorp’s style automatically. - Configure your editor to format on save or add a pre-commit hook.
- Include formatting in CI so all contributors adhere to the same style.
Organizing files and modules
Organize your repository by logical responsibility to make it easier to find and change configuration as it grows. Recommended file layout:| Purpose | Suggested filenames |
|---|---|
| Variables | variables.tf |
| Outputs | outputs.tf |
| Networking resources | network.tf or module modules/network |
| Compute / instances | compute.tf |
| Provider and backend config | providers.tf, backend.tf |
| Readme / usage | README.md |
Documentation and README
Good documentation prevents recurring questions and reduces onboarding time.- Add concise comments for non-obvious decisions in HCL using
#or//. - Maintain a
README.mdin the root and in each module that documents:- Purpose and scope
- Required and optional inputs
- Outputs
- Example usage
- Include usage examples and minimal
terraform init/applyinstructions.

Avoid hard-coded values and secrets
Hard-coding environment-specific values or secrets directly in HCL reduces portability and introduces security risk. Use the recommended alternatives:- Use input variables declared in
variables.tffor values that change between environments. - Supply environment-specific values via
.tfvarsfiles or environment variables (e.g.,TF_VAR_*). - Store secrets in a secure secrets manager (Vault, AWS Secrets Manager, Azure Key Vault) and reference them at runtime rather than embedding them in code.
Never commit plaintext secrets to version control. Use a secrets manager or CI secret storage and reference values via environment variables or secure provider integrations.
- variables.tf
- Use a
prod.tfvars(not committed to git) or setTF_VAR_db_passwordin CI.
Tools to help you write better HCL
Combine editor extensions, formatters, and linters for a robust workflow:- Editor/IDE extensions: real-time syntax checks, autocompletion, and schema validation (e.g., Terraform extension for VS Code).
terraform fmt: enforce consistent formatting across the repository.- Linters and static analysis: tools like
tflint,checkov, orterraform validatehelp catch misconfigurations and policy violations. - Pre-commit hooks and CI: run formatters, linters, and
terraform planvalidations as part of CI to prevent regressions.
Use editor extensions to catch syntax errors and style issues as you type, and run
terraform fmt and linters in CI to ensure consistent formatting and policy checks across the team.Links and references
- Terraform CLI documentation: https://www.terraform.io/cli
- Terraform best practices: https://www.terraform.io/guides
- TFLint: https://github.com/terraform-linters/tflint
- Checkov: https://www.checkov.io/