25 KiB
title | weight | tocHidden |
---|---|---|
Azure Quickstart Part 3 | 120 | true |
{{< hint "important" >}} This guide is part 3 of a series.
Follow [part 1]({{<ref "provider-azure" >}}) to install Crossplane and connect your Kubernetes cluster to Azure.
Follow [part 2]({{<ref "provider-azure-part-2" >}}) to create a composition, custom resource definition and a claim. {{< /hint >}}
[Part 2]({{<ref "provider-azure-part-2" >}}) created a CompositeResourceDefinition to define the schema of the custom API. Users create a Claim to use the custom API and apply their options. Part 2 didn't show how the options set in a Claim change or get applied to the associated composite resources.
Prerequisites
- Complete quickstart [part 1]({{<ref "provider-azure" >}}) and [part 2]({{<ref "provider-azure-part-2" >}}) to install Crossplane and the quickstart configurations.
{{<expand "Skip parts 1 and 2 and just get started" >}}
- Add the Crossplane Helm repository and install Crossplane
helm repo add \
crossplane-stable https://charts.crossplane.io/stable
helm repo update
&&
helm install crossplane \
crossplane-stable/crossplane \
--namespace crossplane-system \
--create-namespace
- When the Crossplane pods finish installing and are ready, apply the Azure Provider
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: upbound-provider-azure
spec:
package: xpkg.upbound.io/upbound/provider-azure:v0.32.0
EOF
- Use the Azure CLI to create a service principal and save the JSON output as
azure-crednetials.json
{{< editCode >}}
az ad sp create-for-rbac \
--sdk-auth \
--role Owner \
--scopes /subscriptions/$$<subscription_id>$$
{{</ editCode >}}
- Create a Kubernetes secret from the Azure JSON file.
kubectl create secret \
generic azure-secret \
-n crossplane-system \
--from-file=creds=./azure-credentials.json
- Create a ProviderConfig
cat <<EOF | kubectl apply -f -
apiVersion: azure.upbound.io/v1beta1
metadata:
name: default
kind: ProviderConfig
spec:
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: azure-secret
key: creds
EOF
- Create a composition {{< hint "tip" >}} Apply your {{}}resourceGroupName{{}} to each resource. {{< /hint >}}
{{< editCode >}}
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: crossplane-quickstart-vm-with-network
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XVirtualMachine
resources:
- name: quickstart-vm
base:
apiVersion: compute.azure.upbound.io/v1beta1
kind: LinuxVirtualMachine
spec:
forProvider:
adminUsername: adminuser
adminSshKey:
- publicKey: ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
example@docs.crossplane.io
username: adminuser
location: "Central US"
osDisk:
- caching: ReadWrite
storageAccountType: Standard_LRS
resourceGroupName: $$<resource_group_name>$$
size: Standard_B1ms
sourceImageReference:
- offer: debian-11
publisher: Debian
sku: 11-backports-gen2
version: latest
networkInterfaceIdsSelector:
matchControllerRef: true
- name: quickstart-nic
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: NetworkInterface
spec:
forProvider:
ipConfiguration:
- name: crossplane-quickstart-configuration
privateIpAddressAllocation: Dynamic
subnetIdSelector:
matchControllerRef: true
location: "Central US"
resourceGroupName: $$<resource_group_name>$$
- name: quickstart-subnet
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: Subnet
spec:
forProvider:
addressPrefixes:
- 10.0.1.0/24
virtualNetworkNameSelector:
matchControllerRef: true
resourceGroupName: $$<resource_group_name>$$
- name: quickstart-network
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: VirtualNetwork
spec:
forProvider:
addressSpace:
- 10.0.0.0/16
location: "Central US"
resourceGroupName: $$<resource_group_name>$$
EOF
{{< /editCode >}}
- Create a CompositeResourceDefinition
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xvirtualmachines.custom-api.example.org
spec:
group: custom-api.example.org
names:
kind: XVirtualMachine
plural: xvirtualmachines
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
region:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
required:
- region
claimNames:
kind: VirtualMachine
plural: virtualmachines
EOF
- Create a new namespace
kubectl create namespace test
{{}}
Enable composition patches
In a Composition patches
map fields in the custom API to fields inside the
managed resources.
The example Composition has four managed resources. A {{}}LinuxVirtualMachine{{}}, {{}}NetworkInterface{{}}, {{}}Subnet{{}} and a {{}}VirtualNetwork{{}}.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
- name: quickstart-vm
base:
apiVersion: compute.azure.upbound.io/v1beta1
kind: LinuxVirtualMachine
- name: quickstart-nic
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: NetworkInterface
- name: quickstart-subnet
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: Subnet
- name: quickstart-network
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: VirtualNetwork
The custom API defined a single option, {{}}region{{}}. A {{}}region{{}} can be either {{}}EU{{}} or {{}}US{{}}.
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
# Removed for brevity
spec:
group: custom-api.example.org
names:
kind: XVirtualMachine
# Removed for brevity
spec:
type: object
properties:
region:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
Creating a composition patch
allows Crossplane to update the settings of the
composite resource. Patches apply to the individual managed resources
inside the Composition.
A {{}}patch{{}} has a
{{}}fromField{{}} and a
{{}}toField{{}} specifying which value
from the custom API should apply to a field in the managed resource.
Patches can create a
{{}}transform{{}} to change the from
field before it's applied.
The transform {{}}type{{}} is what kind of change to make on the from field. Types of changes could include appending a string, preforming a math operation or mapping one value to another.
Applying a {{}}patch{{}} to the {{}}LinuxVirtualMachine{{}} uses the custom API {{}}region{{}} to use as the managed resource {{}}location{{}}.
The custom API value "EU" is {{}}mapped{{}} to the value "Sweden Central" and "US" is {{}}mapped{{}} to the value "Central US."
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
- name: quickstart-vm
base:
apiVersion: compute.azure.upbound.io/v1beta1
kind: LinuxVirtualMachine
spec:
forProvider:
location: "Central US"
# Removed for Brevity
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
Patching is a powerful tool enabling simpler or abstracted APIs. A developer isn't required to know the specific Azure location names, only the abstracted option of "EU" or "US."
Apply the updated composition
Apply the same patch
to all other managed resource
and apply the updated Composition.
{{< hint "tip" >}}
Update each resourceGroupName
with your Azure Resource Group.
{{< /hint >}}
{{< editCode >}}
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: crossplane-quickstart-vm-with-network
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XVirtualMachine
resources:
- name: quickstart-vm
base:
apiVersion: compute.azure.upbound.io/v1beta1
kind: LinuxVirtualMachine
spec:
forProvider:
adminUsername: adminuser
adminSshKey:
- publicKey: ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
example@docs.crossplane.io
username: adminuser
location: "Central US"
osDisk:
- caching: ReadWrite
storageAccountType: Standard_LRS
resourceGroupName: $$<resource_group_name>$$
size: Standard_B1ms
sourceImageReference:
- offer: debian-11
publisher: Debian
sku: 11-backports-gen2
version: latest
networkInterfaceIdsSelector:
matchControllerRef: true
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-nic
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: NetworkInterface
spec:
forProvider:
ipConfiguration:
- name: crossplane-quickstart-configuration
privateIpAddressAllocation: Dynamic
subnetIdSelector:
matchControllerRef: true
location: "Central US"
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-subnet
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: Subnet
spec:
forProvider:
addressPrefixes:
- 10.0.1.0/24
virtualNetworkNameSelector:
matchControllerRef: true
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-network
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: VirtualNetwork
spec:
forProvider:
addressSpace:
- 10.0.0.0/16
location: "Sweden Central"
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
EOF
{{< /editCode >}}
Create a claim
Create a new claim and set the {{}}region{{}} to "EU."
cat <<EOF | kubectl apply -f -
apiVersion: custom-api.example.org/v1alpha1
kind: VirtualMachine
metadata:
name: claimed-eu-virtualmachine
namespace: test
spec:
region: "EU"
EOF
View the Claim with kubectl get claim
{{< hint "note" >}}
It may take up to 10 minutes for the Claim to be READY
.
{{< /hint >}}
kubectl get claim -n test
NAME SYNCED READY CONNECTION-SECRET AGE
claimed-eu-virtualmachine True True 6m2s
The claim reports SYNCED
and READY
as True
after Crossplane creates
all the managed resources.
Describe the LinuxVirtualMachine
resource to see the Azure location is Sweden Central
.
kubectl describe linuxvirtualmachine | grep "At Provider\|Location"
Location: Sweden Central
At Provider:
Location: swedencentral
Using {{}}region: "EU"{{}} patches the
composite resource, updating the Azure location from Central US
to
Sweden Central
.
The developer creating the claim isn't required to know which specific Azure
location or the location naming conventions. Using the abstract API options of
"EU" or "US" the developer places their resources in the desired location.
Deleting the claim removes the managed resources.
{{<hint "note" >}} The managed resources take up to 5 minutes to delete. {{< /hint >}}
kubectl delete virtualmachine claimed-eu-virtualmachine -n test
Create a Crossplane configuration package
Crossplane configuration packages allow users to combine their CustomResourceDefinition and Composition files into a single OCI image.
{{< hint "note" >}}
The Open Container Initiative
defines the OCI image standard.
An OCI images is a standard way to package data.
{{< /hint >}}
You can host configuration packages in image registries like Docker Hub or the Upbound Marketplace.
Crossplane can download and install configuration packages into a Kubernetes cluster.
Creating a configuration package makes your Crossplane custom APIs portable and versioned.
Building and installing configuration packages requires an OCI image compatible tool.
{{< hint "note" >}} You can use any software that builds OCI images. This includes Docker or Upbound's Up CLI. {{< /hint >}}
A configuration package includes at least three files:
crossplane.yaml
defines the metadata of the package.definition.yaml
is the CompositeResourceDefinition for the package.composition.yaml
is the Composition template for the package.
Create a crossplane.yaml file
Configuration packages describe their contents and requirements with a
crossplane.yaml
file.
The crossplane.yaml
file lists the required Crossplane Providers and their
compatible versions as well as the required Crossplane version.
The Crossplane {{}}meta.pkg{{}} API defines the schema for a {{}}Configuration{{}}.
Inside the {{}}spec{{}} define the required Crossplane {{}}version{{}}.
The {{}}dependsOn{{}} section lists the dependencies for a package.
This package lists the Upbound {{}}provider-azure{{}} version {{}}0.32.0{{}} or later as a dependency.
{{<hint "tip" >}} Crossplane automatically installs dependencies. Dependencies can include other configuration packages. {{< /hint >}}
Create a new directory and save the crossplane.yaml
file.
mkdir crossplane-azure-quickstart
cat <<EOF > crossplane-azure-quickstart/crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: crossplane-azure-quickstart
spec:
crossplane:
version: ">=v1.11.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-azure
version: ">=v0.32.0"
EOF
Create a definition.yaml file
A configuration package requires a CompositeResourceDefinition (XRD) to define the custom API.
Save the XRD as definition.yaml
in the same directory as the
crossplane.yaml
file.
cat <<EOF > crossplane-azure-quickstart/definition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xvirtualmachines.custom-api.example.org
spec:
group: custom-api.example.org
names:
kind: XVirtualMachine
plural: xvirtualmachines
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
region:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
required:
- region
claimNames:
kind: VirtualMachine
plural: virtualmachines
EOF
Create a composition.yaml file
The Composition template creates the managed resources and allows patches to customize the managed resources.
Copy the Composition into the composition.yaml
file in the same directory as
crossplane.yaml
.
{{< hint "tip" >}}
Update each resourceGroupName
with your Azure Resource Group.
{{< /hint >}}
{{< editCode >}}
cat <<EOF > crossplane-azure-quickstart/composition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: crossplane-quickstart-vm-with-network
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XVirtualMachine
resources:
- name: quickstart-vm
base:
apiVersion: compute.azure.upbound.io/v1beta1
kind: LinuxVirtualMachine
spec:
forProvider:
adminUsername: adminuser
adminSshKey:
- publicKey: ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQC+wWK73dCr+jgQOAxNsHAnNNNMEMWOHYEccp6wJm2gotpr9katuF/ZAdou5AaW1C61slRkHRkpRRX9FA9CYBiitZgvCCz+3nWNN7l/Up54Zps/pHWGZLHNJZRYyAB6j5yVLMVHIHriY49d/GZTZVNB8GoJv9Gakwc/fuEZYYl4YDFiGMBP///TzlI4jhiJzjKnEvqPFki5p2ZRJqcbCiF4pJrxUQR/RXqVFQdbRLZgYfJ8xGB878RENq3yQ39d8dVOkq4edbkzwcUmwwwkYVPIoDGsYLaRHnG+To7FvMeyO7xDVQkMKzopTQV8AuKpyvpqu0a9pWOMaiCyDytO7GGN
example@docs.crossplane.io
username: adminuser
location: "Central US"
osDisk:
- caching: ReadWrite
storageAccountType: Standard_LRS
resourceGroupName: $$<resource_group_name>$$
size: Standard_B1ms
sourceImageReference:
- offer: debian-11
publisher: Debian
sku: 11-backports-gen2
version: latest
networkInterfaceIdsSelector:
matchControllerRef: true
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-nic
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: NetworkInterface
spec:
forProvider:
ipConfiguration:
- name: crossplane-quickstart-configuration
privateIpAddressAllocation: Dynamic
subnetIdSelector:
matchControllerRef: true
location: "Central US"
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-subnet
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: Subnet
spec:
forProvider:
addressPrefixes:
- 10.0.1.0/24
virtualNetworkNameSelector:
matchControllerRef: true
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
- name: quickstart-network
base:
apiVersion: network.azure.upbound.io/v1beta1
kind: VirtualNetwork
spec:
forProvider:
addressSpace:
- 10.0.0.0/16
location: "Sweden Central"
resourceGroupName: $$<resource_group_name>$$
patches:
- fromFieldPath: "spec.region"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "Sweden Central"
US: "Central US"
EOF
{{< /editCode >}}
Install the Crossplane command-line
To build a configuration package install the Crossplane Kubernetes command-line extension.
wget "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh"
chmod +x install.sh
./install.sh
sudo mv crossplane /usr/local/bin
Follow the directions and move the crossplane
binary to the correct
directory.
Verify the Crossplane command-line installed with crossplane --help
crossplane --help
Usage: crossplane <command>
A command line tool for interacting with Crossplane.
Flags:
-h, --help Show context-sensitive help.
-v, --version Print version and quit.
--verbose Print verbose logging statements.
# Ouptut removed for brevity
Build a configuration package
Use the crossplane
CLI to create an .xpkg
file containing the
custom APIs and Crossplane configuration.
crossplane build configuration -f crossplane-azure-quickstart/ --name="crossplane-azure-quickstart"
Now an .xpkg
OCI image is inside the crossplane-azure-quickstart
directory.
ls crossplane-azure-quickstart/
composition.yaml crossplane-azure-quickstart.xpkg crossplane.yaml definition.yaml
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 [Crossplane concepts]({{<ref "../concepts" >}})