Azure setup
Prerequisites
| Requirement | Description |
|---|---|
| Cloud provider | An Azure cloud-provider with public_dns_zone_name and public_dns_zone_resource_group_name set |
| Assets repository | A Blob Storage-based assets-repository provider |
| Agent environment variables | AZURE_SUBSCRIPTION_ID, AZURE_RESOURCE_GROUP, TOFU_PROVIDER_STORAGE_ACCOUNT, TOFU_PROVIDER_CONTAINER |
RBAC permissions
The agent's service principal needs permissions across four areas: state backend, DNS management, CDN management, and storage account access. You can either assign built-in roles or create a custom role with the minimum required permissions.
Option 1: Built-in roles
# Replace placeholders with your values
PRINCIPAL_ID="YOUR_SERVICE_PRINCIPAL_ID"
SUBSCRIPTION="/subscriptions/YOUR_SUBSCRIPTION_ID"
STATE_RG="$SUBSCRIPTION/resourceGroups/YOUR_STATE_RESOURCE_GROUP"
DNS_RG="$SUBSCRIPTION/resourceGroups/YOUR_DNS_RESOURCE_GROUP"
CDN_RG="$SUBSCRIPTION/resourceGroups/YOUR_CDN_RESOURCE_GROUP"
STORAGE_ACCOUNT="$SUBSCRIPTION/resourceGroups/YOUR_RG/providers/Microsoft.Storage/storageAccounts/YOUR_ASSETS_STORAGE_ACCOUNT"
# State backend: read/write state blobs in the storage container
az role assignment create --assignee $PRINCIPAL_ID \
--role "Storage Blob Data Contributor" --scope $STATE_RG
# Network layer: create and delete DNS records
az role assignment create --assignee $PRINCIPAL_ID \
--role "DNS Zone Contributor" --scope $DNS_RG
# Distribution layer: manage CDN profiles, endpoints, and custom domains
az role assignment create --assignee $PRINCIPAL_ID \
--role "CDN Endpoint Contributor" --scope $CDN_RG
az role assignment create --assignee $PRINCIPAL_ID \
--role "CDN Profile Contributor" --scope $CDN_RG
# Distribution layer: read storage account properties for CDN origin
az role assignment create --assignee $PRINCIPAL_ID \
--role "Reader" --scope $STORAGE_ACCOUNT
Option 2: Custom role with minimum permissions
{
"Name": "Nullplatform Static Files Scope",
"Description": "Minimum permissions for the nullplatform agent to manage Static files scopes",
"Actions": [
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/listkeys/action",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/write",
"Microsoft.Network/dnszones/read",
"Microsoft.Network/dnszones/CNAME/read",
"Microsoft.Network/dnszones/CNAME/write",
"Microsoft.Network/dnszones/CNAME/delete",
"Microsoft.Network/dnszones/A/read",
"Microsoft.Network/dnszones/A/write",
"Microsoft.Network/dnszones/A/delete",
"Microsoft.Cdn/profiles/read",
"Microsoft.Cdn/profiles/write",
"Microsoft.Cdn/profiles/delete",
"Microsoft.Cdn/profiles/endpoints/read",
"Microsoft.Cdn/profiles/endpoints/write",
"Microsoft.Cdn/profiles/endpoints/delete",
"Microsoft.Cdn/profiles/endpoints/customdomains/read",
"Microsoft.Cdn/profiles/endpoints/customdomains/write",
"Microsoft.Cdn/profiles/endpoints/customdomains/delete",
"Microsoft.Cdn/profiles/endpoints/customdomains/EnableCustomHttps/action",
"Microsoft.Cdn/profiles/endpoints/customdomains/DisableCustomHttps/action"
],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete"
],
"AssignableScopes": [
"/subscriptions/YOUR_SUBSCRIPTION_ID"
]
}
Create and assign the custom role:
az role definition create --role-definition custom-role.json
az role assignment create \
--assignee YOUR_SERVICE_PRINCIPAL_ID \
--role "Nullplatform Static Files Scope" \
--scope /subscriptions/YOUR_SUBSCRIPTION_ID
Replace YOUR_SUBSCRIPTION_ID, YOUR_SERVICE_PRINCIPAL_ID, and the resource group names with values from your environment.
Next steps
- Set up the Static files scope: back to the setup overview
- Static files scope: overview of the scope type and how it works