Deployment Templates
Lab Objective
In this hands-on lab, you will learn how to:
- Interpret ARM template structure including schema, parameters, variables, resources, and outputs sections
- Deploy infrastructure using ARM templates through Azure portal, CLI, and PowerShell methods
- Convert ARM templates to Bicep using decompilation tools and understand syntax differences
- Create modular Bicep files with parameters, variables, modules, and conditional deployment logic
- Implement template security best practices including parameter validation, secure string handling, and RBAC integration
- Troubleshoot deployment failures using activity logs, deployment history, and validation techniques
- Optimize template performance through dependency management, parallel deployments, and resource organization
Scenario: Your organization needs to standardize infrastructure deployments across development, staging, and production environments. Youβll create and deploy Infrastructure as Code (IaC) solutions using both ARM templates and Bicep files to ensure consistent, repeatable, and secure Azure resource provisioning while maintaining compliance and governance standards.
Please sign in to launch lab.
Pre-Provisioned Environment
The following Azure resources have been pre-deployed in your environment:
Resource Overview
Resource Type | Resource Name | Configuration | Purpose |
---|---|---|---|
Resource Group | DeploymentTemplates-Lab-RG | Contains all lab resources | Logical container |
Storage Account | templatesstore[unique] | GPv2, Hot tier, LRS | Template and artifact storage |
Key Vault | templateskv[unique] | Standard tier, RBAC enabled | Secure parameter storage |
Virtual Network | templates-vnet | 10.0.0.0/16 address space | Network infrastructure |
Test VM | DeploymentTemplatesVM | Windows Server 2019 | Template testing and validation |
Container Registry | templatesacr[unique] | Basic tier | Container image storage |
Log Analytics | templateslog[unique] | Standard workspace | Deployment monitoring |
Template Storage Structure
Template Storage Account (templatesstore[unique])βββ Container: arm-templatesβ βββ /basic/β β βββ storage-account.jsonβ β βββ virtual-network.jsonβ β βββ virtual-machine.jsonβ βββ /advanced/β β βββ multi-tier-app.jsonβ β βββ linked-templates/β β βββ nested-templates/β βββ /parameters/β βββ dev-parameters.jsonβ βββ staging-parameters.jsonβ βββ prod-parameters.jsonβββ Container: bicep-filesβ βββ /modules/β β βββ storage.bicepβ β βββ network.bicepβ β βββ compute.bicepβ βββ /main-templates/β β βββ webapp-deployment.bicepβ β βββ infrastructure.bicepβ βββ /examples/β βββ conditional-resources.bicepβ βββ loops-and-conditions.bicepβββ Container: deployment-artifacts βββ /scripts/ βββ /configs/ βββ /certificates/
Key Vault Secrets Configuration
Secret Name | Purpose | Example Value |
---|---|---|
AdminPassword | VM administrator password | Secure random password |
DatabaseConnectionString | Application database connection | Encrypted connection string |
StorageAccountKey | Storage access key | Primary access key |
CertificateThumbprint | SSL certificate identifier | Certificate thumbprint |
Network Topology
Virtual Network (templates-vnet - 10.0.0.0/16)βββ ManagementSubnet (10.0.1.0/24)β βββ DeploymentTemplatesVM (10.0.1.4)βββ WebSubnet (10.0.2.0/24)β βββ [Available for template deployments]βββ DataSubnet (10.0.3.0/24)β βββ [Available for template deployments]βββ ContainerSubnet (10.0.4.0/24) βββ [Available for ACI deployments]
Pre-configured Template Examples
Template Type | File Name | Resources Created | Complexity |
---|---|---|---|
Basic Storage | storage-account.json | Storage account with containers | Beginner |
Virtual Network | virtual-network.json | VNet, subnets, NSGs | Beginner |
Virtual Machine | virtual-machine.json | VM, NIC, disk, public IP | Intermediate |
Multi-tier App | multi-tier-app.json | Load balancer, VMs, database | Advanced |
Container Workload | container-deployment.bicep | ACI, storage, networking | Intermediate |
Lab Exercises
Part 1: Understand ARM Template Structure
Step 1: Examine Basic ARM Template Components
- Navigate to Storage accounts in the Azure portal
- Click on
templatesstore[unique]
- Go to Storage browser β Blob containers
- Click on
arm-templates
container - Navigate to
/basic/
folder - Download
storage-account.json
Template analysis:
- Schema version: Identifies ARM template format and API version
- ContentVersion: Template versioning for change tracking
- Parameters section: Define input values with types and constraints
- Variables section: Computed values and reusable expressions
- Resources section: Azure resources to be created or modified
- Outputs section: Values returned after successful deployment
Step 2: Analyze Template Parameters and Variables
- Open the downloaded
storage-account.json
in your preferred editor - Examine the parameters section:
Parameter structure analysis:
- storageAccountName: String parameter with naming constraints
- storageAccountType: Allowed values restricting SKU options
- location: Default value using resource group location function
- tags: Object parameter for resource tagging strategy
Step 3: Review Resource Dependencies
- Navigate back to the
arm-templates
container - Download
multi-tier-app.json
- Open the file and examine the resources array
Dependency analysis:
- Implicit dependencies: References using resource functions
- Explicit dependencies:
"dependsOn"
array declarations - Parallel deployment: Resources without dependencies deploy simultaneously
- Deployment ordering: Critical for network, storage, and compute resources
Part 2: Deploy ARM Templates
Step 1: Deploy Template Using Azure Portal
- Navigate to Resource groups and click
DeploymentTemplates-Lab-RG
- Click βDeploy a custom templateβ
- Click βBuild your own template in the editorβ
- Copy and paste the content from
storage-account.json
Template deployment configuration:
- Storage account name: Enter
armdeploy[unique]
- Storage account type: Select
Standard_LRS
- Location: Use resource group location
- Tags: Add
Environment: Lab
andPurpose: ARM-Demo
Step 2: Monitor Deployment Progress
- Click βReview + createβ then click βCreateβ
- Navigate to the deployment blade to monitor progress
- Observe the deployment timeline and resource creation order
Deployment monitoring:
- Deployment status: Track overall progress and completion
- Resource creation: Individual resource deployment status
- Duration metrics: Time taken for each deployment phase
- Error handling: Automatic rollback on validation failures
Step 3: Validate Deployed Resources
- Navigate to the newly created storage account
armdeploy[unique]
- Verify the configuration matches template specifications
- Check the tags were applied correctly
Validation checklist:
- Storage account exists with correct name and SKU
- Resource tags match template parameters
- Location matches resource group location
- Access tier and replication settings are correct
Part 3: Work with Bicep Files
Step 1: Install and Configure Bicep Tools
- Connect to
DeploymentTemplatesVM
using RDP - Open PowerShell as Administrator
- Install Bicep CLI and VS Code extension
Bicep tooling setup:
- Bicep CLI: Command-line interface for compilation and deployment
- VS Code extension: IntelliSense, syntax highlighting, and validation
- Azure CLI integration: Native Bicep support in Azure CLI
- PowerShell module: Az.Bicep module for PowerShell workflows
Step 2: Convert ARM Template to Bicep
- Download
virtual-network.json
from the templates storage - Open command prompt in the download location
- Run:
az bicep decompile --file virtual-network.json
Bicep conversion analysis:
- Syntax simplification: Reduced JSON verbosity and improved readability
- Type safety: Strong typing and compile-time validation
- Resource references: Simplified symbolic name referencing
- Parameter handling: Cleaner parameter and variable declarations
Step 3: Create Custom Bicep Module
- Create a new file named
webapp-module.bicep
- Define parameters for web app configuration:
Module structure:
- Parameters: Input values for customization
- Resources: Web app, app service plan, and dependencies
- Outputs: Resource identifiers and configuration values
- Metadata: Documentation and versioning information
Step 4: Test Bicep Compilation
- Compile the Bicep file:
az bicep build --file webapp-module.bicep
- Review the generated ARM template JSON
- Validate the template:
az deployment group validate
Compilation validation:
- Syntax errors and type checking
- Resource provider API validation
- Parameter and variable resolution
- Dependency graph verification
Part 4: Implement Advanced Template Features
Step 1: Create Conditional Resource Deployment
- Navigate to the
bicep-files
container in storage - Download
conditional-resources.bicep
- Examine the conditional deployment logic
Conditional deployment patterns:
- Environment-based resources: Deploy different resources per environment
- Feature flags: Enable/disable functionality through parameters
- Cost optimization: Deploy optional resources based on requirements
- Compliance controls: Conditional security and monitoring resources
Step 2: Implement Template Loops
- Open
loops-and-conditions.bicep
from the examples folder - Study the array iteration and resource creation patterns
Loop implementation:
- Copy operations: Create multiple similar resources
- Variable loops: Generate configuration arrays
- Conditional loops: Combine conditions with iterations
- Nested loops: Complex resource relationships and dependencies
Step 3: Create Linked Template Deployment
- Navigate to
/advanced/linked-templates/
in the ARM templates container - Examine the main template and linked template structure
- Deploy the linked template solution
Linked template benefits:
- Modularity: Separate concerns and reusable components
- Team collaboration: Different teams can work on different templates
- Template size limits: Overcome single template size restrictions
- Deployment orchestration: Complex multi-stage deployments
Part 5: Secure Template Deployment
Step 1: Implement Secure Parameter Handling
- Navigate to Key Vault
templateskv[unique]
- Create a new secret named
DeploymentSecret
- Set the value to a complex password
Key Vault integration:
- Secure parameters: Reference Key Vault secrets in templates
- RBAC permissions: Grant template deployment access to secrets
- Secret versioning: Manage secret lifecycle and rotation
- Audit logging: Track secret access and usage patterns
Step 2: Configure Template RBAC
- Go to Resource groups β
DeploymentTemplates-Lab-RG
- Click βAccess control (IAM)β
- Add role assignment for template deployment service principal
RBAC configuration:
- Contributor role: Required for resource creation and modification
- Reader role: Minimum permission for template validation
- Custom roles: Granular permissions for specific deployment scenarios
- Managed identity: Secure authentication for automated deployments
Step 3: Validate Template Security
- Download a template with Key Vault references
- Deploy using secure parameter retrieval
- Monitor the deployment for security compliance
Security validation:
- No secrets stored in template or parameter files
- Proper RBAC assignments for deployment identity
- Secure parameter transmission and storage
- Compliance with organizational security policies
Part 6: Monitor and Troubleshoot Deployments
Step 1: Analyze Deployment History
- Navigate to Resource groups β
DeploymentTemplates-Lab-RG
- Click βDeploymentsβ under Settings
- Review the deployment history and status
Deployment history analysis:
- Success rates: Track deployment reliability over time
- Duration trends: Identify performance improvements or regressions
- Failure patterns: Common deployment issues and resolutions
- Resource changes: Track infrastructure modifications and impacts
Step 2: Troubleshoot Failed Deployment
- Click on a failed deployment from the history
- Examine the error details and affected resources
- Navigate to Activity Log for detailed error information
Troubleshooting methodology:
- Error message analysis: Understanding Azure error formats and codes
- Resource-level debugging: Individual resource creation failures
- Dependency issues: Identify circular or missing dependencies
- Parameter validation: Verify input values and constraints
Step 3: Implement Deployment Monitoring
- Navigate to Log Analytics workspace
templateslog[unique]
- Create queries to monitor deployment metrics
- Set up alerts for deployment failures
Monitoring implementation:
- Deployment logs: Centralized logging for all template deployments
- Performance metrics: Track deployment duration and resource utilization
- Error alerting: Automated notifications for deployment failures
- Compliance reporting: Audit trails for governance and compliance
Troubleshooting Guide
Common Deployment Template Issues
Issue | Symptoms | Possible Cause | Solution |
---|---|---|---|
Template validation failed | Deployment fails before resource creation | Invalid JSON syntax or schema violations | Validate template structure and fix syntax errors using Azure CLI or portal |
Resource already exists | Deployment fails with conflict error | Resource name collision or incomplete cleanup | Use unique naming conventions or implement conditional deployment logic |
Permission denied | Deployment fails with authorization error | Insufficient RBAC permissions for deployment identity | Grant appropriate roles (Contributor) to service principal or user identity |
Dependency cycle detected | Deployment hangs or fails with circular reference | Resources reference each other in circular pattern | Review and restructure resource dependencies to eliminate cycles |
Parameter validation failed | Template accepts invalid parameter values | Missing parameter constraints or validation rules | Add allowed values, min/max length, and regex patterns for parameters |
Template Configuration Checklist
Component | Requirement | Status | Notes |
---|---|---|---|
Schema version | Latest ARM template schema (2019-04-01 or newer) | β | Ensures access to latest features and functions |
Parameter validation | Constraints defined for all input parameters | β | Prevents invalid values and improves security |
Resource dependencies | Proper dependency declaration and ordering | β | Ensures correct deployment sequence |
Secret handling | Key Vault references for sensitive parameters | β | Prevents credential exposure in templates |
Error handling | Rollback and cleanup procedures defined | β | Maintains environment consistency on failures |
Best Practices
Scenario | Recommendation | Benefit |
---|---|---|
Large deployments | Use linked or nested templates for modularity | Improves maintainability and enables team collaboration |
Multi-environment | Parameterize environment-specific values | Single template supports dev, staging, and production |
Security compliance | Store secrets in Key Vault and use managed identities | Meets enterprise security and compliance requirements |
Performance optimization | Minimize dependencies and leverage parallel deployment | Reduces deployment time and improves reliability |
Version control | Tag templates and maintain deployment history | Enables rollback and change tracking capabilities |
Optional Advanced Exercises
For users wanting more technical depth, try these exercises:
Advanced Exercise 1: Automated Template Deployment
# Deploy ARM templates using PowerShell with parameter filesConnect-AzAccount
# Set up variables for automated deployment$resourceGroup = "DeploymentTemplates-Lab-RG"$templateFile = "C:\Templates\multi-tier-app.json"$parameterFile = "C:\Templates\prod-parameters.json"$deploymentName = "AutomatedDeployment-$(Get-Date -Format 'yyyyMMddHHmmss')"
# Deploy template with monitoring$deployment = New-AzResourceGroupDeployment -ResourceGroupName $resourceGroup -TemplateFile $templateFile -TemplateParameterFile $parameterFile -Name $deploymentName -Verbose
# Monitor deployment progressdo { Start-Sleep -Seconds 30 $status = Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroup -Name $deploymentName Write-Host "Deployment Status: $($status.ProvisioningState) - $($status.Timestamp)"} while ($status.ProvisioningState -eq "Running")
Write-Host "Deployment completed with status: $($status.ProvisioningState)"
Advanced Exercise 2: Bicep Module Development
# Create and deploy modular Bicep architecture$resourceGroup = "DeploymentTemplates-Lab-RG"$bicepFile = "infrastructure.bicep"$location = "East US"
# Compile Bicep to ARM templateaz bicep build --file $bicepFile --outfile infrastructure.json
# Validate compiled template$validation = Test-AzResourceGroupDeployment -ResourceGroupName $resourceGroup -TemplateFile "infrastructure.json" -location $location -storageAccountPrefix "bicepstore"
if ($validation.Count -eq 0) { # Deploy if validation passes New-AzResourceGroupDeployment -ResourceGroupName $resourceGroup -TemplateFile "infrastructure.json" -location $location -storageAccountPrefix "bicepstore" -Verbose Write-Host "Bicep deployment completed successfully"} else { Write-Host "Template validation failed:" $validation | ForEach-Object { Write-Host $_.Message }}
Advanced Exercise 3: Template Deployment Monitoring
# Advanced deployment monitoring and alerting$resourceGroup = "DeploymentTemplates-Lab-RG"$workspaceName = "templateslog[unique]"
# Query deployment logs using KQL$query = @"AzureActivity| where TimeGenerated > ago(24h)| where CategoryValue == "Administrative"| where OperationNameValue contains "deployments"| where ResourceGroup == "$resourceGroup"| summarize Count=count() by OperationNameValue, ActivityStatusValue, bin(TimeGenerated, 1h)| order by TimeGenerated desc"@
# Execute query and analyze results$workspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName $resourceGroup -Name $workspaceName$results = Invoke-AzOperationalInsightsQuery -WorkspaceId $workspace.CustomerId -Query $query
# Display deployment metricsWrite-Host "Deployment Activity Summary:"$results.Results | Format-Table -AutoSize
# Create alert rule for deployment failures$actionGroup = Get-AzActionGroup -ResourceGroupName $resourceGroup -Name "DeploymentAlerts"$alertRule = New-AzMetricAlertRuleV2 -ResourceGroupName $resourceGroup -Name "TemplateDeploymentFailures" -TargetResourceId $workspace.ResourceId -WindowSize "00:15:00" -Frequency "00:05:00" -MetricName "DeploymentFailures" -Operator GreaterThan -Threshold 0 -Severity 2 -ActionGroup $actionGroup
Write-Host "Deployment monitoring and alerting configured successfully"
Key Takeaways
After completing this lab, you should understand:
- ARM template structure provides a declarative approach to infrastructure deployment with proper dependency management and parameter validation
- Bicep simplifies infrastructure as code by offering improved syntax, type safety, and development experience while maintaining ARM template compatibility
- Template modularity and reusability enable efficient infrastructure management across multiple environments and deployment scenarios
- Security best practices including Key Vault integration, RBAC configuration, and secure parameter handling protect sensitive deployment information
- Deployment monitoring and troubleshooting techniques help identify and resolve infrastructure deployment issues quickly and effectively
- Advanced template features such as conditional deployment, loops, and linked templates support complex enterprise infrastructure requirements
Deployment Templates Decision Matrix
Template Format Selection
Criteria | ARM Templates (JSON) | Bicep | Azure CLI | Recommendation |
---|---|---|---|---|
Learning curve | Moderate complexity | Easy to learn | Command-based | Bicep for new projects, ARM for existing |
Tooling support | Mature ecosystem | Growing rapidly | Built-in Azure CLI | Bicep with VS Code for best experience |
Enterprise adoption | Widely established | Increasing adoption | Limited IaC capability | ARM for legacy, Bicep for greenfield |
Team collaboration | Version control friendly | Excellent readability | Script-based sharing | Bicep for collaborative development |
Deployment Strategy Selection
Scenario | Template Approach | Expected Outcome |
---|---|---|
Single environment | Standalone templates with hardcoded values | Fast deployment with minimal complexity |
Multi-environment | Parameterized templates with environment files | Consistent deployments with environment-specific configurations |
Enterprise scale | Linked templates with modular architecture | Scalable infrastructure management with team collaboration |
CI/CD integration | Automated deployments with validation gates | Reliable infrastructure delivery with quality assurance |
Cost vs Complexity Trade-offs
Deployment Pattern | Development Effort | Maintenance Cost | Operational Benefit |
---|---|---|---|
Simple templates | Low initial investment | Higher long-term maintenance | Quick deployment with manual oversight |
Modular architecture | Higher upfront development | Lower ongoing maintenance | Automated deployment with consistency |
Enterprise framework | Significant initial investment | Minimal operational overhead | Full automation with governance and compliance |
Additional Resources
- Azure Resource Manager Templates Documentation - Comprehensive guide to ARM template development and deployment
- Bicep Language Reference - Complete syntax guide and best practices for Bicep development
- Template Functions Reference - Built-in functions for dynamic template expressions and calculations
- Deployment Troubleshooting Guide - Common issues and resolution strategies for template deployments
- Infrastructure as Code Best Practices - Security, performance, and maintainability guidelines