The Crossplane Azure Provider lets you manage Azure resources declaratively using Kubernetes.

Let’s get this thing installed and talking to Azure. First, you need a Kubernetes cluster. If you don’t have one, kind is a great way to spin one up locally for testing.

kind create cluster --name crossplane-azure-demo

Now, we need to install Crossplane itself into this cluster. We’ll use Helm for this.

helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane --namespace crossplane-system --create-namespace crossplane-stable/crossplane

This sets up the core Crossplane controllers. They’ll be watching for custom resources that define cloud infrastructure.

Next, we need to tell Crossplane how to talk to Azure. This is done via a ProviderConfig. But before we can create that, Crossplane needs credentials. The Azure provider uses a service principal.

You can create one manually in Azure, or use the Azure CLI. Using the CLI is often simpler for initial setup.

az ad sp create-for-rbac --name crossplane-azure-provider --role Contributor --scopes /subscriptions/<YOUR_AZURE_SUBSCRIPTION_ID>

This command will output JSON containing appId (client ID), password (client secret), and tenant (tenant ID). Keep the password secure!

Now, let’s create the Kubernetes secret that Crossplane will use to authenticate with Azure. Replace the placeholders with the values from the az ad sp create-for-rbac output.

apiVersion: v1
kind: Secret
metadata:
  name: azure-credentials
  namespace: crossplane-system
type: Opaque
stringData:
  credentials: |
    {
      "tenantId": "<YOUR_TENANT_ID>",
      "clientId": "<YOUR_CLIENT_ID>",
      "clientSecret": "<YOUR_CLIENT_SECRET>"
    }

Apply this secret to your cluster:

kubectl apply -f azure-credentials-secret.yaml

With the secret in place, we can create the ProviderConfig resource. This tells the Azure provider which credentials to use and which Azure subscription to manage resources in.

apiVersion: azure.crossplane.io/v1alpha5
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: azure-credentials
      key: credentials
  subscriptionID: <YOUR_AZURE_SUBSCRIPTION_ID>

Apply this configuration:

kubectl apply -f providerconfig.yaml

Finally, we need to install the Azure provider itself. This is done by creating a Provider resource.

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-azure
spec:
  package: xpkg.upbound.io/upbound/provider-azure:v0.37.0 # Check for latest version

Apply this:

kubectl apply -f provider.yaml

Crossplane will now pull the provider image, start the necessary pods, and register the Azure provider with your Kubernetes API. You can check the status of the provider installation:

kubectl get providers

You should see provider-azure with a status of Healthy. If not, check the logs of the provider-azure pod in the crossplane-system namespace.

The Azure provider is now configured and ready to provision Azure resources. You can start defining these resources using Crossplane’s Composite Resources (XRs) and Composed Resources (Claims).

The next step is to define a CompositeResourceDefinition (XRD) for something like a managed PostgreSQL instance, which will then be claimable by your applications.

Want structured learning?

Take the full Crossplane course →