Stage 7 · Master
Cloud SDKs & Azure Automation
Azure Automation Runbooks
Deploy Python runbooks, schedules, and Hybrid Runbook Workers.
Azure Automation Overview
Azure Automation runs runbooks (scripts) on a schedule or on demand. It supports Python, PowerShell, and graphical runbooks. Use it for recurring tasks that do not justify a full container or VM.
| Runbook Type | Language | Use Case |
|---|---|---|
| Python | Python 3.8+ | SDK operations, API calls, data processing |
| PowerShell | PowerShell 5.1/7 | Windows management, Azure cmdlets |
| Graphical | Visual editor | Simple workflows without code |
Python runbooks execute in an Azure-managed sandbox with limited filesystem access. Use Azure Blob Storage or Key Vault for persistent data. Do not rely on local file paths.
Python Runbooks
# This is a Python runbook that runs in Azure Automation
import azure.mgmt.compute
import azure.mgmt.resource
from azure.identity import ManagedIdentityCredential
def main():
credential = ManagedIdentityCredential()
sub_id = "your-subscription-id"
# List all VMs and their status
compute_client = azure.mgmt.compute.ComputeManagementClient(credential, sub_id)
for vm in compute_client.virtual_machines.list_all():
instance_view = compute_client.virtual_machines.instance_view(
vm.id.split("/")[4], # resource group
vm.name,
)
for status in instance_view.statuses:
if status.code.startswith("PowerState/"):
print(f"{vm.name}: {status.code}")
# List resources in a resource group
resource_client = azure.mgmt.resource.ResourceManagementClient(credential, sub_id)
for resource in resource_client.resources.list_by_resource_group("my-rg"):
print(f"{resource.type}: {resource.name}")
if __name__ == "__main__":
main()Runbooks use ManagedIdentityCredential for authentication — no secrets needed. The runbook identity must have appropriate RBAC roles on the target resources.
Scheduling Runbooks
from azure.identity import DefaultAzureCredential
from azure.mgmt.automation import AutomationClient
from azure.mgmt.automation.models import (
ScheduleCreateParameters,
CreateOrUpdateJobScheduleParameters,
)
from datetime import datetime, timedelta
credential = DefaultAzureCredential()
client = AutomationClient(credential, "subscription-id")
# Create a daily schedule
schedule = client.schedule.create_or_update(
"my-rg", "my-automation", "daily-2am",
ScheduleCreate_parameters=ScheduleCreateParameters(
name="daily-2am",
description="Runs every day at 2 AM UTC",
frequency="Day",
interval=1,
start_time=datetime.utcnow() + timedelta(hours=1),
time_zone="UTC",
),
)
# Link schedule to a runbook
client.job_schedule.create_or_update(
"my-rg", "my-automation", "daily-health-check-schedule",
CreateOrUpdateJobScheduleParameters={
"runbook": {"name": "health-check"},
"schedule": {"name": "daily-2am"},
"parameters": {"resource_group": "production"},
},
)Schedules are linked to runbooks through job schedules. Each runbook can have multiple schedules. Parameters are passed to the runbook at runtime.
Hybrid Runbook Workers
from azure.identity import DefaultAzureCredential
from azure.mgmt.automation import AutomationClient
from azure.mgmt.automation.models import (
RunbookCreateOrUpdateParameters,
WebhookCreateOrUpdateParameters,
)
credential = DefaultAzureCredential()
client = AutomationClient(credential, "subscription-id")
# Create a runbook that targets a Hybrid Worker group
runbook = client.runbook.create_or_update(
"my-rg", "my-automation", "onprem-backup",
RunbookCreateOrUpdateParameters={
"runbook_type": "Python3",
"description": "Backup databases on on-premises servers",
"log_progress": True,
"log_verbose": False,
"draft": {"content_type": "text/plain"},
},
)
# Publish the runbook content
client.runbook.begin_publish(
"my-rg", "my-automation", "onprem-backup"
).result()
# Start the runbook on a Hybrid Worker group
job = client.job.create(
"my-rg", "my-automation", "onprem-backup-job",
{
"runbook": {"name": "onprem-backup"},
"parameters": {"server": "db-server-01"},
"run_on": "hybrid-worker-group-1",
},
)Hybrid Runbook Workers run Azure Automation runbooks on machines in your on-premises network or other clouds. The worker polls for jobs and executes them locally.
Webhook-Triggered Runbooks
from azure.identity import DefaultAzureCredential
from azure.mgmt.automation import AutomationClient
credential = DefaultAzureCredential()
client = AutomationClient(credential, "subscription-id")
# Create a webhook
webhook = client.webhook.create_or_update(
"my-rg", "my-automation", "deploy-webhook",
{
"name": "deploy-webhook",
"description": "Triggers deployment runbook",
"is_enabled": True,
"runbook": {"name": "deploy-service"},
"expiry_time": "2025-01-01T00:00:00Z",
},
)
print(f"Webhook URL: {webhook.uri}")
# To trigger, POST to the webhook URL:
# curl -X POST "https://s12.azure-automation.net/webhooks?token=abc123" \
# -H "Content-Type: application/json" \
# -d '{"service": "web-01", "replicas": 3}'Webhooks give you an HTTP endpoint that triggers a runbook. The webhook URL contains a token for authentication. Use webhooks to integrate with CI/CD pipelines and external systems.
Error Handling in Runbooks
import logging
import sys
from datetime import datetime
# Configure logging for Azure Automation
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
stream=sys.stdout,
)
logger = logging.getLogger(__name__)
def main():
try:
logger.info("Starting runbook execution")
result = perform_operation()
logger.info(f"Runbook completed: {result}")
except Exception as e:
logger.error(f"Runbook failed: {e}")
# Write output for the runbook history
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
def perform_operation() -> dict:
"""The actual runbook logic."""
# Your automation code here
return {"status": "success", "timestamp": datetime.utcnow().isoformat()}
if __name__ == "__main__":
main()Azure Automation captures stdout as runbook output and stderr as error output. Use logging for structured logs and print for runbook output. Exit code 1 signals failure.
Runbooks have a default timeout of 1 hour for Python. Set explicit timeouts in your code for long-running operations. Use Azure Functions for event-driven workloads that need longer execution times.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.