Deploying Collibra Unstructured AI infrastructure on Azure

Deploying Unstructured AI infrastructure involves setting up the necessary resources in your cloud environment to support advanced AI applications. This page provides instructions for deploying Unstructured AI infrastructure on Microsoft Azure. It guides you through the necessary prerequisites, configuration, deployment steps, and teardown, ensuring a successful setup.

Prerequisites

Before deployment, ensure the following resources and configurations are in place in your Azure subscription.

Expected final state

Resource Description Example value
User/Service Principal Must have sufficient Azure RBAC permissions. See the required Azure permissions section below.
Storage Account + Container For Terraform state file. deasytfstate / tfstate
Resource Group (State) Contains the storage account. rg-deasy-mgmt-dev
Resource Group (Infrastructure) Where AKS, DB, and networking are deployed. rg-deasy-infra-dev
Resource Group (DNS) Contains the DNS zone. rg-deasy-dns
Azure AD Group Grants AKS cluster admin permissions. unstructured-aks-admins
DNS Zone Azure DNS zone for ingress records. env-id.company.com
Key Vault Stores the TLS certificate. unstructured-certs-kv
TLS Certificate Stored as a Certificate object in Key Vault. deasy-dev-app-cert

Required Azure permissions

The provisioning identity (user or service principal running Terraform) requires different permissions depending on your deployment scenario.

Step 1: Identify your scenario

Scenario Description
Standard Terraform creates all networking.
BYOVNet You provide an existing VNet and subnets for VPN-only access.

Step 2: Create custom roles (BYOVNet only)

Skip this step if you are not using BYOVNet. This custom role is only needed when deploying into a customer-provided VNet.

Copy
# Set subscription ID
SUBSCRIPTION_ID="<your-subscription-id>"

# Custom Role: Unstructured Network Integrator
# Allows joining subnets for AKS/DB and writing subnet config (for NSG association)

az role definition create --role-definition "{
  \"Name\": \"Unstructured Network Integrator\",
  \"Description\": \"Can join, read, and write subnets for AKS and database deployment\",
  \"Actions\": [
    \"Microsoft.Network/virtualNetworks/subnets/join/action\",
    \"Microsoft.Network/virtualNetworks/subnets/read\",
    \"Microsoft.Network/virtualNetworks/subnets/write\"
  ],
  \"NotActions\": [],
  \"AssignableScopes\": [\"/subscriptions/$SUBSCRIPTION_ID\"]
}" 

Note If you prefer not to create a custom role, you can use the built-in Network Contributor role scoped to the AKS and DB subnets instead. This grants broader permissions but is limited to those specific subnets.

Step 3: Grant permissions for your scenario

View required permissions

Role Scope Purpose
Contributor Infrastructure RG Create, update, and delete AKS, DB, networking, and Key Vaults.
Contributor AKS Node RG Create pre-allocated public IP for Front Door origin (public mode only).
Key Vault Secrets Officer Infrastructure RG Create secrets in API and DB Key Vaults.
Role Based Access Control Administrator (conditioned) Infrastructure RG Assign Key Vault roles to workload identities and Network Contributor to AKS identity.
DNS Zone Contributor DNS Zone Create and manage DNS records (TXT validation, CNAME, A records).
Reader Terraform state storage account Read storage account properties (required for Azure AD authentication).
Storage Blob Data Contributor Terraform state container Read and write Terraform state blobs.
Key Vault Certificate User TLS certificate (specific) Read the TLS certificate for HTTPS ingress.

Setup commands:

Copy
# Get your provisioner's object ID
PROVISIONER_ID=$(az ad signed-in-user show --query id -o tsv)
# Or for a service principal:
# PROVISIONER_ID=$(az ad sp show --id <app-id> --query id -o tsv)

# Set your values
SUBSCRIPTION_ID="<your-subscription-id>"
INFRA_RG="rg-deasy-infra-dev"
AKS_NODE_RG="rg-deasy-infra-dev-aks-nodes"   # must match aks_node_resource_group in config.yaml
STATE_RG="rg-deasy-mgmt-dev"
STATE_ACCOUNT="deasytfstate"
STATE_CONTAINER="tfstate"
DNS_RG="rg-deasy-dns"
DNS_ZONE="env-id.company.com"
TLS_KV_NAME="<tls-keyvault-name>"
TLS_CERT_NAME="<certificate-name>"

# Built-in role definition IDs (for ABAC conditions)
KV_SECRETS_USER_ID="4633458b-17de-408a-b874-0445c86b69e6"
KV_SECRETS_OFFICER_ID="b86a8fe4-44ce-4948-aee5-eccb2c155cd7"
READER_ID="acdd72a7-3385-48ef-bd42-f606fba81ae7"
NET_CONTRIBUTOR_ID="4d97b98b-1d4f-4787-a291-c67834d212e7"

# Infrastructure Resource Group
az role assignment create --assignee $PROVISIONER_ID \
  --role "Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$INFRA_RG"

# AKS Node Resource Group: provisioner needs Contributor to pre-allocate the
# public IP for Front Door (public/standard mode only)
az role assignment create --assignee $PROVISIONER_ID \
  --role "Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$AKS_NODE_RG"

# Key Vault Secrets Officer
az role assignment create --assignee $PROVISIONER_ID \
  --role "Key Vault Secrets Officer" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$INFRA_RG"

# RBAC Admin with condition
az role assignment create --assignee $PROVISIONER_ID \
  --role "Role Based Access Control Administrator" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$INFRA_RG" \
  --condition-version "2.0" \
  --condition "((!(ActionMatches{'Microsoft.Authorization/roleAssignments/write'})) OR (@Request[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {$KV_SECRETS_USER_ID, $KV_SECRETS_OFFICER_ID, $READER_ID, $NET_CONTRIBUTOR_ID}))"

# Reader on storage account
az role assignment create --assignee $PROVISIONER_ID \
  --role "Reader" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$STATE_RG/providers/Microsoft.Storage/storageAccounts/$STATE_ACCOUNT"

# Storage Blob Data Contributor on container
az role assignment create --assignee $PROVISIONER_ID \
  --role "Storage Blob Data Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$STATE_RG/providers/Microsoft.Storage/storageAccounts/$STATE_ACCOUNT/blobServices/default/containers/$STATE_CONTAINER"

# DNS Zone Contributor
az role assignment create --assignee $PROVISIONER_ID \
  --role "DNS Zone Contributor" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$DNS_RG/providers/Microsoft.Network/dnsZones/$DNS_ZONE"

# Key Vault Certificate User
az role assignment create --assignee $PROVISIONER_ID \
  --role "Key Vault Certificate User" \
  --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$INFRA_RG/providers/Microsoft.KeyVault/vaults/$TLS_KV_NAME/certificates/$TLS_CERT_NAME"

# AKS Cluster Admin (must be granted by an owner — cannot be self-assigned)
AKS_CLUSTER_ID=$(az aks show --resource-group $INFRA_RG --name unstructured-aks-cluster --query id --output tsv)
az role assignment create --assignee $PROVISIONER_ID \
  --role "Azure Kubernetes Service RBAC Cluster Admin" \
  --scope "$AKS_CLUSTER_ID" 

View BYOVNet additional permissions

Customer prerequisites for BYOVNet:

  1. VNet with AKS and DB subnets. The address space must not overlap with the AKS service CIDR (default 172.20.0.0/16, configurable via aks_service_cidr).
  2. DB Subnet delegation to Microsoft.DBforPostgreSQL/flexibleServers.
  3. Private DNS Zone for PostgreSQL (format: <db-name>.private.postgres.database.azure.com).
  4. VNet Link connecting the private DNS zone to the VNet.

Additional permissions required:

Role Scope Purpose
Network Integrator (custom) AKS Subnet Join AKS nodes to subnet.
Network Integrator (custom) DB Subnet Join PostgreSQL to subnet and NSG association.
Role Based Access Control Administrator (conditioned) AKS Subnet Grant AKS identity Network Contributor for internal load balancer creation.

Setup commands (in addition to standard permissions):

Copy
# Set your BYOVNet resource IDs
AKS_SUBNET_ID="<full-resource-id-of-aks-subnet>"
DB_SUBNET_ID="<full-resource-id-of-db-subnet>"
# Example format:
# /subscriptions/<sub>/resourceGroups/<vnet-rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>

# Network Integrator on AKS subnet
az role assignment create --assignee $PROVISIONER_ID \
  --role "Network Integrator" \
  --scope "$AKS_SUBNET_ID"

# Network Integrator on DB subnet
az role assignment create --assignee $PROVISIONER_ID \
  --role "Network Integrator" \
  --scope "$DB_SUBNET_ID"

# RBAC Admin for AKS internal load balancer
NET_CONTRIBUTOR_ID="4d97b98b-1d4f-4787-a291-c67834d212e7"

az role assignment create --assignee $PROVISIONER_ID \
  --role "Role Based Access Control Administrator" \
  --scope "$AKS_SUBNET_ID" \
  --condition-version "2.0" \
  --condition "((!(ActionMatches{'Microsoft.Authorization/roleAssignments/write'})) OR (@Request[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {$NET_CONTRIBUTOR_ID}))" 

Permission summary by resource location

Resource Location Role Least-privilege method
AKS, DB, Key Vaults Infrastructure RG Contributor Create, update, and delete resources.
Key Vault Secrets Infrastructure RG Key Vault Secrets Officer Create secrets in API/DB Key Vaults.
Role assignments Infrastructure RG RBAC Admin (conditioned) Constrained to Key Vault Secrets User/Officer, Reader, and Network Contributor.
Terraform state State storage account Reader Read storage account properties for Azure AD authentication.
Terraform state State container Storage Blob Data Contributor Scoped to specific container for state blobs.
DNS zone records DNS Zone DNS Zone Contributor Create TXT validation record, CNAME (public mode) or A record (BYOVNet mode).
TLS Certificate Infrastructure RG Key Vault Certificate User Scoped to specific certificate.
AKS Cluster Infrastructure RG Azure Kubernetes Service RBAC Cluster Admin Required for Azure AD RBAC-enabled clusters; cannot be self-assigned.
BYOVNet AKS Subnet Customer VNet Network Integrator Custom role (subnet join for AKS).
BYOVNet DB Subnet Customer VNet Network Integrator Custom role (subnet join and NSG association).
BYOVNet AKS Subnet Customer VNet RBAC Admin (conditioned) Constrained to Network Contributor only (for internal load balancer).

Instructions for creating prerequisite resources

Storage account for Terraform state

Terraform state must be stored in an Azure Storage Account with a blob container.

Copy
# Create resource group for management resources
az group create --name rg-deasy-mgmt-dev --location centralus

# Create storage account
az storage account create \
  --name deasytfstate \
  --resource-group rg-deasy-mgmt-dev \
  --location centralus \
  --sku Standard_LRS \
  --encryption-services blob

# Create blob container for state file
az storage container create \
  --name tfstate \
  --account-name deasytfstate

Record these values in config.yaml under the state: block. The configure tool generates backend.hcl from them. Do not edit providers.tf directly.

Copy
state:
  resource_group:   "rg-deasy-mgmt-dev"
  storage_account:  "deasytfstate"
  container:        "tfstate"
  key:              "collibra/unstructured/terraform.tfstate" 

Resource groups

Three resource groups are required:

Resource group Purpose
rg-deasy-mgmt-dev Terraform state storage account.
rg-deasy-infra-dev AKS cluster, database, networking, and Key Vaults.
rg-deasy-dns DNS zone.
Copy
az group create --name rg-deasy-mgmt-dev --location centralus
az group create --name rg-deasy-infra-dev --location centralus
az group create --name rg-deasy-dns --location centralus

Azure AD group for AKS admins

An Azure AD security group is required to grant cluster admin permissions to users.

Copy
# Create the unstructured-aks-admins group
az ad group create --display-name "unstructured-aks-admins" --mail-nickname "unstructured-aks-admins"

# Add users to the group (get user object ID first)
az ad user show --id [email protected] --query id -o tsv
az ad group member add --group "unstructured-aks-admins" --member-id <user-object-id>

DNS zone

Copy
az network dns zone create \
  --resource-group rg-deasy-dns \
  --name env-id.company.com

Important After creating the zone, delegate your domain to Azure DNS by updating your domain registrar's nameservers to the Azure DNS nameservers:

Copy
az network dns zone show \
  --resource-group rg-deasy-dns \
  --name env-id.company.com \
  --query nameServers

Key Vault with TLS certificate

A Key Vault containing the TLS certificate is required for HTTPS ingress. The certificate must meet the following requirements:

  • Must be stored as a Certificate object in Key Vault.
  • Must use PEM content type (application/x-pem-file), required by ESO's filterPEM for NGINX TLS secret sync.
  • Must include the full certificate chain (leaf, intermediate, and root CA).
  • Must match the domain specified in tls_cert_domain, for example app.env-id.company.com.

Set up Key Vault:

Copy
az keyvault create \
  --name unstructured-certs-kv \
  --resource-group rg-deasy-infra-dev \
  --location centralus \
  --enable-rbac-authorization true

Import certificate:

Import a PEM certificate from a CA (GoDaddy, DigiCert, Let's Encrypt, and so on):

Copy
# PEM file — import directly
az keyvault certificate import \
  --vault-name unstructured-certs-kv \
  --name app-tls-cert \
  --file /path/to/certificate.pem

# PFX file — convert to PEM first, then import with PEM policy
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes -password pass:<pfx-password>
az keyvault certificate import \
  --vault-name unstructured-certs-kv \
  --name app-tls-cert \
  --file certificate.pem \
  --policy '{"secretProperties":{"contentType":"application/x-pem-file"}}'

View example: Azure-managed certificate via App Service

Azure can manage certificate creation and renewal through App Service Certificates:

  1. Create an App Service Certificate in the Azure Portal: go to "App Service Certificates" > Create, select Standard SKU, enter your subdomain in the "Naked domain hostname" field (for example, app.env-id.company.com), and enter a certificate name.
  2. Verify domain ownership by adding a TXT record to the DNS zone of your root domain:
  3. Copy
    # If root domain exists within DNS Zone in Azure
    az network dns record-set txt add-record \
      --resource-group rg-deasy-dns \
      --zone-name dev-azure.deasylabs.io \
      --record-set-name app \
      --value "<verification-token-from-azure>" 
  4. Export and import to Key Vault once verified: in App Service Certificate, go to Export > Download as PFX, then import to Key Vault using the command above.

AWS credentials for ECR access

Helm charts and container images are pulled from AWS ECR. AWS credentials with ECR read access are provided to you. The access key ID is non-sensitive and lives in config.yaml under aws.access_key. The secret access key is never written to disk; terraform apply prompts for it interactively at run time.

Copy
# config.yaml
aws:
  access_key: "<provided-access-key>" 

Note If byor: is set in config.yaml, Terraform does not prompt for AWS credentials.

Prerequisites

Before running the configure tool, verify that the following prerequisites are met:

  • Azure CLI is installed and authenticated (az login).
  • kubelogin is installed (required for AKS Azure AD RBAC authentication).
  • Go is installed to build the configure binary.
  • Subscription is set via export ARM_SUBSCRIPTION_ID="<subscription-id>".
  • The provisioning identity has the required RBAC roles.
  • Storage account and container exist for Terraform state.
  • All three resource groups exist.
  • The unstructured-aks-admins Azure AD group exists.
  • DNS zone exists and the domain is delegated.
  • Key Vault exists with the TLS certificate stored as a Certificate object.
  • AWS access key ID is set in config.yaml under aws.access_key.
  • config.yaml is populated from config.yaml.example.

Azure Entra ID integration setup

Configure Microsoft Entra ID (formerly Azure AD) for application authentication, including app registration, API permissions, and custom user attributes.

Prerequisites

The provisioning identity must have the Administrator or Application Administrator role in your Azure Entra ID tenant.

Expected final state

Resource Description Example value
App Registration Entra ID application for authentication. unstructured-ai
Client Secret Application credential (time-limited). 12-month expiry, stored securely.
API Permissions Microsoft Graph permissions (admin-consented). User.ReadWrite.All, Group.ReadWrite.All, Directory.ReadWrite.All
Extension Attributes Custom user properties. tenant_name, permission_level
Optional Claims Token claim configuration. Extension attributes included in ID tokens.

1. App registration

  1. Navigate to the Azure Portal and search for "Microsoft Entra ID" in the search bar.
  2. In the left sidebar, expand "Manage" and click "App registrations".
  3. Click "+ New registration" at the top.
  4. Fill in the registration details:
    • Name: unstructured-ai (or your preferred application name).
    • Supported account types: Select "Accounts in this organizational directory only (<your-org-name> - Single tenant)".
    • Redirect URI (optional): Set the platform to "Single-page application (SPA)" and enter your URL.
  5. Click "Register".
  6. After registration, note the following values from the "Overview" page:
Value Description
Application (client) ID Unique identifier for the application (used in app configuration).
Directory (tenant) ID Your Azure AD tenant identifier.
Object ID Application object identifier used in Graph API calls (different from the client ID).

Note The Object ID and Application (client) ID are different values. Graph API extension endpoints use the Object ID, while your application configuration uses the client ID.

2. Configure redirect URIs

  1. In your App Registration, go to "Authentication" under "Manage".
  2. Under "Single-page application", add the following redirect URIs: add your production URL as needed, for example https://app.<your-domain>.
  3. Under "Implicit grant and hybrid flows", ensure "ID tokens" is selected (required for OpenID Connect sign-in).
  4. Click "Save".

3. Create client secret

  1. In your App Registration, go to "Certificates & secrets" under "Manage".
  2. Click the "Client secrets" tab.
  3. Click "+ New client secret".
  4. Fill in the details:
    • Description: unstructured-ai-secret.
    • Expires: 365 days (12 months) or your preferred expiration.
  5. Click "Add".
  6. Copy the "Value" immediately after creation.
Field Value
Secret ID <auto-generated>
Value <copy this immediately>
Expires <selected expiration date>

Important Copy the client secret Value immediately after creation. It will be permanently hidden once you navigate away from this page. Store it securely and never commit it to version control.

4. Request API permissions

  1. In your App Registration, go to "API permissions" under "Manage".
  2. Click "+ Add a permission".
  3. Select "Microsoft Graph" > "Application permissions".
  4. Add the following permissions:
Permission Type Purpose
User.ReadWrite.All Application Create, read, update, and delete users.
Group.ReadWrite.All Application Create, read, update, and delete groups.
Directory.ReadWrite.All Application Manage directory extension attributes (tenant_name, permission_level, group_memberships).
  1. Click "Add permissions" after selecting each permission.
  2. Click "Grant admin consent for <your-org-name>" to approve the application permissions.

Note If you are not an admin, request that a Global Administrator or Privileged Role Administrator grants admin consent on your behalf.

5. Register extension attributes

Extension attributes allow you to add custom properties to user objects (for example, tenant_name and permission_level) that can be included as claims in tokens.

5.1 Register extension attributes via Microsoft Graph API

Use Microsoft Graph Explorer or the Azure CLI to register the extension attributes.

Register tenant_name extension:

Copy
POST https://graph.microsoft.com/v1.0/applications/<application-object-id>/extensionProperties
Content-Type: application/json

{
  "name": "tenant_name",
  "dataType": "String",
  "targetObjects": ["User"]
}

Register permission_level extension:

Copy
POST https://graph.microsoft.com/v1.0/applications/<application-object-id>/extensionProperties
Content-Type: application/json

{
  "name": "permission_level",
  "dataType": "String",
  "targetObjects": ["User"]
}

Note Use the Object ID from the App Registration Overview page, not the Application (client) ID.

5.2 Set extension attribute values on users

To set permission_level and tenant_name for a user:

Copy
PATCH https://graph.microsoft.com/v1.0/users/<user-object-id>
Content-Type: application/json

{
  "extension_<client_id_no_hyphens>_tenant_name": "<your-org-name>",
  "extension_<client_id_no_hyphens>_permission_level": "admin"
}

Extension attribute name format:

The naming convention is: extension_{clientIdWithoutHyphens}_{attributeName}

For example, if your Application (client) ID is b856c7cf-fd05-4476-a276-d297108eb230:

  • Remove hyphens: b856c7cffd054476a276d297108eb230.
  • Full attribute name: extension_b856c7cffd054476a276d297108eb230_tenant_name.

Valid permission_level values:

Permission level Description
admin Full access; can manage tenants, users, and all settings.
viewer Read-only access; can view but not modify resources.

6. Configure token claims (optional)

To include extension attributes in ID tokens issued to users:

  1. In your App Registration, go to "Token configuration" under "Manage".
  2. Click "+ Add optional claim".
  3. Select the ID token type.
  4. Add claims or configure via "Manifest".

Alternatively, edit the "Manifest" directly to add:

Copy
{
  "optionalClaims": {
    "idToken": [
      {
        "name": "extension_<client_id_no_hyphens>_tenant_name",
        "source": "user",
        "essential": false
      },
      {
        "name": "extension_<client_id_no_hyphens>_permission_level",
        "source": "user",
        "essential": false
      }
    ]
  }
}

Note Replace <client_id_no_hyphens> with your Application (client) ID with hyphens removed (see the naming convention in step 5.2).

Deployment

Once all prerequisites are in place, deployment is driven by the configure tool in tools/configure/azure. It reads config.yaml, validates inputs, and generates terraform.auto.tfvars and backend.hcl. Both files are auto-generated and must not be edited by hand. For BYOR deployments, it also mirrors images from the source registry into your customer registry.

Run all commands below from iac/azure/:

Copy
cd iac/azure

1. Authenticate and set environment

Copy
# Log in to Azure
az login

# Set subscription (environment variable is more reliable than az account set)
export ARM_SUBSCRIPTION_ID="<subscription-id>" 

2. Populate config.yaml

Copy
cp config.yaml.example config.yaml
# Edit config.yaml with your values (see config.yaml.example for field documentation)

3. Build and run configure

Copy
go build -C ../../tools/configure -o ../../iac/azure/configure ./azure
./configure

This generates terraform.auto.tfvars and backend.hcl. If a customer registry is configured, it also mirrors images.

4. Initialize and apply

Copy
terraform init -backend-config=backend.hcl
terraform plan
terraform apply

terraform apply prompts for client_secret (Entra app secret) and aws_secret_access_key. Neither is stored on disk.

The deployment takes approximately 15 to 20 minutes and creates:

  • AKS cluster with NGINX ingress and Azure Front Door (standard mode) or internal load balancer (BYOVNet mode).
  • PostgreSQL Flexible Server.
  • Networking (VNet, subnets, NSGs).
  • Linkerd service mesh.
  • Backend and frontend applications.
  • DNS records managed by Terraform.

Note After terraform apply completes, Azure Front Door may take an additional up to 30 minutes to fully propagate the managed TLS certificate to all edge PoPs. The site returns 404 or a certificate mismatch warning until propagation completes. This is part of Azure's CDN pipeline, not an infrastructure issue.

5. Verify deployment

Copy
# Get AKS credentials
az aks get-credentials \
  --resource-group rg-deasy-infra-dev \
  --name <aks-cluster-name>

# Check pod status
kubectl get pods -n unstructured

# Verify ingress
kubectl get ingress -n unstructured

Your application should be accessible at https://app.env-id.company.com or your configured domain.

Teardown

Key Vault lock

If the TLS certificate Key Vault has a resource lock, you must remove it before destruction:

Copy
# List locks on the Key Vault
az lock list --resource-group rg-deasy-infra-dev \
  --resource-name unstructured-certs-kv \
  --resource-type Microsoft.KeyVault/vaults

# Delete the lock (replace <lock-name> with the actual name)
az lock delete --name <lock-name> \
  --resource-group rg-deasy-infra-dev \
  --resource-name unstructured-certs-kv \
  --resource-type Microsoft.KeyVault/vaults

To destroy all resources, use the destroy subcommand of the configure tool. It uninstalls workloads, drains Karpenter nodes, and then runs terraform destroy. Run from iac/azure/:

Copy
./configure destroy

The destroy flow prompts for the Entra app client secret and is not stored on disk. Azure provider authentication uses your existing az login session and ARM_* environment variables.

Note Helm may warn about "kept CRDs" during teardown. These are deleted when the cluster is destroyed.