Terraform Coding Guidelines

AIに読ませるためのTerraform Coding Guidelinesを作った。人間が読んでもかまわない。

# Terraform Coding Guidelines

## 1. General Structure
- **Directory Layout**: Organize your Terraform code into logical directories for reusability and clarity. Follow the structure below to separate modules from environment-specific configurations:
- **Modules Directory (`/modules`)**: Use a `modules/` directory to store reusable components like compute, database, and network configurations. Each module should have its own directory and at least one `main.tf`, `variables.tf`, `output.tf`, `README.md`, `specification.md`, file.
- **Environment Directories**: Create separate directories for each environment (e.g., `development/`, `staging/`, `production/`). Each environment directory should contain:
    - **`backend.tf`**: Define backend configuration for storing Terraform state remotely.
    - **`main.tf`**: Specify the infrastructure for the environment, leveraging the reusable modules defined in `/modules`.
    - **`variables.tf`**: Define the variables that are specific to the environment.
    - **`specification.md`**: 
    - **`README.md`**: Provide a `README.md` file for each module and environment directory detailing its summary, usage.

- **Naming**: Use snake_case for both directory names and file names.

## 2. Naming Conventions
- **Principal**: Use full formal names instead of abbreviations. However, in cases where the abbreviation is a proper noun, such as an `id`, this restriction does not apply.
- **Resources**: Use a descriptive and standardized naming convention for resources. For example, `resource "aws_instance" "web_server" {}`. Do not use resource names that are redundant with the resource type, such as resource `"aws_instance" "ec2_instance" {}.`
- **Variables**: Use snake_case for variable names. For example, `variable "instance_type" {}`.
- **Outputs**: Use a consistent naming convention for outputs. For example, `output "vpc_id" {}`.

## 3. Code Formatting
- **Formatting**: Use `terraform fmt` to automatically format your code to the standard style.

## 4. Modules
- **Reusability**: Use modules to encapsulate reusable code. Each module should have a clear and well-documented purpose.
- **Input Variables**: Minimize hard-coded values. Use input variables to increase flexibility.
- **Outputs**: Define outputs for important values that other modules or configurations might need.

## 5. Variables and Outputs
- **Default Values**: Avoid default values.
- **Descriptions**: Provide meaningful descriptions for variables and outputs to improve code readability.
- **Sensitive Values**: Mark sensitive variables as `sensitive = true` to avoid accidental exposure of secrets.

## 6. State Management
- **Remote State**: Store Terraform state remotely using an `S3` backend.
- **State Files**: Never commit `.tfstate` files to version control.

## 7. Resource Tagging
- **Standard Tags**: Use a consistent tagging strategy across all resources, such as `Name`, `Environment`, and `Project`. Tags help in managing and identifying resources.
    - **Environment**: Add an `Environment` tag (e.g., `development`, `staging`, `production`) to distinguish between different deployments. However, personal testing environments should be named `experimental-[personal name]`. (e.g., `experimental-nakamura`)
    - **Project**: Specify the default project name.
    - **Name**: Specify as `[Environment]-[Project]([-Additional Information(Optional)]`. (e.g., `production-awesomeservice`, `staging-awesomeservice-api`)

## 8. Best Practices
- **Idempotency**: Write Terraform code that is idempotent. Re-running `terraform apply` should not introduce unintended changes.
- **Avoid Hard-Coding**: Use variables for values that are likely to change between environments or over time, such as AMI IDs, instance sizes, and VPC IDs.
- **Minimize Provider Configuration**: Use a centralized provider configuration whenever possible. Define the provider block at a common location rather than repeating it in multiple modules.
  
## 9. Error Handling and Validation
- **Validation Rules**: Use `validation` blocks, where necessary, to ensure variables meet specific requirements (e.g., `min_length`, `regex`).
- **Preconditions and Postconditions**: Use `precondition` and `postcondition` where applicable to maintain resource integrity.

## 10. Comments and Documentation
- **Commenting**: Add comments to describe non-intuitive code or decisions. However, avoid excessive comments that describe self-explanatory code.

## 11. Versioning
- **Provider Versions**: Specify provider versions explicitly to ensure consistent behavior across environments. Use version constraints like `= 3.0` to specify a strict version.
- **Terraform Version**: Specify the required Terraform version using `terraform { required_version = "= 1.9.6" }` to enforce a strict version.

## 12. Security
- **Secrets Management**: Avoid storing secrets in plaintext within Terraform code. Use secret management tools such as AWS Secrets Manager or environment variables.
- **IAM Policies**: Follow the principle of least privilege when defining IAM roles and policies. Only grant permissions that are necessary.

## 13. Testing and Validation
- **Linting**: Use tools like `tflint` to check for errors and enforce standards.
- **Validation**: Run `terraform validate` before committing code to catch syntax errors.
- **Plan Review**: Always review the output of `terraform plan` to verify changes before applying them.


ちなみに英語なのはChatGPTにドラフトを作ってもらったらなぜか英語で作成されたためだが、「まぁいいかトークン節約になるだろう」とそのままにしている。