Automate Deployment of Resources by Using Azure Resource Manager Templates or Bicep Files
Understanding Templates and Bicep Files
Azure Resource Manager (ARM) templates and Bicep files are tools that let you define cloud infrastructure using declarative syntax, which means you describe the final state you want rather than writing step-by-step commands. ARM templates use JSON format, while Bicep is a simpler domain-specific language that compiles into JSON during deployment. Both approaches ensure that running the same template multiple times produces the same result, which is called idempotency and is essential for automation.
An infrastructure-as-code file contains several key sections that work together. Parameters accept custom values at deployment time, making templates reusable across different environments like development or production. Variables store calculated values that simplify complex expressions and reduce repetitive code. The resources section lists the Azure components to deploy, while the outputs section returns useful information such as IP addresses after deployment completes.
Parameters, Variables, and Outputs
Parameters serve as the primary way to customize a deployment without changing the template itself. They accept inputs like strings, integers, or secure data types such as securestring for passwords. When you define a parameter, you can provide default values for non-sensitive settings and use the secure types to prevent secrets from appearing in deployment logs.
Variables are internal values calculated within the template to keep resource definitions clean. They combine parameter values, constants, and built-in functions to construct resource names or connection strings. Using variables makes templates easier to read and maintain because changes happen in one central place rather than throughout the code.
Outputs return information after deployment completes, such as a virtual machine's public IP address or a storage account's endpoint. These outputs are useful for verifying deployment success or chaining multiple templates together where one template's output becomes another template's input.
Dependencies and Validation
Azure Resource Manager analyzes resource dependencies to determine the correct deployment order. In ARM templates, you explicitly declare dependencies using the dependsOn property to prevent creating a resource before its prerequisites exist. Bicep simplifies this by automatically detecting dependencies when one resource references another by its symbolic name. Resources with no dependencies deploy in parallel, which speeds up the overall process.
Before deploying, administrators should run validation checks to prevent failures. The preflight validation phase checks template syntax and configuration rules before any resources change. The what-if operation compares the template against the live environment to preview whether resources will be created, updated, ignored, or deleted, giving administrators a safe way to evaluate deployment impact.
Modifying and Deploying Templates
When modifying an ARM template, you can add, remove, or change resource definitions. Each resource has a type, name, location, and specific properties. You use parameters and variables to make definitions flexible for different environments while maintaining consistency. Updating dependency lists is crucial when adding or removing resources to ensure proper deployment order.
Deploying templates requires appropriate permissions, specifically write access to target resources and the Microsoft.Resources/deployments/* permission. Deployments can target different scopes including resource groups, subscriptions, management groups, or tenants depending on the administrative goal. Azure handles orchestration automatically, determining deployment order and deploying independent resources simultaneously.
Exporting and Converting Templates
You can export a template from an existing deployment using the Azure portal, PowerShell, or Azure CLI. The export captures the current state of the resource group, including any manual changes made after the original deployment. There are two export methods: exporting from a resource group creates a snapshot of the live environment, while saving from history retrieves the exact template submitted during the original deployment.
Converting ARM templates to Bicep uses the bicep decompile command or Visual Studio Code extensions. The decompiler performs a best-effort translation, and you must review the output for correctness. After conversion, the Bicep file takes advantage of symbolic resource names and string interpolation, which improve readability compared to verbose JSON syntax.
Creating a Virtual Machine
Creating a virtual machine in Azure involves setting up several components that work together to provide a functional computing environment. You start by selecting a resource group, giving the VM a name, and choosing a deployment region that determines where the VM physically runs. You then pick an operating system image such as Windows Server or Ubuntu Linux and create a local administrator account.
The VM connects to a Virtual Network (VNET) through a Network Interface Card (NIC), which enables network communication. Each NIC must be in the same Azure region and subscription as the VM. The NIC receives two types of IP addresses: a private IP address for internal VNET communication and an optional public IP address for direct internet access.
Security and Disk Configuration
By default, a new VM can be accessed from the internet using RDP for Windows or SSH for Linux, which poses security risks if left open. You should set public inbound ports to None during creation and use Azure Bastion host for secure remote access without exposing the VM to the public internet. Network Security Groups (NSGs) add protection by creating rules that allow or deny traffic based on IP address, port, and protocol.
For disk configuration, you choose the OS disk type such as Standard SSD or Premium SSD, which directly affects performance and cost. The chosen VM size dictates maximum network bandwidth and disk throughput. For high availability, you can deploy VMs across Availability Zones, which are physically separate datacenters within an Azure region.
Azure Disk Encryption
Azure Disk Encryption protects data at rest on VMs by encrypting operating system and data disks using BitLocker for Windows and DM-Crypt for Linux. The encryption keys are managed through Azure Key Vault, which must be in the same region and subscription as the VMs being protected. Before encrypting, you must enable the --enabled-for-disk-encryption parameter on the Key Vault and enable both soft-delete and purge protection.
For additional security, you can use a Key Encryption Key (KEK) to wrap the disk encryption secret before storing it in the vault, providing envelope encryption that protects the secret even if the vault is accessed. Azure Disk Encryption only supports RSA keys, with 2048-bit keys being standard while Windows Server 2022 and Windows 11 require 3072-bit or 4096-bit keys.
Moving Virtual Machines
Before moving a VM, both source and target subscriptions must reside within the same Microsoft Entra ID tenant, and the administrator needs Owner permissions. VMs with managed disks move easily, but unmanaged disks must be converted first. Several configurations block VM movement, including Virtual Machine Scale Sets with Standard SKU load balancers, VMs in availability sets that must move together, and marketplace VMs with attached plans crossing subscription boundaries.
After moving, resource IDs change, so existing Role-Based Access Control assignments become orphaned and must be recreated. If the VM uses a system-assigned managed identity, you must re-register it with dependent Azure services. Azure Backup requires unregistering from the original Recovery Services vault and setting up protection in a new vault.
Managing VM Sizes
Resizing a VM lets you scale resources up or down as demands change, though the VM must restart even without full deallocation. In many cases, the VM must be deallocated when the target size is not available on the current hardware cluster. You can check availability using tools like Get-AzVMSize to confirm the target size is supported.
VMs inside an Availability Set create challenges if the new size is unavailable on existing hardware—all VMs in the set must be deallocated before any member can resize. You must also track subscription quotas limiting total cores per region. Azure Advisor provides cost optimization recommendations by identifying underutilized VMs that are candidates for downsizing.
Managing VM Disks
Azure offers several managed disk types with different performance and cost characteristics. Standard HDD disks are lowest-cost for workloads tolerating higher latency. Standard SSD disks offer better reliability at moderate cost for web servers. Premium SSD disks deliver high performance with low latency for production databases. Azure Ultra Disks are designed for the most demanding workloads with the ability to dynamically adjust IOPS and throughput without restarting the VM.
A VM uses three primary disk roles: the OS disk contains the operating system, data disks store application data, and a temporary disk provides short-term non-persistent storage. You can expand data disk capacity live without stopping the VM, but expanding an OS disk requires deallocating first. Disk caching settings significantly impact I/O performance, with ReadOnly caching working well for frequent reads and None providing best performance for write-heavy workloads.
Availability Zones and Sets
Azure offers three main strategies for high availability. Availability zones are physically separate datacenters within a region, each with independent power, cooling, and networking, providing up to 99.99% uptime when VMs deploy across multiple zones. Availability sets group VMs so Azure distributes them across fault domains (different physical racks) and update domains (groups that reboot together during maintenance), providing 99.95% uptime. Virtual Machine Scale Sets (VMSS) deploy and manage load-balanced VMs that automatically scale based on demand.
For storage redundancy, Locally Redundant Storage replicates data three times within a single datacenter, while Zone-Redundant Storage replicates across three availability zones to protect against datacenter failures. Use availability zones when you need protection against entire datacenter failures and want 99.99% uptime, and use availability sets when your region does not support zones or when 99.95% uptime meets your requirements.
Virtual Machine Scale Sets
Virtual Machine Scale Sets (VMSS) deploy and manage multiple identical VMs with automatic scaling. Administrators manage individual instances using Azure CLI or PowerShell, transitioning VMs through states like start, stop, restart, or deallocate. When modifying a scale set model, the upgrade policy determines how updates apply: Automatic mode pushes changes simultaneously, Rolling mode updates in sequential batches, and Manual mode leaves existing instances untouched.
Scale sets integrate with Azure Load Balancer or Application Gateway using the Application Health extension to probe the application running inside the VM rather than just checking if powered on. When deploying, you must choose between Uniform and Flexible orchestration modes, a setting that cannot be changed after creation. Flexible orchestration is the modern standard supporting up to 1,000 VMs with different sizes, operating systems, and pricing models.
Autoscaling allows scale sets to automatically adjust instance counts based on demand. You define autoscale profiles with metric triggers monitoring CPU usage, memory consumption, or network traffic. Best practices include setting appropriate minimum, maximum, and default capacity limits and distributing instances across multiple availability zones for resiliency.
Provision and Manage Containers in the Azure Portal
Azure Container Registry
Azure Container Registry (ACR) is a managed Docker registry that stores container images for Azure deployments. To authenticate without managing credentials, you can use a managed identity on an Azure resource such as a VM or AKS cluster. The identity can be user-assigned (created separately) or system-assigned (tied to the resource's lifecycle). You enable the identity on the resource, grant it a role like AcrPull on ACR, and the resource pulls images without storing passwords.
ACR offers three service tiers: Basic, Standard, and Premium. The Premium SKU is required for geo-replication, which synchronizes registry content across multiple Azure regions. When you choose a tier, consider throughput needs, storage capacity, and whether low-latency access in several regions is important. Geo-replication automatically ensures that a host in Europe pulls from a European replica while a host in Asia pulls from an Asian replica.
Administrators manage the lifecycle of container images through four operations: push (upload a new image), pull (download for deployment), tag (assign a version label), and delete (remove unused images). ACR supports service endpoints and private endpoints to restrict access to specific virtual networks. A private endpoint gives the registry a private IP address inside your VNet so traffic never leaves the Microsoft backbone.
Azure Container Instances
Azure Container Instances (ACI) is a serverless service that runs containers without managing underlying VMs. It is designed for isolated workloads that need to start quickly and scale on demand. The deployment process begins with storing your container image in Azure Container Registry. To securely access this registry without embedding passwords, you can use managed identities.
When creating a container instance, you define its basic properties including a unique name, operating system type, and the source of the container image. You must allocate CPU cores and memory to match your application's needs. For private images stored in ACR, you must provide registry credentials so ACI can pull the image. You can pass environment variables to the container at startup for dynamic configuration.
Networking determines how your container is accessed. You can assign a public IP address and DNS name label to give your container a public-facing web address. For secure deployments, ACI supports virtual network integration, which places the container inside your private Azure network so it can communicate with other resources without exposing them to the internet. Because containers are stateless, you can mount an Azure File Share as a volume to persist data.
Azure Container Apps
Azure Container Apps is a serverless platform that runs containerized applications without managing underlying Kubernetes infrastructure. When you provision a container app, you first create an environment that acts as a secure boundary where multiple container apps live and share network and logging configurations.
The container app definition includes a template section where you specify the container image and resource settings. You must define vCPU and memory requirements based on the chosen workload profile. Advanced configurations allow for sidecar containers, init containers, and environment variables that control application behavior.
Ingress rules determine how network traffic reaches your application and support both HTTP and TCP protocols. You can configure external ingress for public internet access or internal ingress to keep services private within your virtual network. Scaling policies in Azure Container Apps are powered by KEDA, an event-driven autoscaler that can scale your application to zero when there is no demand, saving costs on compute resources.
An Azure Container Apps environment serves as the foundational host where container apps run and share network and logging infrastructure. There are two primary environment types: Workload profiles offer dedicated compute resources including memory-optimized or GPU-enabled instances, while Consumption only environments are designed for simpler workloads. VNet integration is essential for building a secure foundation, requiring a subnet with a minimum size of /27 for workload profiles or /23 for Consumption only.
Container Scaling and Sizing
When deploying containerized applications, resource allocation balances application stability against running costs. In Azure Container Apps, developers configure specific combinations of CPU and memory, ranging from 0.25 vCPUs to 4.0 vCPUs in the consumption plan. Azure Container Apps offers different workload profiles to match specific requirements: General Purpose balances compute and memory, Memory Optimized provides extra RAM for data-heavy applications, and GPU Enabled supports high-performance compute for AI and machine learning tasks.
Dynamic scaling allows Azure Container Apps to automatically adjust running instances in response to real-time traffic or system load. KEDA monitors external event sources and scales the containers accordingly based on event-driven triggers, resource-based triggers (CPU or memory), or time-based triggers. When traffic drops, KEDA can scale applications down to zero replicas, eliminating computing costs for idle workloads.
For Azure Container Instances, scaling focuses on defining policies based on workload demands. Administrators use Azure Monitor to set up automated rules that react to changing resource demands. These rules can be metrics-based (triggering when CPU exceeds a threshold), schedule-based (adjusting during known peak hours), or a combination of both.
App Service Plans
An App Service plan represents the physical compute resources that host your web applications in Azure. When creating a plan, you choose its region, operating system, and pricing tier, which together determine cost and hardware capabilities. Azure organizes tiers into shared, dedicated, and isolated tiers depending on how much resource isolation your workload requires.
Selecting the right pricing model balances application performance and budget. The Flex Consumption Plan bills based on execution count and memory usage, fitting unpredictable workloads. The Premium Plan charges for CPU and memory usage of warm instances to guarantee quick response times during traffic spikes. The Dedicated Plan uses a flat rate for physical hardware. For high availability, you can deploy your plan with zone redundancy, spreading instances across multiple physical datacenters.
Scaling App Service
Scaling changes how many resources your applications can use to handle traffic demands. Vertical scaling, or scaling up, upgrades your plan to a higher pricing tier for faster CPUs and more memory. Horizontal scaling, or scaling out, adds more VM instances to share the traffic load. The maximum instances depend on your pricing tier, ranging from 3 on Basic up to 100 on Isolated.
Administrators can automate scaling through three workflows. Manual scaling lets you set a fixed number of instances when you want strict control. Autoscale uses custom rules to add or remove instances based on metrics like CPU usage. Automatic scaling, available in Premium tiers, automatically adjusts instances based on incoming HTTP traffic. For plans hosting multiple applications, you can enable per-app scaling to set specific instance limits on individual apps.
Creating App Service Applications
Azure App Service is a platform-as-a-service offering that runs web and mobile applications without managing physical servers. You create a web app by specifying its subscription, resource group, unique name, runtime stack, and underlying App Service plan. The platform supports multiple development stacks such as .NET, Java, Node.js, and Python, or you can package code in custom containers.
Once created, you configure application behavior through encrypted app settings that act as secure environment variables at runtime. You can deploy code using FTP or version control systems like Git. For professional development, integrating with Azure DevOps or GitHub automates the entire build and release process. You should use Microsoft Entra ID for secure authentication, implement RBAC, and store sensitive secrets in Azure Key Vault.
Certificates and TLS
Transport Layer Security encrypts data traveling between users and your web application. Azure App Service configures TLS 1.2 as the minimum default version for new apps, but you can upgrade to TLS 1.3 for stronger protection. To secure custom domains, you bind a certificate using either SNI SSL (allowing multiple certificates to share one IP) or IP-based SSL (requiring a dedicated public IP address).
For high-security APIs and internal tools, Mutual TLS forces clients to present their own certificates before a connection is established. You configure the client certificate mode to Required, Optional, or Optional Interactive User depending on how strictly you want to verify client identities. Implementing custom certificates or mTLS requires at least a Basic tier App Service plan.
Custom Domains and Backup
Using a custom domain replaces the default Azure URL to make your application look professional. Before mapping a custom name, you must prove ownership by adding a TXT record with your Domain Verification ID at your DNS provider. This prevents a subdomain takeover, where a threat actor claims a domain that points to Azure but is no longer in use.
To route traffic correctly, you choose the right DNS record type. An A record points a root domain directly to your App Service's dedicated public IP address. A CNAME record is preferred for subdomains because it maps to the default Azure hostname, which continues working even if Azure changes your inbound IP address.
Azure App Service offers backup solutions to protect application code and configurations. Automatic backups run hourly without configuration, keeping files and settings for up to 30 days. Custom backups run on a custom schedule and store in an Azure Storage account. When restoring, you can restore directly to production or to a staging deployment slot, which allows testing before swapping into production.
Networking and Deployment Slots
You secure your application's network traffic by configuring inbound and outbound firewall rules. Access restrictions create a prioritized list of rules that permit or block traffic based on IP addresses or virtual network subnets. For deeper security, you deploy a Private Endpoint to assign your app a private IP address, removing it from the public internet entirely.
Virtual Network integration sends all outbound traffic from your application into a delegated subnet in your Azure Virtual Network, allowing your app to access secure back-end databases without exposing them to the internet. For reaching resources outside Azure, Hybrid Connections use Azure Relay to establish a secure tunnel over port 443.
Deployment slots are live web applications with their own URLs that run within the same App Service plan as production. Slots serve as isolated staging environments where you can safely test code changes. The swap operation exchanges content and configuration of the staging slot with the production slot. During a swap, the platform prepares the target slot, restarts instances, and warms up the application with HTTP requests to prevent initial latency for users.