|
| 1 | +# Contributing to terraform-azurerm-naming |
| 2 | + |
| 3 | +Thank you for your interest in contributing to this project! This guide will help you understand how the project works and how to contribute effectively. |
| 4 | + |
| 5 | +## Table of Contents |
| 6 | + |
| 7 | +- [Prerequisites](#prerequisites) |
| 8 | +- [Project Structure](#project-structure) |
| 9 | +- [How Code Generation Works](#how-code-generation-works) |
| 10 | +- [Adding a New Azure Resource](#adding-a-new-azure-resource) |
| 11 | +- [Running Locally](#running-locally) |
| 12 | +- [Pull Request Guidelines](#pull-request-guidelines) |
| 13 | +- [Getting Help](#getting-help) |
| 14 | + |
| 15 | +## Prerequisites |
| 16 | + |
| 17 | +Before contributing, ensure you have the following installed: |
| 18 | + |
| 19 | +| Tool | Version | Purpose | |
| 20 | +|------|---------|---------| |
| 21 | +| [Go](https://golang.org/dl/) | 1.23+ | Runs the code generator | |
| 22 | +| [Terraform](https://www.terraform.io/downloads) | 1.0+ | Validates generated files | |
| 23 | +| [Make](https://www.gnu.org/software/make/) | Any | Build automation (Linux/macOS) | |
| 24 | +| [tflint](https://github.com/terraform-linters/tflint) | Latest | Terraform linting | |
| 25 | + |
| 26 | +**Optional but recommended:** |
| 27 | +- [pre-commit](https://pre-commit.com/) - Automatically runs formatting checks before commits |
| 28 | + |
| 29 | +### Quick Setup |
| 30 | + |
| 31 | +```bash |
| 32 | +# Clone the repository |
| 33 | +git clone https://github.com/Azure/terraform-azurerm-naming.git |
| 34 | +cd terraform-azurerm-naming |
| 35 | + |
| 36 | +# Install dependencies (installs terraform, terraform-docs, tfsec, tflint via Go) |
| 37 | +make install |
| 38 | + |
| 39 | +# Optional: Set up pre-commit hooks |
| 40 | +pip install pre-commit |
| 41 | +pre-commit install |
| 42 | +``` |
| 43 | + |
| 44 | +## Project Structure |
| 45 | + |
| 46 | +``` |
| 47 | +terraform-azurerm-naming/ |
| 48 | +├── main.go # Go generator - reads JSON, outputs Terraform |
| 49 | +├── resourceDefinition.json # Primary resource definitions (documented in Azure) |
| 50 | +├── resourceDefinition_out_of_docs.json # Resources not in official Azure docs |
| 51 | +├── templates/ |
| 52 | +│ ├── main.tmpl # Template for main.tf generation |
| 53 | +│ └── outputs.tmpl # Template for outputs.tf generation |
| 54 | +├── main.tf # [GENERATED] - Do not edit manually |
| 55 | +├── outputs.tf # [GENERATED] - Do not edit manually |
| 56 | +├── variables.tf # Module input variables (manually maintained) |
| 57 | +├── Makefile # Build automation for Linux/macOS |
| 58 | +└── docs/ |
| 59 | + ├── missing_resources.md # Resources that need to be added |
| 60 | + └── not_defined.md # Resources without naming documentation |
| 61 | +``` |
| 62 | + |
| 63 | +### Source Files vs Generated Files |
| 64 | + |
| 65 | +| File | Type | Edit? | |
| 66 | +|------|------|-------| |
| 67 | +| `resourceDefinition.json` | Source | Yes | |
| 68 | +| `resourceDefinition_out_of_docs.json` | Source | Yes | |
| 69 | +| `templates/*.tmpl` | Source | Yes | |
| 70 | +| `main.go` | Source | Yes | |
| 71 | +| `variables.tf` | Source | Yes | |
| 72 | +| `main.tf` | **Generated** | No | |
| 73 | +| `outputs.tf` | **Generated** | No | |
| 74 | + |
| 75 | +## How Code Generation Works |
| 76 | + |
| 77 | +The project uses a Go-based code generator that transforms JSON resource definitions into Terraform code: |
| 78 | + |
| 79 | +``` |
| 80 | +┌─────────────────────────────────┐ |
| 81 | +│ resourceDefinition.json │──┐ |
| 82 | +│ (documented resources) │ │ |
| 83 | +└─────────────────────────────────┘ │ |
| 84 | + ▼ |
| 85 | +┌─────────────────────────────────┐ │ ┌────────────┐ ┌─────────────┐ |
| 86 | +│ resourceDefinition_out_of_docs │──┴──▶│ main.go │──▶│ main.tf │ |
| 87 | +│ (undocumented resources) │ │ (generator)│ │ outputs.tf │ |
| 88 | +└─────────────────────────────────┘ └────────────┘ └─────────────┘ |
| 89 | + ▲ |
| 90 | + │ |
| 91 | + ┌──────────┴──────────┐ |
| 92 | + │ templates/main.tmpl │ |
| 93 | + │ templates/outputs.tmpl│ |
| 94 | + └─────────────────────┘ |
| 95 | +``` |
| 96 | + |
| 97 | +**Process:** |
| 98 | +1. `main.go` reads both JSON definition files |
| 99 | +2. Merges and sorts all resources alphabetically |
| 100 | +3. Applies Go templates to generate Terraform locals and outputs |
| 101 | +4. Writes `main.tf` and `outputs.tf` |
| 102 | + |
| 103 | +## Adding a New Azure Resource |
| 104 | + |
| 105 | +### Step 1: Find the Naming Rules |
| 106 | + |
| 107 | +Look up the resource's naming rules in the [Azure naming rules documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules). |
| 108 | + |
| 109 | +### Step 2: Choose the Right JSON File |
| 110 | + |
| 111 | +- **`resourceDefinition.json`** - Use for resources documented in Microsoft's official naming rules |
| 112 | +- **`resourceDefinition_out_of_docs.json`** - Use for resources not in official documentation |
| 113 | + |
| 114 | +### Step 3: Add the Resource Definition |
| 115 | + |
| 116 | +Add a new entry to the appropriate JSON file: |
| 117 | + |
| 118 | +```json |
| 119 | +{ |
| 120 | + "name": "my_new_resource", |
| 121 | + "length": { |
| 122 | + "min": 1, |
| 123 | + "max": 80 |
| 124 | + }, |
| 125 | + "regex": "^[a-zA-Z0-9-]+$", |
| 126 | + "scope": "resourceGroup", |
| 127 | + "slug": "mnr", |
| 128 | + "dashes": true |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +#### Field Reference |
| 133 | + |
| 134 | +| Field | Type | Required | Description | |
| 135 | +|-------|------|----------|-------------| |
| 136 | +| `name` | string | Yes | Resource name matching Terraform provider (e.g., `storage_account` for `azurerm_storage_account`) | |
| 137 | +| `length.min` | integer | Yes | Minimum character length allowed | |
| 138 | +| `length.max` | integer | Yes | Maximum character length allowed | |
| 139 | +| `regex` | string | Yes | Regex pattern for valid names (note: Terraform doesn't support all regex features) | |
| 140 | +| `scope` | string | Yes | Uniqueness scope: `global`, `subscription`, `resourceGroup`, or `parent` | |
| 141 | +| `slug` | string | Yes | Short abbreviation used in generated names (e.g., `st` for storage, `rg` for resource group) | |
| 142 | +| `dashes` | boolean | Yes | Whether the resource name supports dashes/hyphens | |
| 143 | + |
| 144 | +#### Scope Values |
| 145 | + |
| 146 | +| Scope | Meaning | |
| 147 | +|-------|---------| |
| 148 | +| `global` | Name must be globally unique across all Azure (e.g., storage accounts) | |
| 149 | +| `subscription` | Name must be unique within the subscription | |
| 150 | +| `resourceGroup` | Name must be unique within the resource group | |
| 151 | +| `parent` | Name must be unique within the parent resource | |
| 152 | + |
| 153 | +### Step 4: Generate and Validate |
| 154 | + |
| 155 | +```bash |
| 156 | +# Regenerate main.tf and outputs.tf |
| 157 | +make generate |
| 158 | + |
| 159 | +# Format and validate |
| 160 | +make format |
| 161 | +make validate |
| 162 | + |
| 163 | +# Or run all steps at once |
| 164 | +make all |
| 165 | +``` |
| 166 | + |
| 167 | +### Step 5: Verify Your Changes |
| 168 | + |
| 169 | +Check that: |
| 170 | +- Your resource appears in `main.tf` under the `locals.az` block |
| 171 | +- Your resource has a corresponding output in `outputs.tf` |
| 172 | +- `terraform validate` passes |
| 173 | +- `terraform fmt -check` passes |
| 174 | + |
| 175 | +## Running Locally |
| 176 | + |
| 177 | +### Using Make (Linux/macOS) |
| 178 | + |
| 179 | +```bash |
| 180 | +# Full build: install deps, generate, format, validate |
| 181 | +make all |
| 182 | + |
| 183 | +# Individual targets |
| 184 | +make install # Install required tools |
| 185 | +make generate # Run Go generator |
| 186 | +make format # Run terraform fmt |
| 187 | +make validate # Run fmt check, validate, and tflint |
| 188 | +make build # install + generate |
| 189 | +``` |
| 190 | + |
| 191 | +### Manual Commands |
| 192 | + |
| 193 | +```bash |
| 194 | +# Generate Terraform files |
| 195 | +go run main.go |
| 196 | + |
| 197 | +# Format Terraform files |
| 198 | +terraform fmt |
| 199 | + |
| 200 | +# Validate Terraform |
| 201 | +terraform init |
| 202 | +terraform validate |
| 203 | +``` |
| 204 | + |
| 205 | +## Pull Request Guidelines |
| 206 | + |
| 207 | +### Before Submitting |
| 208 | + |
| 209 | +1. **Run the full validation suite:** |
| 210 | + ```bash |
| 211 | + make all |
| 212 | + ``` |
| 213 | + |
| 214 | +2. **Ensure generated files are committed:** |
| 215 | + - After running `make generate`, commit both `main.tf` and `outputs.tf` |
| 216 | + - These files should always reflect the current JSON definitions |
| 217 | + |
| 218 | +3. **Format your code:** |
| 219 | + - Go code: `go fmt main.go` |
| 220 | + - Terraform: `terraform fmt` |
| 221 | + - JSON: Ensure proper formatting |
| 222 | + |
| 223 | +4. **Test your changes:** |
| 224 | + - Run `terraform validate` to ensure the generated code is valid |
| 225 | + - Manually verify your resource output if possible |
| 226 | + |
| 227 | +### PR Checklist |
| 228 | + |
| 229 | +- [ ] I've read the [Code of Conduct](CODE_OF_CONDUCT.md) |
| 230 | +- [ ] I've run `make all` (or equivalent) successfully |
| 231 | +- [ ] Generated files (`main.tf`, `outputs.tf`) are included in my commit |
| 232 | +- [ ] For new resources: I've added to the correct JSON file (`resourceDefinition.json` or `resourceDefinition_out_of_docs.json`) |
| 233 | +- [ ] For new resources: I've verified the naming rules from [Azure documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules) |
| 234 | +- [ ] My changes don't break existing functionality |
| 235 | + |
| 236 | +### Commit Message Format |
| 237 | + |
| 238 | +Use clear, descriptive commit messages: |
| 239 | + |
| 240 | +``` |
| 241 | +feat: add support for azure_container_app resource |
| 242 | +fix: correct regex pattern for storage_account |
| 243 | +docs: update contributing guidelines |
| 244 | +refactor: improve template generation logic |
| 245 | +``` |
| 246 | + |
| 247 | +### What Happens After Submission |
| 248 | + |
| 249 | +1. GitHub Actions runs `terraform fmt -check`, `terraform init`, and `terraform validate` |
| 250 | +2. A CLA bot checks if you've signed the Contributor License Agreement |
| 251 | +3. Maintainers review your changes |
| 252 | +4. Once approved, your PR will be merged |
| 253 | + |
| 254 | +## Getting Help |
| 255 | + |
| 256 | +- **Questions about existing resources?** Check [docs/missing_resources.md](docs/missing_resources.md) |
| 257 | +- **Found a bug?** [Open an issue](https://github.com/Azure/terraform-azurerm-naming/issues/new) |
| 258 | +- **Need clarification?** Comment on relevant issues like [#177](https://github.com/Azure/terraform-azurerm-naming/issues/177) |
| 259 | + |
| 260 | +## Code of Conduct |
| 261 | + |
| 262 | +This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). |
| 263 | + |
| 264 | +## License |
| 265 | + |
| 266 | +By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE). |
0 commit comments