|
| 1 | +# AI Agents Guidelines for OpenTofu Module Development |
| 2 | + |
| 3 | +This document provides shared guidelines for AI agents working on OpenTofu modules to ensure consistency, clarity, and alignment with best practices. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +When working on OpenTofu modules, AI agents should optimize modules, outputs, variables, and file structures according to the specifications outlined in this document. The goal is to maintain consistency across all OpenTofu configurations while following established best practices. |
| 8 | + |
| 9 | +## Key Principles |
| 10 | + |
| 11 | +1. **Consistency**: Maintain uniform naming conventions and structures across all modules |
| 12 | +2. **Clarity**: Ensure code is readable and well-documented |
| 13 | +3. **Best Practices**: Follow OpenTofu and Terraform community standards |
| 14 | +4. **Retrocompatibility**: Preserve backward compatibility when making changes |
| 15 | + |
| 16 | +## Shared Implementation Guidelines |
| 17 | + |
| 18 | +### 1. Output Management |
| 19 | + |
| 20 | +Replace module and resource output names consistently: |
| 21 | +- Use `id` instead of `app_service_id` |
| 22 | +- Use `name` instead of `app_service_name` |
| 23 | + |
| 24 | +Add a global resource output for the main resource in every module: |
| 25 | +```terraform |
| 26 | +output "resource" { |
| 27 | + value = [RESOURCE_TYPE].main |
| 28 | +} |
| 29 | +``` |
| 30 | + |
| 31 | +Ensure outputs are added for all resources and modules referred within each module: |
| 32 | +```terraform |
| 33 | +output "module_service_plan" { |
| 34 | + value = module.service_plan |
| 35 | +} |
| 36 | +output "resource_application_insights" { |
| 37 | + value = azurerm_application_insights.main |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +### 2. Resource Naming |
| 42 | + |
| 43 | +Rename the main resource of each module to "main" for consistent reference: |
| 44 | +```terraform |
| 45 | +resource "azurerm_service_plan" "main" {} |
| 46 | +``` |
| 47 | + |
| 48 | +Add the `moved` block for retrocompatibility: |
| 49 | +```terraform |
| 50 | +moved { |
| 51 | + from = azurerm_service_plan.old_resource_name |
| 52 | + to = azurerm_service_plan.main |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +### 3. Variable Standards |
| 57 | + |
| 58 | +- Update variable descriptions to include clear punctuation (add dots at the end of sentences) |
| 59 | +- Use Markdown links consistently within descriptions `[text](http://example_url)` |
| 60 | +- Update variable naming for clarity and consistency (e.g., change `custom_diagnostic_settings_name` to `diagnostic_settings_custom_name`) |
| 61 | +- Ensure `lookup()` includes a default value: |
| 62 | + ```terraform |
| 63 | + lookup("parameter_name", var.parameter, "default_value") |
| 64 | + ``` |
| 65 | +- Avoid using `lookup` for typed variables |
| 66 | + |
| 67 | +### 4. File Organization Standards |
| 68 | + |
| 69 | +Use standardized naming conventions for files: |
| 70 | +- Data sources: [`d-naming.tf`](d-naming.tf) for specific naming datasources and `data-sources.tf` for grouped datasources |
| 71 | +- Resources: For example, `r-app-service.tf` for specific resources like `azurerm_app_service` |
| 72 | +- Module calls: [`m-logs.tf`](m-logs.tf) for example for logs diagnostic settings module, `m-` prefix for others module calls |
| 73 | +- Split providers constrains into a dedicated [`providers.tf`](providers.tf) file |
| 74 | +- Split inputs in `variables-xx.tf` files and outputs in `outputs-xx.tf` files, where `xx` is a specific category (e.g., `variables-logs.tf`, `outputs-resources.tf`) |
| 75 | + |
| 76 | +### 5. Documentation Requirements |
| 77 | + |
| 78 | +- Add a table for OpenTofu versions, including version 8.x.x |
| 79 | +- Include a warning about modules not being verified for Terraform versions >= 1.3 |
| 80 | +- Add notes to indicate optimization for OpenTofu versions >= 1.8 |
| 81 | +- Light rework of examples: |
| 82 | + - Provide examples in [`base.tf`](examples/main/base.tf) (used for initialization/validation/plan) but exclude detailed examples from README |
| 83 | +- Align README content with updated module names, outputs, and conventions |
| 84 | +- Use the `terraform-docs` tool for generating documentation and ensure it is up-to-date with the latest module structure and outputs |
| 85 | + |
| 86 | +### 6. Control Flow Best Practices |
| 87 | + |
| 88 | +Ensure IDs in keys are avoided; use fixed strings or clearly defined keys. |
| 89 | + |
| 90 | +Use `count` for conditional/boolean operations: |
| 91 | +```terraform |
| 92 | +resource "my_resource" { |
| 93 | + count = var.resource_enabled ? 1 : 0 |
| 94 | + ... |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +Avoid the use of generated values (like resource's id) in `count` or `for_each`. Replace with an object-wrapping approach: |
| 99 | +```terraform |
| 100 | +variable "resource" { type = object({ id = string }) } |
| 101 | +resource "my_other_resource" { |
| 102 | + count = var.resource == null ? 1 : 0 |
| 103 | + attr_id = var.resource.id |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +### 7. Version Management |
| 108 | + |
| 109 | +- Enforce Terraform version constraints >= 1.3 in [`versions.tf`](versions.tf) |
| 110 | +- Require OpenTofu >= 1.8 in CI/CD configurations |
| 111 | +- Update both `.gitlab-ci.yml` and `providers.tf` to reflect AzureRM provider version constraints |
| 112 | + |
| 113 | +### 8. Miscellaneous Updates |
| 114 | + |
| 115 | +- Fork and use Claranet's "azurecaf naming" provider for naming conventions |
| 116 | +- Avoid "unknown values" comparison issues using non-null wrappers for input-generated values |
| 117 | + |
| 118 | +**Do not use:** |
| 119 | +```terraform |
| 120 | +variable "resource_id" {} |
| 121 | +resource "my_other_resource" { |
| 122 | + count = var.resource_id == null ? 1 : 0 |
| 123 | + ... |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +**Instead, wrap into objects:** |
| 128 | +```terraform |
| 129 | +variable "resource" { type = object({ id = string }) } |
| 130 | +resource "my_other_resource" { |
| 131 | + count = var.resource == null ? 1 : 0 |
| 132 | + attr_id = var.resource.id |
| 133 | +} |
| 134 | +``` |
| 135 | + |
| 136 | +## Example Transformation |
| 137 | + |
| 138 | +**Before (Input):** |
| 139 | +```terraform |
| 140 | +output "app_service_id" { |
| 141 | + value = azurerm_app_service.main.id |
| 142 | +} |
| 143 | +
|
| 144 | +output "app_service_name" { |
| 145 | + value = azurerm_app_service.main.name |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +**After (Transformed Output):** |
| 150 | +```terraform |
| 151 | +output "id" { |
| 152 | + value = azurerm_app_service.main.id |
| 153 | +} |
| 154 | +
|
| 155 | +output "name" { |
| 156 | + value = azurerm_app_service.main.name |
| 157 | +} |
| 158 | +
|
| 159 | +output "resource" { |
| 160 | + value = azurerm_app_service.main |
| 161 | +} |
| 162 | +
|
| 163 | +output "module_service_plan" { |
| 164 | + value = module.service_plan |
| 165 | +} |
| 166 | +
|
| 167 | +output "resource_application_insights" { |
| 168 | + value = azurerm_application_insights.main |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +## Git Contribution Guidelines |
| 173 | + |
| 174 | +All AI agents must follow these git contribution standards when working on OpenTofu modules: |
| 175 | + |
| 176 | +### Branch Management |
| 177 | +- **Create a new branch** for each contribution |
| 178 | +- **Use prefixed branch names** based on the type of change: |
| 179 | + - `feat/add_new_param` - for new features or parameters |
| 180 | + - `fix/change_attribute` - for bug fixes or corrections |
| 181 | + - `docs/update_readme` - for documentation updates |
| 182 | + - `refactor/rename_variables` - for code refactoring |
| 183 | + - `chore/update_dependencies` - for maintenance tasks |
| 184 | + |
| 185 | +### Commit Standards |
| 186 | +- **Follow conventional commits structure**: `type(scope): description` |
| 187 | +- **Optional unicode emojis** are allowed for better readability |
| 188 | +- **Examples**: |
| 189 | + - `feat(outputs): ✨ add global resource output` |
| 190 | + - `fix(variables): 🐛 correct lookup default value` |
| 191 | + - `docs(readme): 📝 update version compatibility table` |
| 192 | + - `refactor(resources): ♻️ rename main resource with moved block` |
| 193 | + |
| 194 | +### Development Environment |
| 195 | +- **Install and update tools** using mise-en-place: `mise install` |
| 196 | +- **Keep tools up-to-date** before starting work |
| 197 | +- **Verify tool versions** match project requirements in [`.tool-versions`](.tool-versions) |
| 198 | + |
| 199 | +### Code Quality Assurance |
| 200 | +- **Install pre-commit hooks**: `pre-commit install` |
| 201 | +- **Pre-commit must trigger** on each commit to ensure validity of changes |
| 202 | +- **All pre-commit checks must pass** before pushing changes |
| 203 | +- **Address any pre-commit failures** immediately |
| 204 | + |
| 205 | +### Review Process |
| 206 | +- **Open a merge request** when changes are ready for review |
| 207 | +- **Provide clear description** of changes and their impact |
| 208 | +- **Reference related issues** or requirements |
| 209 | +- **Ensure all CI/CD checks pass** before requesting review |
| 210 | +- **Address review feedback** promptly and thoroughly |
| 211 | + |
| 212 | +## AI Agent Responsibilities |
| 213 | + |
| 214 | +When working on OpenTofu modules, AI agents should: |
| 215 | + |
| 216 | +1. **Analyze** existing code structure and identify areas for improvement |
| 217 | +2. **Apply** the standardized naming conventions and file structures |
| 218 | +3. **Update** outputs, variables, and documentation according to guidelines |
| 219 | +4. **Validate** configurations against best practices |
| 220 | +5. **Ensure** retrocompatibility through appropriate migration strategies |
| 221 | +6. **Follow** git contribution guidelines for all changes |
| 222 | +7. **Document** changes and maintain clear commit messages |
| 223 | + |
| 224 | +## Quality Assurance |
| 225 | + |
| 226 | +- Validate all examples and configurations against updated specifications |
| 227 | +- Ensure consistency across all documentation files |
| 228 | +- Test variable naming conventions and OpenTofu configurations |
| 229 | +- Verify that all changes maintain backward compatibility |
| 230 | +- Confirm all pre-commit checks pass |
| 231 | +- Ensure proper git workflow is followed |
| 232 | + |
| 233 | +## Notes for AI Agents |
| 234 | + |
| 235 | +- Focus on alignment with best practices for readability |
| 236 | +- Avoid introducing unnecessary complexity |
| 237 | +- Carefully validate examples against specifications |
| 238 | +- Maintain consistency across all files and configurations |
| 239 | +- Always include retrocompatibility measures when making breaking changes |
| 240 | +- Follow git contribution guidelines for proper version control |
0 commit comments