Top-level resources (if any)
terraforminfrastructure-as-codebest-practicessecuritycoding-standards
Description
This rule provides guidelines for Terraform best practices, coding standards, and security considerations to ensure maintainable, efficient, and secure infrastructure-as-code.
Globs
**/*.tf
---
description: This rule provides guidelines for Terraform best practices, coding standards, and security considerations to ensure maintainable, efficient, and secure infrastructure-as-code.
globs: **/*.tf
---
- **Use Remote State**: Store Terraform state files remotely to enable collaboration and prevent conflicts. Consider using Terraform Cloud, HashiCorp Consul, AWS S3 with DynamoDB locking, or Azure Storage Account with Blob Storage Locking.
- Properly configure access controls for your remote state backend to prevent unauthorized access.
- Implement versioning for state files to track changes and facilitate rollbacks.
- **Consistent Naming Conventions**: Adopt a consistent naming convention for resources, modules, and variables to improve readability and maintainability.
- Use nouns for resource names (e.g., `aws_instance.web_server` instead of `web_server_instance`).
- Include environment or project context in names (e.g., `dev_web_server` or `prod_db`).
- Follow a consistent casing style (e.g., snake_case or camelCase).
- **Modularity and Code Structure**: Organize Terraform code into modules to promote reusability and maintainability.
- Create modules for common infrastructure components (e.g., VPC, EC2 instance, database).
- Follow a standard module structure (e.g., `variables.tf`, `outputs.tf`, `main.tf`, `versions.tf`).
- Limit the use of custom scripts within modules; prefer Terraform resources and data sources.
- **Validation and Formatting**: Always validate and format Terraform code using `terraform fmt` and `terraform validate` to ensure quality and consistency.
- Integrate `terraform fmt` and `terraform validate` into your CI/CD pipeline.
- Use a linter such as TFLint to enforce organization-specific coding best practices.
- **Use Existing Shared and Community Modules**: Leverage pre-built modules from the Terraform Registry or other trusted sources to avoid reinventing the wheel.
- Thoroughly review modules before use to understand their functionality and security implications.
- Pin module versions to prevent unexpected changes.
- **Import Existing Infrastructure**: Use the `terraform import` command to bring existing infrastructure under Terraform management.
- Understand the limitations of `terraform import` and manually verify the imported configuration.
- **Avoid Hard-coding Variables**: Use variables to parameterize Terraform configurations and avoid hard-coding values.
- Define variables in `variables.tf` with appropriate descriptions, types, and default values.
- Use environment variables or Terraform Cloud variables to pass sensitive values.
- **Tag Resources**: Tag all Terraform resources with relevant metadata (e.g., `Name`, `Environment`, `Project`, `Owner`).
- Use consistent tagging conventions across your infrastructure.
- Leverage tags for cost allocation and resource management.
- **Introduce Policy as Code**: Implement policy as code using tools like HashiCorp Sentinel or Open Policy Agent (OPA) to enforce compliance and security policies.
- Define policies for resource configurations, naming conventions, and security settings.
- Integrate policy checks into your CI/CD pipeline.
- **Code Organization and Structure:**
- **Directory Structure Best Practices:** Organize your Terraform project with a clear directory structure. A common pattern:
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ec2/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ ├── prod/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
├── main.tf # Top-level resources (if any)
├── variables.tf # Global variables
└── outputs.tf # Global outputs
- **File Naming Conventions:** Adhere to consistent file naming. Use `main.tf` for the primary resource definitions, `variables.tf` for variables, `outputs.tf` for outputs, and `terraform.tfvars` for environment-specific variable values.
- **Module Organization:** Keep modules self-contained and reusable. Each module should have a specific purpose (e.g., creating a VPC, an EC2 instance, or a database).
- **Component Architecture:** Design your infrastructure as a collection of loosely coupled components (modules) that can be composed together.
- **Code Splitting Strategies:** Break down large configurations into smaller, more manageable modules and files.
- **Common Patterns and Anti-patterns:**
- **Design Patterns:**
- **Singleton Pattern:** Ensure only one instance of a critical resource exists (e.g., a VPC). Use `count = var.create_vpc ? 1 : 0` to conditionally create a single VPC.
- **Factory Pattern:** Use modules to create multiple instances of a resource with different configurations (e.g., multiple EC2 instances with different sizes and roles).
- **Facade Pattern:** Create a module that simplifies the creation of complex infrastructure by abstracting away the underlying details.
- **Recommended Approaches:**
- Use data sources to retrieve information about existing resources instead of hardcoding their IDs or names.
- Use dynamic blocks to create multiple resources or configure resource properties based on variable values.
- Use lifecycle rules to manage resource creation, modification, and deletion.
- **Anti-patterns:**
- **Hardcoding values:** Avoid hardcoding values in your Terraform configurations. Use variables instead.
- **Creating monolithic configurations:** Break down large configurations into smaller, more manageable modules.
- **Ignoring errors:** Always handle errors and provide meaningful error messages.
- **State Management Best Practices:**
- **Remote State:** Always use remote state to store Terraform state files.
- **State Locking:** Enable state locking to prevent concurrent modifications.
- **State Encryption:** Encrypt state files to protect sensitive data.
- **State Versioning:** Implement versioning for state files.
- **Error Handling Patterns:**
- Use the `try` and `can` functions to handle errors when retrieving data or evaluating expressions.
- Use `validation` blocks to validate variable values and prevent invalid configurations.
- Provide meaningful error messages to help users diagnose and fix issues.
- **Performance Considerations:**
- **Optimization Techniques:**
- Use the `count` and `for_each` meta-arguments to create multiple resources efficiently.
- Use data sources to retrieve information about existing resources instead of creating new ones.
- Use the `depends_on` meta-argument sparingly to avoid unnecessary dependencies.
- **Memory Management:**
- Be mindful of the memory usage of your Terraform configurations, especially when working with large datasets.
- Avoid creating large variables or outputs that can consume excessive memory.
- **Rendering Optimization:**
- Use efficient string interpolation techniques to avoid unnecessary string concatenation.
- Use the `templatefile` function to render complex templates efficiently.
- **Security Best Practices:**
- **Common Vulnerabilities:**
- **Hardcoded secrets:** Avoid hardcoding secrets in your Terraform configurations.
- **Publicly accessible resources:** Ensure that resources are not publicly accessible unless explicitly required.
- **Insufficient access controls:** Implement strict access controls to prevent unauthorized access to resources.
- **Input Validation:**
- Validate variable values to prevent invalid or malicious input.
- Use regular expressions to enforce specific input formats.
- **Authentication and Authorization Patterns:**
- Use IAM roles and policies to grant resources the necessary permissions.
- Use Terraform Cloud or other secrets management tools to manage sensitive credentials.
- **Data Protection Strategies:**
- Encrypt sensitive data at rest and in transit.
- Use encryption keys managed by a key management service (KMS).
- **Secure API Communication:**
- Use HTTPS for all API communication.
- Validate API responses to prevent data injection attacks.
- **Testing Approaches:**
- **Unit Testing Strategies:**
- Use `terraform show` and `terraform plan` to verify that your Terraform configurations create the expected resources.
- Use `terratest` or other testing frameworks to write automated unit tests.
- **Integration Testing:**
- Deploy your Terraform configurations to a test environment and verify that the resources are functioning correctly.
- Use automated testing tools to perform integration tests.
- **End-to-end Testing:**
- Simulate real-world scenarios and verify that your infrastructure can handle them.
- Use automated testing tools to perform end-to-end tests.
- **Test Organization:**
- Organize your tests into a clear directory structure.
- Use meaningful test names to describe the purpose of each test.
- **Mocking and Stubbing:**
- Use mocking and stubbing to isolate your tests and prevent dependencies on external resources.
- Use testing frameworks that support mocking and stubbing.
- **Common Pitfalls and Gotchas:**
- **Frequent Mistakes:**
- **Incorrect resource dependencies:** Ensure that resource dependencies are correctly defined.
- **Ignoring resource lifecycle:** Understand the lifecycle of Terraform resources and how they are created, modified, and deleted.
- **Using outdated Terraform versions:** Keep your Terraform version up to date to take advantage of new features and bug fixes.
- **Edge Cases:**
- **Handling resource conflicts:** Be prepared to handle resource conflicts that can occur when multiple Terraform configurations are applied simultaneously.
- **Managing resources with external dependencies:** Be aware of resources that have external dependencies (e.g., DNS records) and handle them appropriately.
- **Version-specific Issues:**
- Be aware of version-specific issues and compatibility concerns when upgrading Terraform or provider versions.
- Consult the Terraform and provider documentation for any breaking changes or migration guides.
- **Compatibility Concerns:**
- Ensure that your Terraform configurations are compatible with the target infrastructure environment.
- Use provider versions that are compatible with the Terraform version.
- **Debugging Strategies:**
- Use the `terraform plan` command to preview the changes that will be made to your infrastructure.
- Use the `terraform apply` command with the `-auto-approve` flag to apply changes automatically.
- Use the `terraform show` command to inspect the current state of your infrastructure.
- **Tooling and Environment:**
- **Recommended Development Tools:**
- **Terraform CLI:** The official Terraform command-line interface.
- **Terraform Cloud/Enterprise:** A collaboration and automation platform for Terraform.
- **IDE/Text Editor:** Visual Studio Code with the Terraform extension, Atom, or Sublime Text.
- **TFLint:** A linter for Terraform code.
- **Terratest:** A testing framework for Terraform code.
- **Build Configuration:**
- Use a consistent build configuration across all environments.
- Use environment variables or Terraform Cloud variables to configure the build environment.
- **Linting and Formatting:**
- Integrate linting and formatting into your CI/CD pipeline.
- Use `terraform fmt` and TFLint to ensure code quality and consistency.
- **Deployment Best Practices:**
- Use a CI/CD pipeline to automate Terraform deployments.
- Use version control to track changes to your Terraform configurations.
- Use infrastructure-as-code principles to manage your infrastructure.
- **CI/CD Integration:**
- Integrate Terraform into your CI/CD pipeline using tools like Jenkins, GitLab CI, or GitHub Actions.
- Automate the execution of `terraform plan` and `terraform apply` commands.
- Implement automated testing and validation as part of the CI/CD process.