XWebApplication¶
Experimental
This API is experimental and may change without notice.
A complete Azure web application environment with a resource group, PostgreSQL database, Linux App Service, and Key Vault-backed database credential. Microsoft Entra ID authentication can be enabled with an automatically managed enterprise application and rotating client secret.
API¶
| Property | Value |
|---|---|
| Group | environments.platform.example.org |
| Kind | XWebApplication |
| Plural | xwebapplications |
| Scope | Namespaced |
| Versions | v1alpha1 (referenceable) |
| Source | compositions/apis/environments/webapplication/schema.yaml |
Spec¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
appSize |
string |
yes | — | App Service t-shirt size. One of: small, medium, large. |
customDomain |
object |
no | — | Optional custom hostname for the App Service, with DNS records in an existing Azure public DNS zone and a free managed certificate. |
customDomain.dnsZone |
string |
yes | — | Existing Azure public DNS zone name. |
customDomain.dnsZoneResourceGroup |
string |
yes | — | Resource group holding the DNS zone. |
customDomain.hostname |
string |
yes | — | Fully qualified hostname inside dnsZone, e.g. portal.example.com. |
databaseAdminUsername |
string |
no | pgadmin |
PostgreSQL administrator login name. |
databaseName |
string |
no | — | PostgreSQL database name. Defaults to spec.name. |
databaseSize |
string |
yes | — | PostgreSQL t-shirt size. One of: small, medium, large. |
databaseSkuName |
string |
no | `` | Optional PostgreSQL compute SKU override passed to XDatabase.skuName. Empty uses databaseSize; storage still follows databaseSize. Check regional support and capacity before changing. Constraints: pattern: ^((B|GP|MO)Standard[A-Za-z0-9_]+)?$. |
entraIdAuth |
object |
no | {} |
Optional Microsoft Entra ID authentication for the application. When enabled, an XEnterpriseApp and rotating client credential are provisioned automatically. |
entraIdAuth.additionalRedirectUris |
[]string |
no | [] |
Additional OAuth redirect URIs, such as the Backstage localhost callback used during development. |
entraIdAuth.enabled |
boolean |
no | false |
Enable Entra ID authentication. |
image |
string |
yes | — | Container image reference run by App Service. |
location |
string |
yes | — | Azure region for every environment resource. |
name immutable |
string |
yes | — | Short environment name used to derive Azure resource names. Constraints: minLength: 1, maxLength: 12, pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$. |
port |
integer |
no | 8080 |
Port the application container listens on. Constraints: min: 1, max: 65535. |
Fields marked immutable are fixed once the resource is created; changing one is rejected by the API server. An immutable object pins the fields nested under it too. To change one, delete the resource and create it again.
Example¶
The platform generates the database password and exposes it to App Service through an Azure Key Vault reference. PostgreSQL permits Azure service IPs so the public App Service can connect. The app receives its public URL in APPLICATION_URL. databaseSkuName optionally overrides database compute while databaseSize continues to determine storage. Set the optional customDomain to serve the app on a hostname in an existing Azure DNS zone with a managed certificate. Set entraIdAuth.enabled to create an XEnterpriseApp; its client secret rotates every 30 days and is copied into the environment Key Vault. Disabling authentication still provisions the App Service. Ready and the EnvironmentReady condition remain false until every required resource, including enabled authentication resources, is ready. EnvironmentReady lists pending resources. The generated Key Vault reference includes the current secret version so App Service configuration refreshes after rotation.
---
apiVersion: environments.platform.example.org/v1alpha1
kind: XWebApplication
metadata:
name: webdemo01
spec:
name: webdemo01
image: docker.io/library/nginx:latest
location: swedencentral
appSize: small
databaseSize: small
databaseSkuName: B_Standard_B2s
port: 80
Taken from teams/crd-dev/webapplication.yaml,
which is applied to the cluster by Flux, so it cannot drift from a working
manifest.
Status¶
Populated by Crossplane once the underlying Azure resources exist. Every
composite in this repository exposes the provisioned Azure resource ID as
status.id.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
applicationHostname |
string |
no | — | Default public hostname of the App Service. |
applicationId |
string |
no | — | Azure resource ID of the App Service. |
applicationUrl |
string |
no | — | Public HTTPS URL of the application: the custom hostname when set, otherwise the default hostname. |
databaseFqdn |
string |
no | — | Fully qualified domain name of the PostgreSQL server. |
databaseId |
string |
no | — | Azure resource ID of the PostgreSQL server. |
enterpriseApplicationClientId |
string |
no | — | Application (client) ID used for OAuth. |
enterpriseApplicationId |
string |
no | — | Provider ID of the Entra application. |
id |
string |
no | — | Azure resource ID of the environment resource group. |
resourceGroupId |
string |
no | — | Azure resource ID of the environment resource group. |
Common problems¶
A Key Vault RoleAssignment reports that changing role_definition_id requires replacing the resource.
Cause. Azure returns a subscription-qualified role definition ID while the desired ID omits the subscription prefix.
Fix. Use the subscription-qualified role definition ID from azure-platform-config.data.subscriptionId for both Key Vault roles. The corrected ID matches the existing assignment without recreating it.
The enterpriseApp resource reports Authorization_RequestDenied.
Cause. The Crossplane service principal lacks Application.ReadWrite.All or its Microsoft Graph admin consent.
Fix. Re-run the cluster bootstrap as a Global Administrator or Privileged Role Administrator.
Backstage reports an invalid or expired Microsoft client secret.
Cause. Credential rotation has started but the new Key Vault version or App Service setting has not reconciled yet.
Fix. Check XEnterpriseApp, the entra-client-secret XKeyVaultSecret, and the App Service reconciliation. This demo accepts a short rotation race instead of maintaining two active credentials.