Building a Resilient Business Continuity Plan for SMBs with Azure: A CLI-First Guide

For small to medium-sized businesses (SMBs), an unexpected outage, data loss, or natural disaster can be catastrophic, potentially leading to significant financial losses or even closure. Proactive resilience is not a luxury; it's a necessity. This comprehensive guide will walk you through building a robust business continuity plan SMB organizations can rely on, leveraging Microsoft Azure services and prioritizing a CLI-first approach. By the end, you'll have the foundational knowledge and commands to implement critical backup, disaster recovery, and recovery testing strategies, ensuring your business can quickly recover from disruptions.
Prerequisites
- Active Azure subscription with owner/contributor permissions
- Azure CLI (version 2.x or later) installed and configured on your workstation
- PowerShell (version 5.1 or later) with Az module installed
- Inventory of critical on-premises servers, applications, and data
- Defined Recovery Time Objective (RTO) and Recovery Point Objective (RPO) for key systems
- Reliable internet connectivity for Azure integration
Step 1: Establish Core Azure Infrastructure for BCP
Before deploying any specific backup or disaster recovery solutions, you need to set up the fundamental Azure resources that will house your business continuity components. This includes creating a dedicated resource group to logically organize all BCP-related services and a general-purpose storage account for various backup needs or as a staging area.
az group create --name SkyCoreBCP-RG --location eastus
az storage account create --name skycorebcpstorage --resource-group SkyCoreBCP-RG --location eastus --sku Standard_LRS --kind StorageV2
az group create: Creates a new Azure resource group.--name SkyCoreBCP-RG: Specifies the name for your resource group. Choose a naming convention that suits your organization.--location eastus: Defines the Azure region where the resource group metadata will reside.az storage account create: Creates a new Azure storage account.--name skycorebcpstorage: A globally unique name for your storage account.--sku Standard_LRS: Sets the storage redundancy.Standard_LRS(Locally Redundant Storage) is cost-effective for staging, but for production backups, considerStandard_GRS(Geo-Redundant Storage) orStandard_ZRS(Zone-Redundant Storage) for higher resilience.--kind StorageV2: Specifies a general-purpose v2 storage account, which supports blobs, files, queues, and tables.
Portal alternative: Navigate to "Resource groups" > "Create" to create the group. Then, go to "Storage accounts" > "Create" to configure the storage account, selecting the appropriate options for redundancy and type.
Confirmation: Verify the resources were created by listing them:
az group show --name SkyCoreBCP-RG
az storage account show --name skycorebcpstorage --resource-group SkyCoreBCP-RG --query '{name:name, location:location, sku:sku.name}'
Many SMBs underestimate the importance of accurately defining their Recovery Time Objective (RTO) and Recovery Point Objective (RPO) early on. Choosing a low-cost, less-redundant storage SKU (like LRS) might save money initially, but if your RTO demands near-instant recovery and your RPO requires minimal data loss, it will fail. Always align your technical choices with your business's true recovery needs, even if it means a higher monthly spend. A non-functional BCP is a wasted investment.
Step 2: Implement On-premises Data Backup with Azure Recovery Services (MARS Agent)
For file servers, applications, and system state on your physical or virtual machines running on-premises, Azure Backup offers a robust solution via the Microsoft Azure Recovery Services (MARS) agent. This agent allows direct backup of files, folders, and system state to an Azure Recovery Services vault, providing a straightforward and cost-effective way to protect critical data without requiring full VM replication.
First, create the Recovery Services vault in Azure. This vault will store your backups and manage your backup policies.
az backup vault create --name SkyCoreRSVault --resource-group SkyCoreBCP-RG --location eastus --sku Standard
az backup vault create: Creates an Azure Recovery Services vault.--name SkyCoreRSVault: The unique name for your Recovery Services vault.--resource-group SkyCoreBCP-RG: The resource group created in Step 1.--location eastus: The Azure region for the vault. Choose a region close to your on-premises infrastructure for better performance or a different region for geo-redundancy.--sku Standard: Sets the vault SKU. For most SMBs, Standard is sufficient. Premium offers advanced features like soft delete and geo-redundancy built-in for backup items.
Portal alternative: Go to "Recovery Services vaults" > "Create", fill in the details, and select "Review + create".
Confirmation: Verify the vault creation:
az backup vault show --name SkyCoreRSVault --resource-group SkyCoreBCP-RG --query '{name:name, location:location, sku:sku.name}'
Next, you'll configure a backup policy within this vault. This example creates a simple daily backup policy for MARS agent backups.
# Connect to Azure if not already connected
Connect-AzAccount
# Set context to your subscription (if multiple)
# Set-AzContext -SubscriptionId "<YourSubscriptionId>"
$vault = Get-AzRecoveryServicesVault -Name "SkyCoreRSVault" -ResourceGroupName "SkyCoreBCP-RG"
# Create a new backup policy for MARS agent. This example is for daily backup.
# More complex schedules can be configured, e.g., weekly, monthly.
New-AzRecoveryServicesBackupProtectionPolicy -Name "SkyCoreMARSDailyPolicy" -WorkloadType AzureFiles -BackupManagementType AzureStorage -RecoveryServicesVault $vault -SchedulePolicyType Daily -RetentionPolicyType Daily -RetentionDuration 30
# For specific MARS agent policies, PowerShell is generally preferred for full control.
# The workload type 'AzureFiles' is often used as a proxy for MARS agent scenarios
# when defining policy, though the agent itself handles file/folder specifics.
Connect-AzAccount: Logs you into Azure PowerShell.Get-AzRecoveryServicesVault: Retrieves the created vault.New-AzRecoveryServicesBackupProtectionPolicy: Creates a new backup policy.-Name "SkyCoreMARSDailyPolicy": Name for the backup policy.-WorkloadType AzureFiles: For MARS agent, this is a common workload type.-BackupManagementType AzureStorage: Indicates the backup is managed in Azure Storage.-RecoveryServicesVault $vault: Specifies the vault where the policy will reside.-SchedulePolicyType Daily: Sets the backup schedule to daily. Other options include Weekly.-RetentionPolicyType Daily: Sets the retention policy type.-RetentionDuration 30: Retains daily backups for 30 days.
Portal alternative: In the Recovery Services vault, go to "Backup policies" > "+Backup policy", choose "Azure File Share" (or "Azure virtual machine" if you intend to protect IaaS VMs later, but for MARS, the workflow differs slightly), and configure the schedule and retention.
On-premises MARS Agent Setup (Manual/Scripted):
- Download the MARS Agent: From the Recovery Services vault in the Azure portal, go to "Backup" under "Getting started", select "On-premises", choose "Files and folders" and "System State", then follow the links to download the agent installer and vault credentials file.
- Install the Agent: Run the installer on each on-premises server you want to back up.
- Register with Vault: During installation, use the downloaded vault credentials file to register the agent with your Azure Recovery Services vault.
- Configure Backup Schedule: Use the MARS agent console (Microsoft Azure Backup) on the local server to select files/folders/system state, define the backup schedule, and link it to the policy you created (or create a simple one via the agent UI).
Confirmation: Once the agent is configured and the first backup runs, you can check the "Backup jobs" in your Recovery Services vault in the Azure portal to see the status.
Step 3: Configure Disaster Recovery for On-premises VMs with Azure Site Recovery
For mission-critical on-premises virtual machines (VMs), a simple file backup isn't enough. You need the ability to failover entire VMs to Azure with minimal downtime. Azure Site Recovery (ASR) provides this capability, continuously replicating your on-premises Hyper-V, VMware, or physical servers to Azure, ready for a disaster recovery event.
ASR is a complex service involving on-premises components (Configuration Server, Process Server for VMware/Physical, or direct integration with Hyper-V hosts). While the CLI can manage replication and recovery plans once configured, the initial setup involving on-premises components is often done via the Azure portal wizard for simplicity and to ensure correct component deployment.
First, create an Azure Site Recovery vault. This is distinct from the Azure Backup Recovery Services vault.
az site-recovery vault create --name SkyCoreASRVault --resource-group SkyCoreBCP-RG --location eastus
az site-recovery vault create: Creates an Azure Site Recovery vault.--name SkyCoreASRVault: The unique name for your Site Recovery vault.--resource-group SkyCoreBCP-RG: The resource group created in Step 1.--location eastus: The Azure region for the vault. Consider a different region than your primary site for true disaster recovery.
Portal alternative: Navigate to "Recovery Services vaults" (it's the same resource type as the backup vault, but distinct in purpose for ASR) > "+Create", and name it appropriately for Site Recovery.
Confirmation: Verify the ASR vault creation:
az site-recovery vault show --name SkyCoreASRVault --resource-group SkyCoreBCP-RG --query '{name:name, location:location}'
On-premises ASR Setup (Hybrid Configuration - Portal Driven Initial Setup):
- Choose Replication Goal: In the Azure portal, navigate to your
SkyCoreASRVault. Under "Getting Started", select "Site Recovery". Define your replication goal (e.g., "From on-premises" to "To Azure", select your virtualization type like "VMware/Physical" or "Hyper-V"). - Prepare Infrastructure: Follow the wizard to download and install the Azure Site Recovery Configuration Server (for VMware/Physical) or register your Hyper-V hosts. This involves deploying appliances on your on-premises infrastructure.
- Enable Replication: Once the infrastructure is prepared, you'll discover your on-premises VMs through the portal and enable replication, setting target resources (storage account, network) in Azure.
While the initial setup is portal-heavy due to on-premises component deployment, you can manage replication and orchestrate recovery plans with CLI once configured.
# Example: List replicated items (after on-premises setup)
az site-recovery replicated-item list --resource-group SkyCoreBCP-RG --vault-name SkyCoreASRVault
# Example: Create a simple recovery plan (after VMs are replicating)
az site-recovery recovery-plan create --resource-group SkyCoreBCP-RG --vault-name SkyCoreASRVault --name "SkyCorePrimaryRP" --fabric-name "<YourFabricName>" --primary-zone "eastus" --recovery-zone "westus" --vm-ids "/subscriptions/<SubscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Compute/virtualMachines/<VMName>" --direction PrimaryToRecovery
az site-recovery replicated-item list: Lists all virtual machines currently being replicated.az site-recovery recovery-plan create: Creates an orchestrated recovery plan, defining the order and groups of VMs for failover.--name SkyCorePrimaryRP: Name of your recovery plan.--fabric-name "<YourFabricName>": The name of your on-premises ASR fabric (e.g., "SkyCoreHyperVFabric" or "SkyCoreVMwareFabric").--primary-zone eastus: Source region.--recovery-zone westus: Target DR region (must be different from source for true DR).--vm-ids "/subscriptions/...<VMName>": The resource ID of a replicated VM. You'll need to specify all VMs in the plan.--direction PrimaryToRecovery: Specifies the failover direction.
Confirmation: After setup, regularly check the "Replicated items" and "Recovery plans" sections in the Azure portal for the Site Recovery vault to ensure all VMs are replicating healthily and your recovery plans are defined.
Azure Site Recovery offers powerful DR capabilities, but its initial setup for on-premises infrastructure is inherently hybrid and not entirely CLI-first. Many IT admins try to force a full CLI deployment and get stuck. Be prepared to leverage the Azure portal's guided wizards for deploying the Configuration Server, Process Server, or registering Hyper-V hosts. Once the on-premises agents are communicating with Azure, CLI operations become much more viable for managing replication and orchestrating failovers. Don't be afraid to use the right tool for the job, even if it means a momentary departure from pure CLI.
Step 4: Enhance Azure-Native Application Resilience and Backups
If your SMB already hosts applications or databases directly within Azure, ensuring their resilience is a critical part of your business continuity plan. Azure offers native services for backup, geo-replication, and failover groups for services like Azure App Service and Azure SQL Database.
Let's look at setting up backups for an Azure App Service and geo-replication for an Azure SQL Database.
Azure App Service Backup Configuration
For your web applications hosted in Azure App Service, you can configure automatic backups to a storage account.
# First, get the connection string for your previously created storage account (or create a new one)
$storageAccountKey = az storage account keys list --resource-group SkyCoreBCP-RG --account-name skycorebcpstorage --query '[0].value' --output tsv
$storageAccountConnectionString = "DefaultEndpointsProtocol=https;AccountName=skycorebcpstorage;AccountKey=$storageAccountKey;EndpointSuffix=core.windows.net"
# Configure App Service Backup
az webapp config backup update --resource-group SkyCoreBCP-RG --webapp-name <YourAppServiceName> --frequency-interval Daily --retention-period-in-days 30 --storage-account-url $storageAccountConnectionString --db-name "<OptionalDatabaseName>" --db-connection-string "<OptionalDatabaseConnectionString>" --db-type SQLAzure
az storage account keys list: Retrieves the access keys for your storage account.az webapp config backup update: Configures the backup settings for an Azure App Service.--webapp-name <YourAppServiceName>: The name of your Azure App Service.--frequency-interval Daily: Sets daily backups. Other options: Hour.--retention-period-in-days 30: Retains backups for 30 days.--storage-account-url $storageAccountConnectionString: The connection string to the Azure Storage account where backups will be stored.--db-name,--db-connection-string,--db-type: Optional parameters for backing up connected databases if the App Service has database connections configured.
Portal alternative: Navigate to your App Service > "Backups" under "Development Tools" > "Configure and Schedule backups".
Confirmation: List existing backups for your App Service:
az webapp backup list --resource-group SkyCoreBCP-RG --webapp-name <YourAppServiceName>
Azure SQL Database Geo-Replication and Long-Term Retention
For critical Azure SQL Databases, geo-replication provides an active secondary replica in a different region, enabling rapid failover. Additionally, configure long-term retention (LTR) for regulatory compliance or extended recovery needs.
# Example: Create a geo-secondary replica for an Azure SQL Database
az sql db replica create --resource-group SkyCoreBCP-RG --server <YourSQLServerName> --name <YourPrimaryDBName> --partner-resource-group <PartnerResourceGroup> --partner-server <PartnerSQLServerName> --partner-database <PartnerSecondaryDBName> --partner-location westus --no-wait
# Example: Set Long-Term Retention (LTR) policy for weekly backups for 10 years
az sql db ltr-backup set-policy --resource-group SkyCoreBCP-RG --server <YourSQLServerName> --name <YourPrimaryDBName> --weekly-retention-days 520 --week-of-year 1 --m-week-of-year 1 --yearly-retention 10
az sql db replica create: Creates a geo-secondary replica for an Azure SQL Database.--server <YourSQLServerName>: The name of the Azure SQL logical server hosting the primary database.--name <YourPrimaryDBName>: The name of the primary database.--partner-resource-group: Resource group for the secondary database.--partner-server: New or existing logical SQL server in the target region.--partner-database: Name for the secondary database.--partner-location westus: The Azure region for the secondary replica. Crucially, this should be a different region from your primary database for geo-redundancy.--no-wait: Allows the command to return immediately without waiting for the replica creation to complete.az sql db ltr-backup set-policy: Configures long-term retention for an Azure SQL Database.--weekly-retention-days 520: Retains weekly backups for 520 weeks (approx. 10 years).--week-of-year 1: Specifies the first week of the year for a yearly backup.--m-week-of-year 1: Specifies the first week of the month for a monthly backup (if configured).--yearly-retention 10: Retains yearly backups for 10 years.
Portal alternative: For geo-replication, navigate to your SQL Database > "Geo-replication" under "Data management". For LTR, go to your SQL Server > "Backups" > "Retention policies" for the specific database.
Confirmation: Check the database's geo-replication status and LTR policy:
az sql db show --resource-group SkyCoreBCP-RG --server <YourSQLServerName> --name <YourPrimaryDBName> --expand-geo-backup
az sql db ltr-backup show-policy --resource-group SkyCoreBCP-RG --server <YourSQLServerName> --name <YourPrimaryDBName>
Step 5: Develop and Test Recovery Procedures and Network Connectivity
A business continuity plan is only as good as its tested recovery procedures. This step focuses on defining how you will recover and ensuring the necessary network infrastructure is in place to access your recovered resources. For an SMB, this often means ensuring VPN connectivity to Azure and proper DNS resolution post-failover.
Configure VPN Gateway for DR Connectivity
If your on-premises network relies on a Site-to-Site VPN to Azure, you'll need to ensure your DR network in Azure also has appropriate connectivity, or that you can establish a new VPN post-failover to access recovered resources.
# Create a new Virtual Network for your DR environment (if not already existing)
az network vnet create --name SkyCoreDR-VNet --resource-group SkyCoreBCP-RG --location westus --address-prefix 10.100.0.0/16
# Create a gateway subnet within your DR VNet
az network vnet subnet create --name GatewaySubnet --resource-group SkyCoreBCP-RG --vnet-name SkyCoreDR-VNet --address-prefix 10.100.255.0/27
# Create a public IP address for the VPN Gateway
az network public-ip create --name SkyCoreDRVpnGwIP --resource-group SkyCoreBCP-RG --location westus --allocation-method Static --sku Standard
# Create the VPN Gateway (takes ~30-45 minutes)
az network vnet-gateway create --name SkyCoreDRVpnGw --resource-group SkyCoreBCP-RG --location westus --public-ip-address SkyCoreDRVpnGwIP --vnet SkyCoreDR-VNet --gateway-type Vpn --sku VpnGw1 --vpn-type RouteBased --no-wait
az network vnet create: Creates a virtual network.--name SkyCoreDR-VNet: Name for your DR virtual network.--location westus: Crucially, a different region from your primary environment.az network vnet subnet create: Creates a subnet within the VNet.GatewaySubnet: This is a reserved name for the VPN Gateway subnet.az network public-ip create: Creates a public IP for the VPN Gateway.az network vnet-gateway create: Creates the Azure VPN Gateway.--sku VpnGw1: A basic SKU for SMBs. Adjust based on performance needs.
Portal alternative: Navigate to "Virtual networks", then "VPN gateways" to configure these resources.
Confirmation: Once the VPN Gateway is deployed, you can create a local network gateway representing your on-premises firewall/router and then create a connection between them.
Test Failover with Azure Site Recovery
The most critical aspect of your BCP is testing. For ASR-protected VMs, perform regular test failovers without impacting production.
# Example: Start a test failover for a recovery plan
az site-recovery recovery-plan test-failover start --resource-group SkyCoreBCP-RG --vault-name SkyCoreASRVault --name SkyCorePrimaryRP --replication-provider Azure --failover-direction PrimaryToRecovery --recovery-point-type Latest --az-recovery-vnet-name SkyCoreDR-VNet
az site-recovery recovery-plan test-failover start: Initiates a test failover for an ASR recovery plan.--name SkyCorePrimaryRP: The name of your recovery plan.--recovery-point-type Latest: Uses the latest available recovery point.--az-recovery-vnet-name SkyCoreDR-VNet: Specifies the isolated virtual network in Azure where the test VMs will be created. This prevents impact on your production network.
Portal alternative: In your Site Recovery vault, navigate to "Recovery plans", select your plan, and click "Test Failover".
Confirmation: After a test failover, you'll see temporary VMs running in your designated test network. Connect to them, verify application functionality, and then clean up the test resources using `az site-recovery recovery-plan test-failover cleanup`.
A common and dangerous mistake for any business continuity plan, especially for SMBs with limited IT resources, is failing to regularly test it. A BCP sitting on a shelf, even if technically sound, is worthless if it hasn't been validated end-to-end. Processes change, personnel leave, and configurations drift. Schedule and execute at least annual, if not quarterly, full recovery tests. Document every step, every error, and every successful recovery. An untested plan is a false sense of security.
Step 6: Implement Monitoring, Documentation, and Continuous Improvement
A BCP is not a one-time project; it's an ongoing process. Establishing robust monitoring, maintaining comprehensive documentation, and committing to continuous improvement are vital for the long-term success of your business continuity plan.
Centralized Monitoring with Azure Monitor and Log Analytics
Use Azure Monitor and Log Analytics to centralize logs and metrics from your BCP components, allowing you to proactively detect issues with backups, replication, or DR infrastructure.
# Create a Log Analytics Workspace
az monitor log-analytics workspace create --resource-group SkyCoreBCP-RG --name SkyCoreBCPLAW --location eastus
# Configure alerts for backup failures (example for Recovery Services Vault)
az monitor activity-log alert create --resource-group SkyCoreBCP-RG --name "BackupFailureAlert" --scope "/subscriptions/<SubscriptionId>/resourceGroups/SkyCoreBCP-RG/providers/Microsoft.RecoveryServices/vaults/SkyCoreRSVault" --condition "category = 'Administrative' and operationName = 'Microsoft.RecoveryServices/vaults/backupFabrics/backupProtectionContainers/protectedItems/write' and level = 'Error'" --action-group "/subscriptions/<SubscriptionId>/resourceGroups/SkyCoreBCP-RG/providers/Microsoft.Insights/actionGroups/SkyCoreAdminsAG"
# Note: You'll need to create an Action Group first to define who gets notified (email, SMS, etc.)
az monitor action-group create --resource-group SkyCoreBCP-RG --name SkyCoreAdminsAG --short-name SkyCoreAdmins --receiver-name "emailreceiver" --receiver-type Email --email-address "itadmins@skycore.com"
az monitor log-analytics workspace create: Creates a Log Analytics workspace.az monitor activity-log alert create: Creates an alert rule based on Azure Activity Log events.--scope: The resource ID of the Recovery Services vault to monitor.--condition: Filters for specific events, e.g., backup protection item write operations with an 'Error' level.--action-group: Specifies an action group to be triggered when the alert fires.az monitor action-group create: Creates an action group for notifications.
Portal alternative: Go to "Log Analytics workspaces" to create, and "Alerts" under "Monitor" to configure alert rules and action groups.
Confirmation: Generate a test alert or check the Activity Log to ensure your alert rules are active and correctly configured.
Documentation and Continuous Improvement
This phase is less about CLI commands and more about process and governance. Your BCP documentation should include:
- Business Impact Analysis (BIA) Summary: Critical systems, RTOs, RPOs.
- Recovery Procedures: Step-by-step guides for failover and failback, including pre-requisites, network configurations, and application-specific steps.
- Contact Lists: Internal teams, external vendors, emergency services.
- Test Reports: Dates, outcomes, lessons learned, and updates made.
- Roles and Responsibilities: Who does what during a disaster.
Schedule quarterly reviews of your BCP. Technology evolves, business needs change, and personnel shifts. A regular review cycle ensures your BCP remains relevant, effective, and actionable. Integrate lessons learned from testing and real-world incidents back into your plan.
When to bring in a consultant
Implementing a truly effective business continuity plan, especially one spanning on-premises and cloud environments, can become complex quickly. While this guide provides a solid foundation, nuances like highly customized applications, strict compliance requirements, large-scale migrations, or complex network topologies often require specialized expertise. If you're struggling with accurately defining RTO/RPO for intricate systems, orchestrating multi-tier application recovery, or require a comprehensive security review of your DR solution, a seasoned IT consulting firm like SkyCore Solutions can provide invaluable guidance. We ensure your plan is not just technically sound but also optimally aligned with your business objectives and regulatory needs.
Book a free consultation