Skip to content

Commit 73c5adf

Browse files
Add AZD template files (#3)
* Add AZD template files * Fix: addressed code review feedback * Adding codeowners and copilot * feat: update devcontainer configuration and enhance copilot instructions * fix: remove skip_provider_registration from azurerm provider configuration * fix: correct commit message instructions formatting * feat: update copilot instructions and add Azure best practices section fix: add .azure directory to .gitignore --------- Co-authored-by: Matt Dotson <[email protected]>
1 parent 2edf47c commit 73c5adf

File tree

13 files changed

+263
-0
lines changed

13 files changed

+263
-0
lines changed

.devcontainer/devcontainer.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "Azure Developer CLI",
3+
"image": "mcr.microsoft.com/devcontainers/go:1.4.1-bullseye",
4+
"features": {
5+
// terraform and az (required for auth) are installed by default
6+
// See https://containers.dev/features for list of features
7+
"ghcr.io/devcontainers/features/python:1" : {},
8+
"ghcr.io/devcontainers/features/azure-cli:1": {},
9+
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
10+
"ghcr.io/devcontainers/features/terraform:1": {
11+
"installTFsec": true
12+
},
13+
"ghcr.io/azure/azure-dev/azd:latest": {}
14+
},
15+
"customizations": {
16+
"vscode": {
17+
"extensions": [
18+
"GitHub.vscode-github-actions",
19+
"hashicorp.terraform",
20+
"ms-azuretools.azure-dev",
21+
"ms-azuretools.vscode-docker",
22+
"GitHub.copilot",
23+
"GitHub.copilot-chat",
24+
"ms-vscode.makefile-tools",
25+
"DavidAnson.vscode-markdownlint",
26+
"golang.go",
27+
"azapi-vscode.azapi",
28+
"ms-azuretools.vscode-azureterraform"
29+
// Include other VSCode extensions if needed
30+
// Right click on an extension inside VSCode to add directly to devcontainer.json, or copy the extension ID
31+
]
32+
}
33+
},
34+
"forwardPorts": [
35+
// Forward ports if needed for local development
36+
],
37+
"containerEnv": {
38+
"ARM_PARTNER_ID": "acce1e78-90a1-4306-89d1-a03ed6284007"
39+
},
40+
"postCreateCommand": "pip install --upgrade pip && pip install checkov",
41+
"remoteUser": "vscode",
42+
"hostRequirements": {
43+
"memory": "8gb"
44+
}
45+
}

.github/CODEOWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This is the default CODEOWNERS file for the repository.
2+
# It assigns @Azure-Samples/ise-scale-contributors as the default owners.
3+
4+
* @Azure-Samples/ise-scale-contributors
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Commit Message instructions
2+
3+
Write commit messages that conform to the [Convention Commits 1.0.0 specification](https://www.conventionalcommits.org/en/v1.0.0/)

.github/copilot-instructions.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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.

.github/dependabot.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "devcontainers"
4+
directory: "/.devcontainer"
5+
schedule:
6+
interval: "weekly"
7+
commit-message:
8+
prefix: "chore(deps):"
9+
open-pull-requests-limit: 5

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,5 @@ FodyWeavers.xsd
398398

399399
# JetBrains Rider
400400
*.sln.iml
401+
402+
.azure/

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"github.copilot.chat.commitMessageGeneration.instructions": [
3+
{
4+
"file": ".github/copilot-commit-message-instructions.md"
5+
}
6+
]
7+
}

azure.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Name of the application.
2+
name: Copilot-Studio-with-Azure-AI-Search
3+
metadata:
4+
5+
infra:
6+
provider: terraform

infra/main.tf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
resource "azurecaf_name" "rg_name" {
2+
name = var.environment_name
3+
resource_type = "azurerm_resource_group"
4+
random_length = 0
5+
clean_input = true
6+
}
7+
8+
# Deploy resource group
9+
resource "azurerm_resource_group" "rg" {
10+
name = azurecaf_name.rg_name.result
11+
location = var.location
12+
// Tag the resource group with the azd environment name
13+
// This should also be applied to all resources created in this module
14+
tags = { azd-env-name : var.environment_name }
15+
}
16+
17+
# Add resources to be provisioned below.
18+
# To learn more, https://developer.hashicorp.com/terraform/tutorials/azure-get-started/azure-change
19+
# Note that a tag:
20+
# azd-service-name: "<service name in azure.yaml>"
21+
# should be applied to targeted service host resources, such as:
22+
# azurerm_linux_web_app, azurerm_windows_web_app for appservice
23+
# azurerm_function_app for function

infra/main.tfvars.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"location": "${AZURE_LOCATION}",
3+
"environment_name": "${AZURE_ENV_NAME}"
4+
}

0 commit comments

Comments
 (0)