Skip to main content

Using Upbound to build a platform above Azure

Upbound launched this week and we’re excited to see how platform teams begin building above the clouds with Upbound. Users beginning their journey in the product will notice the Get Started experience only offers launching managed control planes from Crossplane configurations built on AWS or GCP.

Does this mean users who want to build above Azure are out of luck? Not at all! While we work on building a configuration for Azure (coming soon!), this blog demonstrates how you can use the features & capabilities of Upbound to build a platform above Azure.

Complete the Get Started experience

Upbound’s Get Started experience must be completed before you can gain access to the Upbound Console. Once you reach the Console, you will be able to provision another managed control plane and create a GitHub-synced configuration where you will define your APIs for Azure. If you have not already completed the Get Started experience, “speed run” through it by selecting any of the configurations above, connect Upbound to your GitHub account, and give your first managed control plane a name.

Finally, when Upbound asks for parameters to connect Upbound to GCP or AWS, provide fake strings. Upbound uses these inputs to concoct a ProviderConfig for your managed control plane to connect to GCP or AWS. But we don’t care about this – we’re creating our own managed control plane for Azure!

Use the Upbound Console

Let’s get to work building a platform above Azure driven by an Upbound managed control plane. From Upbound Console start by creating a new configuration. Hover over the `Create Configuration` button and select `Start from Scratch`.

To create a new configuration from scratch, give your configuration a name (for example, “my-azure-platform-apis”), set the GitHub repo visibility to whichever you prefer, and click `Clone configuration to GitHub`. After the configuration is created, Upbound will take you to the overview screen for your new configuration. Confirm that Upbound created a repo for you (it should look something like “https://github.com//my-azure-platform-apis.git”


Navigate back to the dashboard of the Console by clicking the icon in the top navigation bar. Now, create a managed control plane by clicking `Create Control Plane`.

Select the configuration you created previously to install it on your new managed control plane. In the next screen, give your control plane a name (for example, “azure-control-plane”), and click `Create`.

You should now have a new managed control plane created and configured to install from a new “scratch” Crossplane configuration. The remaining steps you need to do are:

  • Author a new API for Azure resources in your git repo based on provider-azure
  • Deploy the new configuration with API to your managed control plane
  • Create a ProviderConfig for Azure on your managed control plane

Author your API

Go to the GitHub repository Upbound created for you in the previous step. Open the `crossplane.yaml` file and replace the contents with the following (gist reference):

apiVersion: meta.pkg.crossplane.io/v1alpha1
kind: Configuration
metadata:
  name: configuration-azure-platform
  annotations:
    meta.crossplane.io/maintainer: <replacewithyouremail>
    meta.crossplane.io/source: github.com/<replacewithyourgiturl>
    meta.crossplane.io/license: Apache-2.0
    meta.crossplane.io/description: |
      This configuration defines a set of Crossplane APIs for Azure resources
    meta.crossplane.io/readme: |
      This configuration defines a set of Crossplane APIs for Azure resources
spec:
  crossplane:
    version: ">=v1.7.0-0"
  dependsOn:
    - provider: xpkg.upbound.io/upbound/provider-azure
      version: ">=v0.30.0"

The important thing we have done above is take a dependency on provider-azure for this configuration. Next, create a folder called “apis” in the root of your repo. In the “apis” folder, create a folder called “blob”. In the blob folder, create a “definition.yaml” and “composition.yaml”. Your directory structure should look like this:

We are going to build an API for Azure Blob storage. To start, let’s define the shape of the API. Open the `definition.yaml` file and paste in the following (gist reference):

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xblobs.infrastructure.example.org
spec:
  group: infrastructure.example.org
  names:
    kind: XBlob
    plural: xblobs
  claimNames:
    kind: Blob
    plural: blobs
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                id:
                  type: string
                  description: "ID of this Blob that objects will use to refer to it."
                  minLength: 1
                  # Maximum key length in GCP is 40 characters. We are setting a 34 character
                  # limit to accomodate the generated hash suffix ('-' + 5 chars).
                  maxLength: 34
                parameters:
                  type: object
                  description: "Blob parameters."
                  properties:
                    resourcegroup:
                      type: string
                      description: "ID of a resource group to associate the blob with. Will create one with this name if not exists."
              required:
                - id
                - parameters
            status:
              type: object
              properties:
                subnetIds:
                  type: array
                  items:
                    type: string

Close and save the file. Next, open the `composition.yaml` file and paste in the following (gist reference):

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xblobs.infrastructure.example.org
  labels:
    provider: azure
spec:
  compositeTypeRef:
    apiVersion: infrastructure.example.org/v1alpha1
    kind: XBlob
  resources:
    - base: 
        apiVersion: azure.upbound.io/v1beta1
        kind: ResourceGroup
        spec:
          forProvider:
            location: westus
      patches:
        - fromFieldPath: spec.parameters.resourcegroup
          toFieldPath: metadata.annotations[crossplane.io/external-name]
    - base:
        apiVersion: storage.azure.upbound.io/v1beta1
        kind: Account
        metadata:
            name: storageaccount
        spec:
          forProvider:
            accountReplicationType: LRS
            accountTier: Standard
            location: westus
            resourceGroupNameSelector:
              matchControllerRef: true
            tags:
              provisioner: Upbound
          writeConnectionSecretToRef:
            name: blob-storage-account
            namespace: upbound-system
      patches:
        - fromFieldPath: spec.id
          toFieldPath: metadata.annotations[crossplane.io/external-name]
    - base:
        apiVersion: storage.azure.upbound.io/v1beta1
        kind: Container
        spec:
          forProvider:
            containerAccessType: private
            storageAccountNameSelector:
              matchControllerRef: true
      patches:
        - fromFieldPath: spec.id
          toFieldPath: metadata.annotations[crossplane.io/external-name]
          transforms:
            - type: string
              string:
                fmt: "%s-container"
        - fromFieldPath: spec.id
          toFieldPath: metadata.name
          transforms:
            - type: string
              string:
                fmt: "%s-container"
    - base:
        apiVersion: storage.azure.upbound.io/v1beta1
        kind: Blob
        spec:
          forProvider:
            storageAccountNameSelector:
              matchControllerRef: true
            storageContainerNameSelector:
              matchControllerRef: true
            type: Block
      patches:
        - fromFieldPath: spec.id
          toFieldPath: metadata.annotations[crossplane.io/external-name]

Save and close the file. Commit and push the changes to your repo on GitHub.

Deploy new configuration definition

Back on Upbound Console, click into your managed control plane for Azure. You should see an update is available to be installed on your control plane. Initiate the update by clicking the `Update Available` text and confirm by clicking `Update Configuration`.

It will take about a minute or so to apply the latest configuration. You can click over to the Settings tab, scroll down to Providers, and see that provider-azure gets installed. Once the configuration has been updated, there should now be a “Blob” type card in the explorer view (you may need to refresh the page once the update is completed).

Create a ProviderConfig

The last thing you need to do is create a ProviderConfig on your managed control plane for provider-azure, so your control plane can communicate with Azure and process resource requests. Provider-azure does not support Upbound’s OIDC integration yet, so you will need to provide credentials for a service account. You can find instructions for how to do this in the quickstart documentation for provider-azure under “Create a Kubernetes secret”.

In order to push your ProviderConfig to your managed control plane, you can use the up CLI’s ctp kubeconfig get command to set your kubeconfig. For that command, you need

Make a claim against your API

Now that you’ve configured your managed control plane to communicate with Azure, it’s time to create a claim for the Blob API. You can use your control plane’s portal to do this or you can submit the claim directly via CLI (gist reference).


After you’ve submitted the claim, you can return to the control plane explorer view and observe the resources get created. It can take a few minutes, but you should eventually see green status icons for each of the resources created.

Congratulations: you now have a managed control plane in Upbound configured to talk to Azure & the definition of your APIs is now syncing from GitHub.
-

Want to try out Upbound for yourself? Enable SRE teams with a more efficient workflow and the building blocks of platform engineering by setting up your first cloud platform powered by Upbound’s managed control planes.  Sign up for your 30 day free trial here!