Skip to content

Azure Deployment

This guide walks you through deploying Beacon to Azure using an automated template. The template creates all required resources in one go.

What Gets Created

The deployment template creates:

ResourcePurpose
Resource GroupContainer for all Beacon resources
App RegistrationMulti-tenant app for accessing client M365 data
Function AppRuns the Beacon polling service
App Service PlanHosting plan for the Function App
Storage AccountRequired by Azure Functions and alert deduplication
Federated CredentialSecure authentication (no secrets needed)
Log Analytics WorkspaceStores alerts for querying and dashboards
Application InsightsFunction App logging and monitoring
Data Collection EndpointIngestion endpoint for Log Analytics
Data Collection RuleRoutes alerts to the custom table
Custom Table (Beacon_Alerts_CL)Schema for alert data
Role AssignmentAllows Function App to write to Log Analytics

Prerequisites

Before you begin, you'll need:

  • Azure subscription with permission to create resources
  • Azure CLI installed (Download here)
  • Bicep CLI installed (run az bicep install if not already installed)

Step 1: Download the Template

Download both template files from the repository:

Save both files to the same folder on your computer.

TIP

You can also clone the entire repository:

bash
git clone https://github.com/emildosen/beacon.git
cd beacon/infra

Step 2: Sign In to Azure

Open a terminal and sign in:

bash
az login

A browser window will open. Sign in with your Azure account. If you have multiple subscriptions, you'll be asked to select one after authenticating.

Step 3: Deploy

Run the deployment command, replacing the location with your preferred Azure region:

bash
az deployment sub create \
  --location australiaeast \
  --template-file beacon.bicep

Available Regions

Common regions include: australiaeast, northeurope, westeurope, eastus, westus2, uksouth, southeastasia.

For a full list, run: az account list-locations -o table

Deployment Parameters

You can customise the deployment with these parameters:

Basic Parameters

ParameterDefaultDescription
resourceGroupNamerg-beaconName for the resource group
appNameBeaconName used for the app registration and resources
appPlanSkuB1Hosting plan tier (Y1, EP1, B1)
enableFederatedAuthtrueEnable federated authentication for the Function App managed identity

Resource Names

Use these parameters to specify custom names for resources, useful when resources already exist or you need specific naming conventions. Leave empty to use auto-generated names. Default patterns use the appName parameter (shown below as {app}).

ParameterDefaultDescription
functionAppName{app}-func-[6 random]Function App name
storageAccountName{app}[10 random]Storage Account name
appServicePlanName{app}-planApp Service Plan name
logAnalyticsWorkspaceNamelaw-{app}Log Analytics Workspace name
dataCollectionEndpointNamedce-{app}Data Collection Endpoint name
dataCollectionRuleNamedcr-{app}Data Collection Rule name
appInsightsNameai-{app}Application Insights name

Example with custom values:

bash
az deployment sub create \
  --location australiaeast \
  --template-file beacon.bicep \
  --parameters \
    resourceGroupName=rg-beacon-prod \
    appName=BeaconProd

Example with custom resource names:

bash
az deployment sub create \
  --location australiaeast \
  --template-file beacon.bicep \
  --parameters \
    resourceGroupName=rg-beacon-prod \
    functionAppName=my-existing-func \
    storageAccountName=myexistingstorage

Example disabling federated auth (for client secret authentication):

bash
az deployment sub create \
  --location australiaeast \
  --template-file beacon.bicep \
  --parameters \
    enableFederatedAuth=false

Hosting Plan Options

Cost Warning

The default B1 plan costs approximately $55 USD/month. This is the recommended option for reliable deployments.

SKUTypeBest For
B1BasicRecommended. Reliable builds and consistent performance.
Y1ConsumptionLower cost (pay-per-use), but deployment builds may timeout.
EP1Elastic PremiumHigh volume or low-latency requirements. Always warm.

Step 4: Note the Outputs

When deployment completes, you'll see output values. Save these for later:

Outputs:
  adminConsentUrl: https://login.microsoftonline.com/.../adminconsent?client_id=...
  appRegistrationAppId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  appRegistrationName: Beacon
  customTableName: Beacon_Alerts_CL
  dataCollectionEndpointUrl: https://dce-beacon-xxxx.australiaeast-1.ingest.monitor.azure.com
  dataCollectionRuleId: dcr-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  dataCollectionRuleName: dcr-beacon-alerts
  functionAppName: beacon-func-xxxxxx
  functionAppUrl: https://beacon-func-xxxxxx.azurewebsites.net
  logAnalyticsWorkspaceId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  logAnalyticsWorkspaceName: law-beacon
  resourceGroupName: rg-beacon
  storageAccountName: beaconxxxxxxxxxx
  appInsightsName: ai-beacon

The adminConsentUrl is particularly important - you'll need it for onboarding client tenants.

The app registration is created with the required permissions, but admin consent must still be granted.

For your own tenant

Not strictly necessary, only if you want to monitor your own tenant too.

  1. Open the adminConsentUrl from the deployment outputs
  2. Sign in with a Global Administrator account
  3. Review the permissions and click Accept

For client tenants

For each client tenant you want to monitor:

  1. Replace the tenant ID in the consent URL:
    https://login.microsoftonline.com/{client-tenant-id}/adminconsent?client_id={app-client-id}
  2. Send this URL to the client's Global Administrator
  3. They sign in and accept the permissions

Expected Behaviour

After granting consent, you'll see an error. This is expected. The app has no redirect URL configured, so the browser has nowhere to go. The consent itself was granted successfully.

Verify Deployment

  1. Open the Azure Portal
  2. Navigate to Resource groupsrg-beacon (or your custom name)
  3. Confirm all resources are present and healthy

To check the Function App:

  1. Open the Function App resource
  2. Go to Functions in the left menu
  3. You should see the pollAuditLogs function listed

To verify alerts are being ingested (after the function has run):

  1. Open the Log Analytics workspace → Logs
  2. Run this query:
    kusto
    Beacon_Alerts_CL
    | take 10

Troubleshooting

Deployment fails with permission error

You need sufficient permissions to:

  • Create resource groups in the subscription
  • Create app registrations in Entra ID
  • Create resources (storage accounts, function apps, etc.)

Try running with an account that has Owner or Contributor role on the subscription, plus Application Administrator in Entra ID.

Bicep extension error

If you see an error about the Microsoft Graph extension:

bash
az bicep upgrade

The Graph extension requires Bicep version 0.29.0 or later.

Function App shows no functions

The code is deployed from GitHub. If functions aren't appearing:

  1. Open the Function App in Azure Portal
  2. Go to Deployment Center
  3. Check the deployment status and logs

No data in Log Analytics

If alerts aren't appearing in the Beacon_Alerts_CL table:

  1. Check the Function App logs for errors
  2. Verify the function has run at least once (check Monitor in the function)
  3. Ensure admin consent was granted for client tenants

Updating Beacon

To update to the latest version:

  1. Open the Function App in Azure Portal
  2. Go to Deployment Center
  3. Click Sync to pull the latest code from GitHub

Clean Up

To remove all Beacon resources:

bash
az group delete --name rg-beacon --yes

Warning

This deletes all resources in the resource group, including any data in the storage account. The app registration is not deleted automatically. Remove it manually from Entra ID if needed.