IaC Workflows Guide
This steering file provides guidance for Infrastructure as Code (IaC) tool selection, Bicep/ARM patterns, and deployment workflows using the azure-architect power.
This steering file provides guidance for Infrastructure as Code (IaC) tool selection, Bicep/ARM patterns, and deployment workflows using the azure-architect power.
This steering file provides guidance for Infrastructure as Code (IaC) tool selection, Bicep/ARM patterns, and deployment workflows using the azure-architect power.
The azure-architect power includes Azure MCP tools that work without authentication:
Use `bicepschema` to get the exact schema for any Azure resource:
// Get storage account schema
bicepschema({
intent: "Get storage account schema",
command: "bicepschema_get",
parameters: { "resource-type": "Microsoft.Storage/storageAccounts" }
})
// Get App Service schema
bicepschema({
intent: "Get App Service schema",
command: "bicepschema_get",
parameters: { "resource-type": "Microsoft.Web/sites" }
})
// Get Key Vault schema
bicepschema({
intent: "Get Key Vault schema",
command: "bicepschema_get",
parameters: { "resource-type": "Microsoft.KeyVault/vaults" }
})// Azure general best practices
get_azure_bestpractices({
intent: "Get Azure best practices",
command: "get_azure_bestpractices_get",
parameters: { resource: "general", action: "all" }
})
// Code generation best practices
get_azure_bestpractices({
intent: "Get code generation best practices",
command: "get_azure_bestpractices_get",
parameters: { resource: "general", action: "code-generation" }
})
// Deployment best practices
get_azure_bestpractices({
intent: "Get deployment best practices",
command: "get_azure_bestpractices_get",
parameters: { resource: "general", action: "deployment" }
})
// Terraform best practices for Azure
azureterraformbestpractices({
intent: "Get Terraform best practices",
command: "azureterraformbestpractices_get",
parameters: {}
})Search results from `microsoft_docs_search` return excerpts that may be truncated. Follow this pattern for complete information:
// Step 1: Search to find relevant articles
microsoft_docs_search({ query: "Bicep storage account properties" })
// Step 2: If excerpt shows "..." or seems incomplete, fetch full article
microsoft_docs_fetch({
url: "https://learn.microsoft.com/azure/azure-resource-manager/bicep/..."
})Use this decision tree to choose the right IaC tool for your project:
┌─────────────────────────────────────────────────────────────────┐
│ IaC Tool Selection │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ Azure-only infrastructure? │
└───────────────────────────────┘
│ │
Yes No
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Team experience │ │ Use Terraform │
│ with ARM/Bicep? │ │ (multi-cloud) │
└─────────────────┘ └─────────────────┘
│ │
Yes No
│ │
▼ ▼
┌──────────────┐ ┌──────────────────────┐
│ Use Bicep │ │ Existing Terraform │
│ (native) │ │ expertise? │
└──────────────┘ └──────────────────────┘
│ │
Yes No
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Use Terraform│ │ Use Bicep │
│ │ │ (easier) │
└──────────────┘ └──────────────┘| Factor | Bicep | Terraform | |--------|-------|-----------| | **Learning curve** | Lower (Azure-native) | Higher (HCL syntax) | | **Multi-cloud** | No | Yes | | **State management** | Azure handles it | You manage state | | **Module ecosystem** | Azure Verified Modules | Terraform Registry | | **IDE support** | VS Code extension | Multiple IDEs | | **Preview features** | Day-0 support | Depends on provider |
// Step 1: Get best practices first
get_azure_bestpractices({
intent: "Get Azure best practices",
command: "get_azure_bestpractices_get",
parameters: { resource: "general", action: "code-generation" }
})
// Step 2: Get schema for your resource
bicepschema({
intent: "Get storage account schema",
command: "bicepschema_get",
parameters: { "resource-type": "Microsoft.Storage/storageAccounts" }
})
// Step 3: Search for additional documentation
microsoft_docs_search({ query: "Bicep file structure best practices Azure" })Organize your Bicep code using this recommended structure:
infra/
├── main.bicep # Entry point, orchestrates modules
├── main.bicepparam # Parameter file for deployment
├── modules/
│ ├── networking/
│ │ ├── vnet.bicep
│ │ └── nsg.bicep
│ ├── compute/
│ │ ├── appservice.bicep
│ │ └── functions.bicep
│ └── data/
│ ├── storage.bicep
│ └── cosmos.bicep
└── environments/
├── dev.bicepparam
├── staging.bicepparam
└── prod.bicepparam// Use a naming module for consistency
param environment string
param location string = resourceGroup().location
param workloadName string
var resourceToken = toLower(uniqueString(subscription().id, resourceGroup().id))
var abbrs = loadJsonContent('abbreviations.json')
// Example: st-myapp-dev-abc123
var storageAccountName = '${abbrs.storage}${workloadName}${environment}${resourceToken}'param deployRedis bool = false
resource redis 'Microsoft.Cache/redis@2023-08-01' = if (deployRedis) {
name: redisName
location: location
properties: {
sku: {
name: 'Basic'
family: 'C'
capacity: 0
}
}
}param storageAccounts array = [
{ name: 'logs', sku: 'Standard_LRS' }
{ name: 'data', sku: 'Standard_GRS' }
]
resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = [for account in storageAccounts: {
name: '${account.name}${resourceToken}'
location: location
sku: { name: account.sku }
kind: 'StorageV2'
}]Use the `bicepschema` tool to get exact schemas:
// Get schema for any Azure resource type
bicepschema({
intent: "Get resource schema",
command: "bicepschema_get",
parameters: { "resource-type": "Microsoft.Storage/storageAccounts" }
})Common resource types:
// Step 1: Get Terraform best practices for Azure
azureterraformbestpractices({
intent: "Get Terraform best practices",
command: "azureterraformbestpractices_get",
parameters: {}
})
// Step 2: Search for additional documentation
microsoft_docs_search({ query: "Terraform Azure provider getting started" })terraform/
├── main.tf # Root module, calls child modules
├── variables.tf # Input variables
├── outputs.tf # Output values
├── providers.tf # Provider configuration
├── versions.tf # Version constraints
├── terraform.tfvars # Variable values (gitignored)
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/
│ └── data/
└── environments/
├── dev/
│ └── terraform.tfvars
├── staging/
└── prod/**Recommended: Azure Storage Backend**
terraform {
backend "azurerm" {
resource_group_name = "rg-terraform-state"
storage_account_name = "stterraformstate"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}**State Management Best Practices:**
resource "random_string" "suffix" {
length = 6
special = false
upper = false
}
locals {
resource_suffix = random_string.suffix.result
storage_name = "st${var.workload}${var.environment}${local.resource_suffix}"
}variable "deploy_redis" {
type = bool
default = false
}
resource "azurerm_redis_cache" "main" {
count = var.deploy_redis ? 1 : 0
name = "redis-${var.workload}-${var.environment}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
capacity = 0
family = "C"
sku_name = "Basic"
}resource "azurerm_network_security_group" "main" {
name = "nsg-${var.workload}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
dynamic "security_rule" {
for_each = var.nsg_rules
content {
name = security_rule.value.name
priority = security_rule.value.priority
direction = security_rule.value.direction
access = security_rule.value.access
protocol = security_rule.value.protocol
source_port_range = security_rule.value.source_port_range
destination_port_range = security_rule.value.destination_port_range
source_address_prefix = security_rule.value.source_address_prefix
destination_address_prefix = security_rule.value.destination_address_prefix
}
}
}// Step 1: Search for architecture patterns
microsoft_docs_search({
"query": "Azure architecture web application database caching"
})
// Step 2: Get deployment best practices
microsoft_docs_search({
"query": "Azure deployment best practices CI/CD"
})
// Step 3: Find pipeline guidance
microsoft_docs_search({
"query": "GitHub Actions Azure deployment workflow"
})name: Deploy Infrastructure
on:
push:
branches: [main]
paths: ['infra/**']
pull_request:
branches: [main]
paths: ['infra/**']
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Bicep Build (Validate)
run: az bicep build --file infra/main.bicep
plan:
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: What-If Deployment
run: |
az deployment sub what-if \
--location eastus \
--template-file infra/main.bicep \
--parameters infra/environments/${{ github.event.inputs.environment }}.bicepparam
deploy:
needs: plan
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy Infrastructure
run: |
az deployment sub create \
--location eastus \
--template-file infra/main.bicep \
--parameters infra/environments/prod.bicepparam┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Dev │ ──▶ │ Staging │ ──▶ │ Production │
│ │ │ │ │ │
│ Auto-deploy │ │ Auto-deploy │ │ Manual gate │
│ on PR merge │ │ after dev │ │ + approval │
└─────────────┘ └─────────────┘ └─────────────┘**Best Practices:**
// For Bicep
microsoft_docs_search({ "query": "Bicep project structure best practices" })
// For Terraform
microsoft_docs_search({ "query": "Terraform Azure module structure" }) microsoft_docs_search({
"query": "Azure reference architecture your-workload-type"
}) microsoft_docs_search({ "query": "Azure deployment CI/CD best practices" }) microsoft_docs_search({ "query": "Azure resource-type configuration best practices" }) microsoft_code_sample_search({ "query": "Bicep resource-type example" }) microsoft_docs_search({ "query": "resource-type ARM template reference" }) az bicep decompile --file template.json microsoft_docs_search({ "query": "ARM to Bicep migration guide" }) microsoft_docs_search({ "query": "Bicep best practices modules" })