Skip to main content
The Azure Cloud Account connects an Azure subscription to Formal using workload identity federation. Formal presents its AWS identity, which your tenant trusts through a federated identity credential, then authenticates as a dedicated user-assigned managed identity. No secrets are created; access is entirely federated.

What Formal Discovers

Discover Azure Database for PostgreSQL and MySQL flexible servers and add them as Formal resources.
Discover AKS clusters for Kubernetes access control.
Discover Azure virtual machines for SSH access.
Forward Formal Connector logs to Blob Storage containers for long-term storage and compliance.
Autodiscovery for all three resource types is on by default. See Resource Autodiscovery for how discovered resources behave.

Architecture

The terraform-formal-azure module creates:
  1. Resource Group: a group named fml-<suffix> holding Formal’s identity, so the module needs no pre-existing group
  2. User-Assigned Managed Identity: the identity Formal authenticates as
  3. Federated Identity Credential: pins Formal’s OIDC issuer, Formal’s per-integration role ARN as the subject, and the api://AzureADTokenExchange audience. Entra matches all three exactly, so only that role can exchange a token.
  4. Role Assignments: the built-in roles the enabled capabilities require, on the subscription or on a single resource group when one is set
Formal derives the roles from the capabilities you enable and returns them for the module to grant. Reader covers every discovery call, so it is granted once rather than per resource type, and Storage Blob Data Contributor is added for log delivery.
Azure has no region for the integration itself. The managed identity is regional, but what it can read is not, so discovery covers the whole subscription regardless of where the identity lives.

Setup

1

Navigate to Cloud Accounts

2

Create Integration

Click Create Integration and choose Microsoft Azure
3

Enter Details

Enter a name and the subscription ID to connect. Optionally set a resource group to narrow Formal’s access to that group instead of the whole subscription.
4

Choose Discovery

Toggle autodiscovery for Virtual Machines, AKS, and Databases. All are on by default.
5

Configure Blob Storage Access

To deliver logs to Blob Storage, enable Blob Storage log writes. Leave the storage account list empty to allow every account in scope, or name specific accounts to scope access.
6

Run the Setup Command

Formal shows a command with your integration ID and security key filled in. Paste it into an authenticated Azure Cloud Shell for that subscription:
It fetches the setup parameters from Formal, runs terraform apply, then reports the tenant and managed identity client ID back to Formal, which activates the integration.
Azure Cloud Shell can run Bash or PowerShell, and remembers the last choice. Run this command in Bash. In PowerShell it fails with The '<' operator is reserved for future use; switch shells with the selector at the top of Cloud Shell, or type bash first.
To change access later, change the capability on the integration in Formal, then run the same command again. The script keeps its Terraform state in the subscription, so a rerun adds what the integration now needs and removes what it no longer does.

Blob Storage Log Delivery

To forward logs to Blob Storage, the integration needs Blob Storage access. Enable it when creating the integration with two settings: Formal grants matching roles: Storage Blob Data Contributor on the subscription or resource group when the account list is empty, or on each named account when you restrict it. Once access is granted, create a Log Integration pointing at a container to start forwarding logs.

Security

  • Federated, keyless: no client secrets or certificates are created or stored.
  • Pinned role: the federated identity credential trusts only Formal’s exact per-integration role ARN, matched case sensitively alongside the issuer and audience.
  • Least privilege: the managed identity gets only the built-in roles the capabilities you enable require.
  • Scope narrowing: set a resource group to keep discovery and every role assignment inside that group.
  • Account scoping: restrict blob_storage_accounts so Formal can write only to the accounts you name.

Troubleshooting

Possible causes:
  • The Cloud Shell is not set to the target subscription
  • The account lacks permission to create resource groups, identities, or role assignments
  • The integration ID or security key is wrong
  • The command was run in PowerShell rather than Bash
Solution:
  1. Run az account set --subscription <SUBSCRIPTION_ID> in the Cloud Shell
  2. Ensure the account has Owner, or Contributor plus User Access Administrator
  3. Copy the exact command Formal shows when you create the integration
Possible causes:
  • Autodiscovery disabled for that resource type
  • The integration is scoped to a resource group that does not hold the resources
  • The database server is neither a PostgreSQL nor a MySQL flexible server
  • The managed identity is missing the Reader role
Solution:
  1. Verify the discovery toggle is enabled on the Cloud Account
  2. Confirm the resource group on the integration matches where the resources live, or clear it to cover the subscription
  3. Re-run the setup command so the module grants the roles
  4. Wait a few minutes for the initial scan
Possible causes:
  • Entra has not finished replicating the new federated identity credential
Solution:Wait a few minutes and let the next discovery run retry. A new credential can take a moment to become usable, so the first token exchange may fail with AADSTS70021 even though setup succeeded.
Possible causes:
  • Blob Storage access not enabled on the integration
  • The target account is not in the blob_storage_accounts allowlist
  • Log integration not configured
Solution:
  1. Confirm allow_blob_access is enabled on the Cloud Account
  2. Add the account to blob_storage_accounts, or leave the list empty to allow all accounts in scope
  3. Create a Log Integration pointing to this cloud integration

Next Steps

Log Integration

Forward logs to Blob Storage

Add Resources

Manually configure discovered resources

Terraform

Manage integrations as code

View Resources

See all autodiscovered resources