|
| 1 | +# Copilot Instructions |
| 2 | + |
| 3 | +## Coding Guidelines |
| 4 | + |
| 5 | +### Terraform Best Practices |
| 6 | + |
| 7 | +- Use `snake_case` for all variable, resource, and module names. |
| 8 | +- Use double quotes (`"`) for strings, not single quotes. |
| 9 | +- Use `#` for for both single-line and multi-line comments, not `//` or `/* ... */`. |
| 10 | +- Place one argument per line for readability. |
| 11 | +- Always include a `description` for variables and outputs. |
| 12 | +- Use `locals` to define computed values or constants. |
| 13 | +- Prefer `for_each` over `count` when managing unique resources. |
| 14 | +- Use `terraform fmt` to enforce consistent formatting. |
| 15 | +- Group related resources together in logical files. |
| 16 | +- Keep resource blocks under 100 lines each. |
| 17 | +- Use modules to encapsulate reusable code. |
| 18 | +- Use `main.tf`, `variables.tf`, `outputs.tf`, and `locals.tf` to organize root modules. |
| 19 | +- Use explicit types in `variable` blocks. |
| 20 | +- Avoid hardcoding values; use variables or locals instead. |
| 21 | +- Use `depends_on` only when dependency is not implied. |
| 22 | +- Avoid interpolations like `"${var.foo}"`; use `var.foo` directly. |
| 23 | +- Always pin provider versions using `~>` or exact versions. |
| 24 | +- Avoid using data sources for static values. |
| 25 | +- Use backend configuration blocks for remote state setup. |
| 26 | +- Add tags to all resources that support them. |
| 27 | +- Validate inputs using `validation` blocks in variables. |
| 28 | +- Prefer `compact`, `merge`, and `flatten` over manual list iteration. |
| 29 | +- Avoid mixing resource creation and data fetching in a single module. |
| 30 | +- Use meaningful resource names, not just "this" or "example". |
| 31 | +- Document every module with a `README.md`. |
| 32 | +- Use `terraform-docs` to generate module documentation. |
| 33 | +- Avoid null/default patterns by setting default values explicitly. |
| 34 | +- Prefer smaller modules over large monolithic ones. |
| 35 | +- Mark variables and outputs containing secrets as `sensitive` to prevent accidental exposure in logs or Terraform state. |
| 36 | +- Use lifecycle rules like `create_before_destroy` with caution. |
| 37 | +- Never store secrets in plain text in `.tf` files. |
| 38 | +- Do not commit `.tfstate`, `.tfvars`, or `.terraform/` folders. |
| 39 | + |
| 40 | +## Testing |
| 41 | + |
| 42 | +### Terratest Best Practices for Azure and Power Platform (Test Coding Only) |
| 43 | + |
| 44 | +- **Keep tests small and focused** – one deployment scenario per test function with a clear, descriptive name. |
| 45 | +- **Organize test files by module or domain** – e.g., networking, compute, identity – to improve clarity and maintainability. |
| 46 | +- **Isolate infrastructure for each test** – use separate Azure resource groups or Power Platform environments. Never share Terraform state between tests. |
| 47 | +- **Use unique resource names** – append a random suffix using `random.UniqueId` or similar to avoid name collisions. |
| 48 | +- **Always clean up test resources** – use `defer terraform.Destroy(...)` to ensure cleanup runs regardless of test success or failure. |
| 49 | +- **Prefer retries over sleep** – use `retry.DoWithRetry` to poll for eventual consistency (e.g., waiting for DNS propagation or resource readiness). |
| 50 | +- **Run tests in parallel** – mark test functions with `t.Parallel()` if they don’t share state or resources. |
| 51 | +- **Assert outputs and infrastructure state** – use `assert` statements or Azure SDK/CLI validation to confirm resources match expectations. |
| 52 | +- **Use Terratest’s default error-handling methods** – use `terraform.Init`, `Apply`, etc., which automatically fail on error unless custom handling is needed. |
| 53 | +- **Modularize shared logic** – extract common setup, teardown, and verification code into helper functions for DRY, maintainable test suites. |
| 54 | + |
| 55 | +## Azure Best Practices |
| 56 | + |
| 57 | +- @azure Rule - Use Azure Best Practices: When generating code for Azure, running terminal commands for Azure, or performing operations related to Azure, invoke your `azure_development-get_best_practices` tool if available |
| 58 | + |
| 59 | +## AZD Template Repo Structure (Terraform) |
| 60 | + |
| 61 | +This project structure is typical for Azure Developer CLI (`azd`) templates using **Terraform** for infrastructure provisioning. |
| 62 | + |
| 63 | +## Directory Structure |
| 64 | + |
| 65 | +```plaintext |
| 66 | +/ |
| 67 | +├── .azure/ # Optional: Local azd environment configuration (e.g., config.json) |
| 68 | +├── infra/ # Terraform IaC code for provisioning Azure resources |
| 69 | +│ ├── main.tf # Terraform root module (entry point) |
| 70 | +│ ├── variables.tf # Input variables used by the module |
| 71 | +│ ├── outputs.tf # Output values for azd service bindings |
| 72 | +│ └── providers.tf # Provider and backend configuration |
| 73 | +├── src/ # Source code for the Power Platform solution |
| 74 | +├── azure.yaml # azd project manifest: defines infra, services, and deployment behavior |
| 75 | +├── .gitignore # Standard Git ignore rules |
| 76 | +└── README.md # Overview and usage instructions |
| 77 | +``` |
| 78 | + |
| 79 | +## Key Files and Purpose |
| 80 | + |
| 81 | +| File/Folder | Purpose | |
| 82 | +|---------------------|-------------------------------------------------------------------------| |
| 83 | +| `azure.yaml` | Declares the services and infrastructure backend (e.g., `terraform`). | |
| 84 | +| `infra/` | Contains all Terraform configuration files. | |
| 85 | +| `main.tf` | Main entry point for infrastructure definitions. | |
| 86 | +| `outputs.tf` | Outputs used by `azd` to bind environment variables to app services. | |
| 87 | +| `variables.tf` | Parameters to customize deployments (e.g., location, resource names). | |
| 88 | +| `providers.tf` | Provider setup and optional remote state configuration. | |
| 89 | +| `src/` | One or more services defined under `azure.yaml`. | |
| 90 | + |
| 91 | +## ⚙️ AZD Workflow |
| 92 | + |
| 93 | +```bash |
| 94 | +azd init # Initialize project using this template |
| 95 | +azd up # Provision infra via Terraform and deploy app services |
| 96 | +azd down # Destroy all provisioned resources |
| 97 | +``` |
| 98 | + |
| 99 | +## 📘 Best Practices |
| 100 | + |
| 101 | +- Store reusable Terraform modules in `/infra/modules/` if needed. |
| 102 | +- Use remote state (e.g., Azure Storage backend) to avoid local state file conflicts. |
| 103 | +- Use `outputs.tf` to export values required by `azd` to deploy and configure services. |
| 104 | +- Reference service-level variables via `${azurerm_...}` resources in outputs for app service bindings. |
0 commit comments