docs/content/v1.11/getting-started/provider-aws-part-3.md

18 KiB

title weight tocHidden
AWS Quickstart Part 3 120 true

{{< hint "important" >}} This guide is part 3 of a series.

Follow [part 1]({{<ref "provider-aws" >}}) to install Crossplane and connect your Kubernetes cluster to AWS.

Follow [part 2]({{<ref "provider-aws-part-2" >}}) to create a composition, custom resource definition and a claim. {{< /hint >}}

[Part 2]({{<ref "provider-aws-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-aws" >}}) and [Part 2]({{<ref "provider-aws-part-2" >}}) to install Crossplane and the quickstart configurations.

{{<expand "Skip parts 1 and 2 and just get started" >}}

  1. 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
  1. When the Crossplane pods finish installing and are ready, apply the AWS Provider
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: upbound-provider-aws
spec:
  package: xpkg.upbound.io/upbound/provider-aws:v0.27.0
EOF
  1. Create a file called aws-credentials.txt with your AWS keys {{< editCode >}}
[default]
aws_access_key_id = $@<aws_access_key>$@
aws_secret_access_key = $@<aws_secret_key>$@

{{</ editCode >}}

  1. Create a Kubernetes secret from the AWS keys
kubectl create secret \
generic aws-secret \
-n crossplane-system \
--from-file=creds=./aws-credentials.txt
  1. Create a ProviderConfig
cat <<EOF | kubectl apply -f -
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-secret
      key: creds
EOF
  1. Create a composition
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: dynamodb-with-bucket
spec:
  compositeTypeRef:
    apiVersion: custom-api.example.org/v1alpha1
    kind: XDatabase
  resources:
    - name: s3-bucket
      base:
        apiVersion: s3.aws.upbound.io/v1beta1
        kind: Bucket
        spec:
          forProvider:
            region: "us-east-2"
    - name: dynamodb
      base:
        apiVersion: dynamodb.aws.upbound.io/v1beta1
        kind: Table
        spec:
          forProvider:
            region: "us-east-2"
            writeCapacity: 1
            readCapacity: 1
            attribute:
              - name: S3ID
                type: S
            hashKey: S3ID
EOF
  1. Create a composite resource definition
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.custom-api.example.org
spec:
  group: custom-api.example.org
  names:
    kind: XDatabase
    plural: xdatabases
  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: Database
    plural: databases
EOF
  1. 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 {{}}table{{}}.

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
    - name: s3-bucket
      base:
        apiVersion: s3.aws.upbound.io/v1beta1
        kind: Bucket
        spec:
          forProvider:
            region: "us-east-2"
    - name: dynamodb
      base:
        apiVersion: dynamodb.aws.upbound.io/v1beta1
        kind: Table
        spec:
          forProvider:
            region: "us-east-2"
            writeCapacity: 1
            readCapacity: 1
            attribute:
              - name: S3ID
                type: S
            hashKey: S3ID

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: XDatabase
# 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 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 {{}}Bucket{{}} uses the custom API {{}}region{{}} to use as the managed resource {{}}region{{}}.

The custom API value "EU" is {{}}mapped{{}} to the value "eu-north-1" and "US" is {{}}mapped{{}} to the value "us-east-2."

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
resources:
    - name: s3-bucket
      base:
        apiVersion: s3.aws.upbound.io/v1beta1
        kind: Bucket
        spec:
          forProvider:
            region: "us-east-2"
      patches:
        - fromFieldPath: "region"
          toFieldPath: "spec.forProvider.region"
          transforms:
            - type: map
              map: 
                EU: "eu-north-1"
                US: "us-east-2"

Patching is a powerful tool enabling simpler or abstracted APIs. A developer isn't required to know the specific AWS region identifier, only the abstracted option of "EU" or "US."

Apply the updated composition

Apply the same patch to the Table managed resource and apply the updated composition.

cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: dynamodb-with-bucket
spec:
  compositeTypeRef:
    apiVersion: custom-api.example.org/v1alpha1
    kind: XDatabase
  resources:
    - name: s3-bucket
      base:
        apiVersion: s3.aws.upbound.io/v1beta1
        kind: Bucket
        spec:
          forProvider:
            name: default
            region: "us-east-2"
      patches:
        - fromFieldPath: "spec.region"
          toFieldPath: "spec.forProvider.region"
          transforms:
            - type: map
              map: 
                EU: "eu-north-1"
                US: "us-east-2"
    - name: dynamodb
      base:
        apiVersion: dynamodb.aws.upbound.io/v1beta1
        kind: Table
        spec:
          forProvider:
            writeCapacity: 1
            readCapacity: 1
            attribute:
              - name: S3ID
                type: S
            hashKey: S3ID
            region: "us-east-2"
      patches:
        - fromFieldPath: "spec.region"
          toFieldPath: "spec.forProvider.region"
          transforms:
            - type: map
              map: 
                EU: "eu-north-1"
                US: "us-east-2"
EOF

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: Database
metadata:
  name: claimed-eu-database
  namespace: test
spec:
  region: "EU"
EOF

View the claim with kubectl get claim

kubectl get database -n test
NAME                  SYNCED   READY   CONNECTION-SECRET   AGE
claimed-eu-database   True     True                        18m

The claim reports SYNCED and READY as True after Crossplane creates all the managed resources.

Describe the Table resource to see the AWS region is eu-north-1.

kubectl describe table | grep arn:aws
    Arn:           arn:aws:dynamodb:eu-north-1:622343227358:table/claimed-eu-database-2sh9w-dhvw6

Using {{}}region: "EU"{{}} patches the composite resource, updating the AWS region from us-east-2 to eu-north-1. The developer creating the claim isn't required to know which specific AWS region or the 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 database claimed-eu-database -n test

Create a Crossplane configuration package

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.

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 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-aws{{}} version {{}}0.27.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-aws-quickstart
spec:
  crossplane:
    version: ">=v1.11.0"
  dependsOn:
    - provider: xpkg.upbound.io/upbound/provider-aws
      version: ">=v0.27.0"

Create a new directory and save the crossplane.yaml file.

mkdir crossplane-aws-quickstart
cat <<EOF > crossplane-aws-quickstart/crossplane.yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
  name: crossplane-aws-quickstart
spec:
  crossplane:
    version: ">=v1.11.0"
  dependsOn:
    - provider: xpkg.upbound.io/upbound/provider-aws
      version: ">=v0.27.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-aws-quickstart/definition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xdatabases.custom-api.example.org
spec:
  group: custom-api.example.org
  names:
    kind: XDatabase
    plural: xdatabases
  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: Database
    plural: databases
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-aws-quickstart/composition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: dynamodb-with-bucket
spec:
  compositeTypeRef:
    apiVersion: custom-api.example.org/v1alpha1
    kind: XDatabase
  resources:
    - name: s3-bucket
      base:
        apiVersion: s3.aws.upbound.io/v1beta1
        kind: Bucket
        spec:
          providerConfigRef:
            name: default
        patches:
        - fromFieldPath: "spec.region"
          toFieldPath: "spec.forProvider.region"
          transforms:
             - type: map
               map: 
                EU: "eu-north-1"
                US: "us-east-1"
    - name: dynamodb
      base:
        apiVersion: dynamodb.aws.upbound.io/v1beta1
        kind: Table
        spec:
          forProvider:
            writeCapacity: 1
            readCapacity: 1
            attribute:
              - name: S3ID
                type: S
            hashKey: S3ID
      patches:
        - fromFieldPath: "spec.region"
          toFieldPath: "spec.forProvider.region"
          transforms:
            - type: map
              map: 
                EU: "eu-north-1"
                US: "us-east-1"
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-aws-quickstart/ --name="crossplane-aws-quickstart"

Now an .xpkg OCI image is inside the crossplane-aws-quickstart directory.

ls crossplane-aws-quickstart/
composition.yaml  crossplane-aws-quickstart.xpkg  crossplane.yaml  definition.yaml

Next steps

  • Explore AWS 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" >}})