19 KiB
title | weight | tocHidden |
---|---|---|
GCP Quickstart Part 3 | 120 | true |
{{< hint "important" >}} This guide is part 3 of a series.
Follow [part 1]({{<ref "provider-gcp" >}}) to install Crossplane and connect your Kubernetes cluster to GCP.
Follow [part 2]({{<ref "provider-gcp-part-2" >}}) to create a composition, custom resource definition and a claim. {{< /hint >}}
[Part 2]({{<ref "provider-gcp-part-2" >}}) created a composite resource definition 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 the associated composite resources.
Prerequisites
- Complete quickstart [part 1]({{<ref "provider-gcp" >}}) and [Part 2]({{<ref "provider-gcp-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 GCP Provider.
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: upbound-provider-gcp
spec:
package: xpkg.upbound.io/upbound/provider-gcp:v0.28.0
EOF
- Create a file called
gcp-credentials.json
with your GCP service account JSON file.
{{< hint type="tip" >}} The GCP documentation provides information on how to generate a service account JSON file. {{< /hint >}}
- Create a Kubernetes secret from the GCP JSON file
kubectl create secret \
generic gcp-secret \
-n crossplane-system \
--from-file=creds=./gcp-credentials.json
- Create a ProviderConfig Include your {{< hover label="providerconfig" line="7" >}}GCP project ID{{< /hover >}} in the ProviderConfig settings.
{{< hint type="warning" >}}
Find your GCP project ID from the project_id
field of the
gcp-credentials.json
file.
{{< /hint >}}
{{< editCode >}}
cat <<EOF | kubectl apply -f -
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
projectID: $@<PROJECT_ID>$@
credentials:
source: Secret
secretRef:
namespace: crossplane-system
name: gcp-secret
key: creds
EOF
{{< /editCode >}}
- Create a composition
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: topic-with-bucket
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XTopicBucket
resources:
- name: crossplane-quickstart-bucket
base:
apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
spec:
forProvider:
location: US
- name: crossplane-quickstart-topic
base:
apiVersion: pubsub.gcp.upbound.io/v1beta1
kind: Topic
spec:
forProvider:
messageStoragePolicy:
- allowedPersistenceRegions:
- "us-central1"
EOF
- Create a composite resource definition
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xtopicbuckets.custom-api.example.org
spec:
group: custom-api.example.org
names:
kind: XTopicBucket
plural: xtopicbuckets
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
location:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
required:
- location
claimNames:
kind: TopicBucket
plural: topicbuckets
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 two managed resources, a {{}}bucket{{}} and a {{}}topic{{}}.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
- name: crossplane-quickstart-bucket
base:
apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
spec:
forProvider:
location: US
- name: crossplane-quickstart-topic
base:
apiVersion: pubsub.gcp.upbound.io/v1beta1
kind: Topic
spec:
forProvider:
messageStoragePolicy:
- allowedPersistenceRegions:
- "us-central1"
The custom API defined a single option, {{}}location{{}}. A {{}}location{{}} can be either {{}}EU{{}} or {{}}US{{}}.
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
# Removed for brevity
spec:
group: custom-api.example.org
names:
kind: XDatabase
# Removed for brevity
spec:
type: object
properties:
location:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
Creating a composition patch
allows Crossplane to update the settings of a
composite resource. Patches apply to an individual managed resource
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 {{}}Topic{{}} uses the custom API {{}}spec.location{{}} field to use as the managed resource {{}}allowedPersistenceRegions{{}} value.
The custom API value "EU" is {{}}mapped{{}} to the value "europe-central2" and "US" is {{}}mapped{{}} to the value "us-central1."
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
- name: crossplane-quickstart-topic
base:
apiVersion: pubsub.gcp.upbound.io/v1beta1
kind: Topic
spec:
forProvider:
messageStoragePolicy:
- allowedPersistenceRegions:
- "us-central1"
patches:
- fromFieldPath: "spec.location"
toFieldPath: "spec.forProvider.messageStoragePolicy[*].allowedPersistenceRegions[*]"
transforms:
- type: map
map:
EU: "europe-central2"
US: "us-central1"
Patching is a powerful tool enabling simpler or abstracted APIs. Developers aren't required to know the specific GCP region, just the abstracted option of "EU" or "US."
Apply the updated composition
Apply a similar patch
to the Bucket
managed resource and apply the updated
composition.
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: topic-with-bucket
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XTopicBucket
resources:
- name: crossplane-quickstart-bucket
base:
apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
spec:
forProvider:
location: "US"
patches:
- fromFieldPath: "spec.location"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "EU"
US: "US"
- name: crossplane-quickstart-topic
base:
apiVersion: pubsub.gcp.upbound.io/v1beta1
kind: Topic
spec:
forProvider:
messageStoragePolicy:
- allowedPersistenceRegions:
- "us-central1"
patches:
- fromFieldPath: "spec.location"
toFieldPath: "spec.forProvider.messageStoragePolicy[*].allowedPersistenceRegions[*]"
transforms:
- type: map
map:
EU: "europe-central2"
US: "us-central1"
EOF
Create a claim
Create a new claim and set the {{}}location{{}} to "EU."
cat <<EOF | kubectl apply -f -
apiVersion: custom-api.example.org/v1alpha1
kind: TopicBucket
metadata:
name: claimed-eu-topic-with-bucket
namespace: test
spec:
location: "EU"
EOF
View the claim with kubectl get claim
kubectl get TopicBucket -n test
NAME SYNCED READY CONNECTION-SECRET AGE
claimed-eu-topic-with-bucket True True 2m26s
The claim reports SYNCED
and READY
as True
after Crossplane creates
all the managed resources.
Describe the Topic
resource to see the GCP location is
{{< hover label="topicLocation" line="5">}}europe-central2{{< /hover >}}.
kubectl describe topic | grep "For Provider" -A3
For Provider:
Message Storage Policy:
Allowed Persistence Regions:
europe-central2
Describe the Bucket
resource to see the GCP location is also set to
{{}}EU{{}}.
kubectl describe bucket | grep "For Provider" -A1
For Provider:
Location: EU
Using {{}}location: "EU"{{}} in the
claim patches the composite resource, updating the Topic
GCP region from
us-central1
to europe-central-2
and the Bucket
from GCP region US
to GCP
region EU
.
The developer creating the claim isn't required to know which specific GCP
region or the naming conventions. Using the abstract API options of "EU" or "US"
the developer places their resources in the desired location.
In this example, patching also allows platform teams to ensure all resources are in the same location.
Deleting the claim removes the managed resources.
{{<hint "note" >}} The managed resources take up to 5 minutes to delete. {{< /hint >}}
kubectl delete TopicBucket claimed-eu-topic-with-bucket -n test
Create a Crossplane configuration package
Creating a configuration package makes your Crossplane custom APIs portable and versioned.
Crossplane configuration packages allow users to combine their custom resource definition and composition files into an 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.
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 command-line tool {{< /hint >}}
A configuration package includes three files:
crossplane.yaml
defines the metadata of the package.definition.yaml
is the composite resource definition 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-gcp{{}} version {{}}0.28.0{{}} or later as a dependency.
{{<hint "tip" >}} Crossplane automatically installs dependencies. Dependencies can include other configuration packages. {{< /hint >}}
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: crossplane-gcp-quickstart
spec:
crossplane:
version: ">=v1.11.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-gcp
version: ">=v0.28.0"
Create a new directory and save the crossplane.yaml
file.
mkdir crossplane-gcp-quickstart
cat <<EOF > crossplane-gcp-quickstart/crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: crossplane-gcp-quickstart
spec:
crossplane:
version: ">=v1.11.0"
dependsOn:
- provider: xpkg.upbound.io/upbound/provider-gcp
version: ">=v0.28.0"
EOF
Create a definition.yaml file
A configuration package requires a composite resource definition (XRD) to define the custom API.
Save the XRD as definition.yaml
in the same directory as the
crossplane.yaml
file.
cat <<EOF > crossplane-gcp-quickstart/definition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xtopicbuckets.custom-api.example.org
spec:
group: custom-api.example.org
names:
kind: XTopicBucket
plural: xtopicbuckets
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
location:
type: string
oneOf:
- pattern: '^EU$'
- pattern: '^US$'
required:
- location
claimNames:
kind: TopicBucket
plural: topicbuckets
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
.
cat <<EOF > crossplane-gcp-quickstart/composition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: topic-with-bucket
spec:
compositeTypeRef:
apiVersion: custom-api.example.org/v1alpha1
kind: XTopicBucket
resources:
- name: crossplane-quickstart-bucket
base:
apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
spec:
forProvider:
location: "US"
patches:
- fromFieldPath: "spec.location"
toFieldPath: "spec.forProvider.location"
transforms:
- type: map
map:
EU: "EU"
US: "US"
- name: crossplane-quickstart-topic
base:
apiVersion: pubsub.gcp.upbound.io/v1beta1
kind: Topic
spec:
forProvider:
messageStoragePolicy:
- allowedPersistenceRegions:
- "us-central1"
patches:
- fromFieldPath: "spec.location"
toFieldPath: "spec.forProvider.messageStoragePolicy[*].allowedPersistenceRegions[*]"
transforms:
- type: map
map:
EU: "europe-central2"
US: "us-central1"
EOF
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
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-gcp-quickstart/ --name="crossplane-gcp-quickstart"
Now an .xpkg
OCI image is inside the crossplane-gcp-quickstart
directory.
ls crossplane-gcp-quickstart/
composition.yaml crossplane-gcp-quickstart.xpkg crossplane.yaml definition.yaml
Next steps
- Explore GCP 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" >}})