Azure Sites logo

Backstage Azure Sites Plugin

Created by FRISS

Azure Sites in Azure App Service covers web apps and function apps. These run your APIs, jobs, and sites on a managed platform. The Backstage Azure Sites plugin brings those apps into your service catalog so you can see what is running without leaving Backstage.

The plugin adds an overview for each catalog entity that matches your Azure apps. It shows key details like name, state, location, and tags. From that view you can jump straight to the Azure Portal overview page or the log stream for quick triage. This keeps common checks in one place and reduces portal tab chasing during incidents.

Teams use it when they have many functions or web apps spread across regions or subscriptions. It helps during deploys when you want a simple status pulse across related apps. It helps during on call when you need one click into portal logs. Actions to start or stop an app can be protected by the Backstage permissions framework so operators can keep control while giving others read access. The plugin lives in the community plugins repo which continues to evolve with Backstage.

Installation Instructions

These instructions apply to self-hosted Backstage only.

Install the frontend package

  1. From your Backstage root, add the package to the app
Copy
yarn --cwd packages/app add @backstage-community/plugin-azure-sites

Register the frontend API client

  1. Create the API factory so the widget can call the backend
Copy
// packages/app/src/apis.ts
import {
  createApiFactory,
  discoveryApiRef,
  identityApiRef,
} from '@backstage/core-plugin-api';
import {
  azureSiteApiRef,
  AzureSitesApiBackendClient,
} from '@backstage-community/plugin-azure-sites';

// add to the exported apis array
export const apis = [
  // other factories
  createApiFactory({
    api: azureSiteApiRef,
    deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
    factory: ({ discoveryApi, identityApi }) =>
      new AzureSitesApiBackendClient({ discoveryApi, identityApi }),
  }),
];

Add the widget to the entity page

  1. Add the tab and widget so users can see Azure Sites on an entity
Copy
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
  EntityAzureSitesOverviewWidget,
  isAzureWebSiteNameAvailable,
} from '@backstage-community/plugin-azure-sites';

const serviceEntityPage = (
  <EntityLayout>
    {/* other routes */}
    <EntityLayout.Route
      if={e => Boolean(isAzureWebSiteNameAvailable(e))}
      path="/azure"
      title="Azure"
    >
      <EntityAzureSitesOverviewWidget />
    </EntityLayout.Route>
    {/* other routes */}
  </EntityLayout>
);

export default serviceEntityPage;

Install the backend plugin on the new backend system

The backend plugin supports the new backend system.

  1. Add the backend feature to your backend index file
Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

// other feature additions

backend.add(import('@backstage-community/plugin-azure-sites-backend'));

// other feature additions

backend.start();
  1. Add configuration in your app config
Copy
# app-config.yaml
azureSites:
  domain: your-domain.onmicrosoft.com
  tenantId: your-tenant-id
  clientId: your-app-registration-client-id
  clientSecret: ${AZURE_SITES_CLIENT_SECRET}
  allowedSubscriptions:
    - id: your-subscription-id-one
    - id: your-subscription-id-two

Notes
Use the Azure Directory Overview page to find the tenant id.
The domain is visible in the Azure portal URL.
The app registration needs rights to read your web apps and function apps.
Use environment variables for secrets in production.

Optional permission policy for start and stop

These actions are protected by the permissions framework. This example allows only entity owners to start or stop.

Copy
// packages/backend/src/plugins/permission.ts
import {
  AuthorizeResult,
  isPermission,
  PolicyDecision,
  PolicyQuery,
  PermissionPolicy,
} from '@backstage/plugin-permission-node';
import {
  createCatalogConditionalDecision,
  catalogConditions,
} from '@backstage/plugin-catalog-backend/alpha';
import { BackstageIdentityResponse } from '@backstage/plugin-auth-node';
import { azureSitesActionPermission } from '@backstage-community/plugin-azure-sites-common';

class PermissionPolicyImpl implements PermissionPolicy {
  async handle(
    request: PolicyQuery,
    user?: BackstageIdentityResponse,
  ): Promise<PolicyDecision> {
    if (isPermission(request.permission, azureSitesActionPermission)) {
      return createCatalogConditionalDecision(
        request.permission,
        catalogConditions.isEntityOwner({
          claims: user?.identity.ownershipEntityRefs ?? [],
        }),
      );
    }

    return { result: AuthorizeResult.ALLOW };
  }
}

export default new PermissionPolicyImpl();

Wire this policy into your permission plugin setup, following your backend pattern.

Catalog entity annotation

Add this annotation to each entity you want to show in the Azure tab.

Copy
metadata:
  annotations:
    azure.com/microsoft-web-sites: my-site-name

The value can be a full name or a partial name. Partial name matches are case insensitive. Example names

Copy
func-testapp-eu
func-testapp-ca
func-testapp-us

Use this to match all three

Copy
metadata:
  annotations:
    azure.com/microsoft-web-sites: func-testapp

Legacy backend

This backend plugin works only with the new backend system. If your repo uses the old backend, migrate to the new backend system.

What the plugin exports on the frontend

Import these from the frontend package

Copy
import {
  EntityAzureSitesOverviewWidget,
  isAzureWebSiteNameAvailable,
  azureSiteApiRef,
  AzureSitesApiBackendClient,
} from '@backstage-community/plugin-azure-sites';

Place EntityAzureSitesOverviewWidget inside the Entity page layout as shown above.
Add the API factory in packages app apis as shown above.

Changelog

This changelog is produced from commits made to the Azure Sites plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

No new features in this period

Bug fixes

  • Include the config schema in the package for proper validation #2920 Merged 7 months ago

Documentation

  • Update README links to the community plugins repo to fix 404s #3931 Merged 4 months ago

Maintenance

  • Update to Backstage v1.38.1 #3848 Merged 5 months ago
  • Remove unused dev dependency canvas #3565 Merged 5 months ago
  • Reduce knip false positives in reports #3018 Merged 6 months ago
  • Remove usage of Backstage backend common in plugin code #2482 Merged 8 months ago

Deprecations

  • Deprecate the legacy backend for Azure Sites #2042 Merged 10 months ago

Set up Backstage in minutes with Roadie