Azure Quickstart Part 2
This document applies to Crossplane version v1.16 and not to the latest release v1.18.
This guide is part 2 of a series.
Part 1 covers to installing Crossplane and connect your Kubernetes cluster to Azure.
This guide walks you through building and accessing a custom API with Crossplane.
Prerequisites
- Complete quickstart part 1 connecting Kubernetes to Azure.
- an Azure account with permissions to create an Azure Virtual Machine, Resource Group and Virtual Networking.
- Add the Crossplane Helm repository and install Crossplane
1helm repo add \
2crossplane-stable https://charts.crossplane.io/stable
3helm repo update
4&&
5helm install crossplane \
6crossplane-stable/crossplane \
7--namespace crossplane-system \
8--create-namespace
- When the Crossplane pods finish installing and are ready, apply the Azure Provider
1cat <<EOF | kubectl apply -f -
2apiVersion: pkg.crossplane.io/v1
3kind: Provider
4metadata:
5 name: provider-azure-network
6spec:
7 package: xpkg.upbound.io/upbound/provider-azure-network:v1
8EOF
- Use the Azure CLI to create a service principal and save the JSON output as
azure-crednetials.json
- Create a Kubernetes secret from the Azure JSON file.
1kubectl create secret \
2generic azure-secret \
3-n crossplane-system \
4--from-file=creds=./azure-credentials.json
- Create a ProviderConfig
Create a custom API
Crossplane allows you to build your own custom APIs for your users, abstracting away details about the cloud provider and their resources. You can make your API as complex or simple as you wish.
The custom API is a Kubernetes object.
Here is an example custom API.
1apiVersion: compute.example.com/v1alpha1
2kind: VirtualMachine
3metadata:
4 name: my-vm
5spec:
6 location: "US"
Like any Kubernetes object the API has a
,
and
.
Define a group and version
To create your own API start by defining an API group and version.
The group can be any value, but common convention is to map to a fully qualified domain name.
The version shows how mature or stable the API is and increments when changing, adding or removing fields in the API.
Crossplane doesn’t require specific versions or a specific version naming convention, but following Kubernetes API versioning guidelines is strongly recommended.
v1alpha1
- A new API that may change at any time.v1beta1
- An existing API that’s considered stable. Breaking changes are strongly discouraged.v1
- A stable API that doesn’t have breaking changes.
This guide uses the group
.
Because this is the first version of the API, this guide uses the version
.
1apiVersion: compute.example.com/v1alpha1
Define a kind
The API group is a logical collection of related APIs. In a group are individual kinds representing different resources.
For example a compute
group may have a VirtualMachine
and BareMetal
kinds.
The kind
can be anything, but it must be
UpperCamelCased.
This API’s kind is
Define a spec
The most important part of an API is the schema. The schema defines the inputs accepted from users.
This API allows users to provide a
of where to run their
cloud resources.
All other resource settings can’t be configurable by the users. This allows Crossplane to enforce any policies and standards without worrying about user errors.
Apply the API
Crossplane uses
(also called an XRD
) to install your custom API in
Kubernetes.
The XRD
contains all the
information about the API including the
,
,
and
.
The XRD’s
must be the
combination of the
and
.
The
uses the
specification to define
the API
.
The API defines a
that
must be
either
or
.
Apply this XRD to create the custom API in your Kubernetes cluster.
1cat <<EOF | kubectl apply -f -
2apiVersion: apiextensions.crossplane.io/v1
3kind: CompositeResourceDefinition
4metadata:
5 name: virtualmachines.compute.example.com
6spec:
7 group: compute.example.com
8 names:
9 kind: VirtualMachine
10 plural: virtualmachines
11 versions:
12 - name: v1alpha1
13 schema:
14 openAPIV3Schema:
15 type: object
16 properties:
17 spec:
18 type: object
19 properties:
20 location:
21 type: string
22 oneOf:
23 - pattern: '^EU$'
24 - pattern: '^US$'
25 required:
26 - location
27 served: true
28 referenceable: true
29 claimNames:
30 kind: VirtualMachineClaim
31 plural: virtualmachineclaims
32EOF
Adding the
allows users
to access this API either at the cluster level with the
endpoint or in a namespace
with the
endpoint.
The namespace scoped API is a Crossplane Claim.
View the installed XRD with kubectl get xrd
.
View the new custom API endpoints with kubectl api-resources | grep VirtualMachine
1kubectl api-resources | grep VirtualMachine
2virtualmachineclaims compute.example.com/v1alpha1 true VirtualMachineClaim
3virtualmachines compute.example.com/v1alpha1 false VirtualMachine
Create a deployment template
When users access the custom API Crossplane takes their inputs and combines them with a template describing what infrastructure to deploy. Crossplane calls this template a Composition.
The
defines all the
cloud resources to deploy.
Each entry in the template
is a full resource definitions, defining all the resource settings and metadata
like labels and annotations.
This template creates an Azure
,
and
.
Crossplane uses
to apply
the user’s input to the resource template.
This Composition takes the user’s
input and uses it as the
used in the individual
resource.
Apply this Composition to your cluster.
1cat <<EOF | kubectl apply -f -
2apiVersion: apiextensions.crossplane.io/v1
3kind: Composition
4metadata:
5 name: crossplane-quickstart-vm-with-network
6spec:
7 resources:
8 - name: quickstart-vm
9 base:
10 apiVersion: compute.azure.upbound.io/v1beta1
11 kind: LinuxVirtualMachine
12 spec:
13 forProvider:
14 adminUsername: adminuser
15 adminSshKey:
16 - publicKey: ssh-rsa
17 AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
18 example@docs.crossplane.io
19 username: adminuser
20 location: "Central US"
21 osDisk:
22 - caching: ReadWrite
23 storageAccountType: Standard_LRS
24 resourceGroupNameSelector:
25 matchControllerRef: true
26 size: Standard_B1ms
27 sourceImageReference:
28 - offer: debian-11
29 publisher: Debian
30 sku: 11-backports-gen2
31 version: latest
32 networkInterfaceIdsSelector:
33 matchControllerRef: true
34 patches:
35 - type: FromCompositeFieldPath
36 fromFieldPath: "spec.location"
37 toFieldPath: "spec.forProvider.location"
38 transforms:
39 - type: map
40 map:
41 EU: "Sweden Central"
42 US: "Central US"
43 - name: quickstart-nic
44 base:
45 apiVersion: network.azure.upbound.io/v1beta1
46 kind: NetworkInterface
47 spec:
48 forProvider:
49 ipConfiguration:
50 - name: crossplane-quickstart-configuration
51 privateIpAddressAllocation: Dynamic
52 subnetIdSelector:
53 matchControllerRef: true
54 location: "Central US"
55 resourceGroupNameSelector:
56 matchControllerRef: true
57 patches:
58 - type: FromCompositeFieldPath
59 fromFieldPath: "spec.location"
60 toFieldPath: "spec.forProvider.location"
61 transforms:
62 - type: map
63 map:
64 EU: "Sweden Central"
65 US: "Central US"
66 - name: quickstart-subnet
67 base:
68 apiVersion: network.azure.upbound.io/v1beta1
69 kind: Subnet
70 spec:
71 forProvider:
72 addressPrefixes:
73 - 10.0.1.0/24
74 virtualNetworkNameSelector:
75 matchControllerRef: true
76 resourceGroupNameSelector:
77 matchControllerRef: true
78 patches:
79 - type: FromCompositeFieldPath
80 fromFieldPath: "spec.location"
81 toFieldPath: "spec.forProvider.location"
82 transforms:
83 - type: map
84 map:
85 EU: "Sweden Central"
86 US: "Central US"
87 - name: quickstart-network
88 base:
89 apiVersion: network.azure.upbound.io/v1beta1
90 kind: VirtualNetwork
91 spec:
92 forProvider:
93 addressSpace:
94 - 10.0.0.0/16
95 location: "Central US"
96 resourceGroupNameSelector:
97 matchControllerRef: true
98 patches:
99 - type: FromCompositeFieldPath
100 fromFieldPath: "spec.location"
101 toFieldPath: "spec.forProvider.location"
102 transforms:
103 - type: map
104 map:
105 EU: "Sweden Central"
106 US: "Central US"
107 - name: crossplane-resourcegroup
108 base:
109 apiVersion: azure.upbound.io/v1beta1
110 kind: ResourceGroup
111 spec:
112 forProvider:
113 location: Central US
114 patches:
115 - type: FromCompositeFieldPath
116 fromFieldPath: "spec.location"
117 toFieldPath: "spec.forProvider.location"
118 transforms:
119 - type: map
120 map:
121 EU: "Sweden Central"
122 US: "Central US"
123 compositeTypeRef:
124 apiVersion: compute.example.com/v1alpha1
125 kind: VirtualMachine
126EOF
The
defines
which custom APIs can use this template to create resources.
Read the Composition documentation for more information on configuring Compositions and all the available options.
Read the Patch and Transform documentation for more information on how Crossplane uses patches to map user inputs to Composition resource templates.
View the Composition with kubectl get composition
1kubectl get composition
2NAME XR-KIND XR-APIVERSION AGE
3crossplane-quickstart-vm-with-network XVirtualMachine custom-api.example.org/v1alpha1 77s
Install the Azure virtual machine provider
Part 1 only installed the Azure Virtual Network Provider. To deploying virtual machines requires the Azure Compute provider as well.
Add the new Provider to the cluster.
1cat <<EOF | kubectl apply -f -
2apiVersion: pkg.crossplane.io/v1
3kind: Provider
4metadata:
5 name: provider-azure-compute
6spec:
7 package: xpkg.upbound.io/upbound/provider-azure-compute:v1
8EOF
View the new Compute provider with kubectl get providers
.
1kubectl get providers
2NAME INSTALLED HEALTHY PACKAGE AGE
3provider-azure-compute True True xpkg.upbound.io/upbound/provider-azure-compute:v1.0.0 25s
4provider-azure-network True True xpkg.upbound.io/upbound/provider-azure-network:v1.0.0 3h
5upbound-provider-family-azure True True xpkg.upbound.io/upbound/provider-family-azure:v1.0.0 3h
Access the custom API
With the custom API (XRD) installed and associated to a resource template (Composition) users can access the API to create resources.
Create a
object to
create the cloud resources.
1cat <<EOF | kubectl apply -f -
2apiVersion: compute.example.com/v1alpha1
3kind: VirtualMachine
4metadata:
5 name: my-vm
6spec:
7 location: "EU"
8EOF
View the resource with kubectl get VirtualMachine
.
1kubectl get VirtualMachine
2NAME SYNCED READY COMPOSITION AGE
3my-vm True True crossplane-quickstart-vm-with-network 3m3s
This object is a Crossplane composite resource (also called an XR
).
It’s a
single object representing the collection of resources created from the
Composition template.
View the individual resources with kubectl get managed
1kubectl get managed
2NAME READY SYNCED EXTERNAL-NAME AGE
3resourcegroup.azure.upbound.io/my-vm-7jb4n True True my-vm-7jb4n 3m43s
4
5NAME READY SYNCED EXTERNAL-NAME AGE
6linuxvirtualmachine.compute.azure.upbound.io/my-vm-5h7p4 True True my-vm-5h7p4 3m43s
7
8NAME READY SYNCED EXTERNAL-NAME AGE
9networkinterface.network.azure.upbound.io/my-vm-j7fpx True True my-vm-j7fpx 3m43s
10
11NAME READY SYNCED EXTERNAL-NAME AGE
12subnet.network.azure.upbound.io/my-vm-b2dqt True True my-vm-b2dqt 3m43s
13
14NAME READY SYNCED EXTERNAL-NAME AGE
15virtualnetwork.network.azure.upbound.io/my-vm-pd2sw True True my-vm-pd2sw 3m43s
Accessing the API created all five resources defined in the template and linked them together.
Look at a specific resource to see it’s created in the location used in the API.
1kubectl describe linuxvirtualmachine | grep Location
2 Location: Sweden Central
3 Location: swedencentral
Delete the resources with kubectl delete VirtualMachine
.
Verify Crossplane deleted the resources with kubectl get managed
Using the API with namespaces
Accessing the API VirtualMachine
happens at the cluster scope.
Most organizations
isolate their users into namespaces.
A Crossplane Claim is the custom API in a namespace.
Creating a Claim is just like accessing the custom API endpoint, but with the
from the custom API’s claimNames
.
Create a new namespace to test create a Claim in.
1kubectl create namespace crossplane-test
Then create a Claim in the crossplane-test
namespace.
1cat <<EOF | kubectl apply -f -
2apiVersion: compute.example.com/v1alpha1
3kind: VirtualMachineClaim
4metadata:
5 name: my-namespaced-vm
6 namespace: crossplane-test
7spec:
8 location: "EU"
9EOF
View the Claim with kubectl get claim -n crossplane-test
.
1kubectl get claim -n crossplane-test
2NAME SYNCED READY CONNECTION-SECRET AGE
3my-namespaced-vm True True 5m11s
The Claim automatically creates a composite resource, which creates the managed resources.
View the Crossplane created composite resource with kubectl get composite
.
1kubectl get composite
2NAME SYNCED READY COMPOSITION AGE
3my-namespaced-vm-r7gdr True True crossplane-quickstart-vm-with-network 5m33s
Again, view the managed resources with kubectl get managed
.
1NAME READY SYNCED EXTERNAL-NAME AGE
2resourcegroup.azure.upbound.io/my-namespaced-vm-r7gdr-cvzw6 True True my-namespaced-vm-r7gdr-cvzw6 5m51s
3
4NAME READY SYNCED EXTERNAL-NAME AGE
5linuxvirtualmachine.compute.azure.upbound.io/my-namespaced-vm-r7gdr-vrbgb True True my-namespaced-vm-r7gdr-vrbgb 5m51s
6
7NAME READY SYNCED EXTERNAL-NAME AGE
8networkinterface.network.azure.upbound.io/my-namespaced-vm-r7gdr-hwrb8 True True my-namespaced-vm-r7gdr-hwrb8 5m51s
9
10NAME READY SYNCED EXTERNAL-NAME AGE
11subnet.network.azure.upbound.io/my-namespaced-vm-r7gdr-gh468 True True my-namespaced-vm-r7gdr-gh468 5m51s
12
13NAME READY SYNCED EXTERNAL-NAME AGE
14virtualnetwork.network.azure.upbound.io/my-namespaced-vm-r7gdr-5qhz7 True True my-namespaced-vm-r7gdr-5qhz7 5m51s
Deleting the Claim deletes all the Crossplane generated resources.
kubectl delete claim -n crossplane-test my-VirtualMachine-database
1kubectl delete claim -n crossplane-test my-namespaced-vm
2virtualmachineclaim.compute.example.com "my-namespaced-vm" deleted
Verify Crossplane deleted the composite resource with kubectl get composite
.
Verify Crossplane deleted the managed resources with kubectl get managed
.
Next steps
- Explore Azure resources that Crossplane can configure in the Provider CRD reference.
- Join the Crossplane Slack and connect with Crossplane users and contributors.
- Read more about the Crossplane concepts to find out what else you can do with Crossplane.