--- title: AWS Quickstart Part 3 weight: 120 tocHidden: true --- {{< hint "important" >}} This guide is part 3 of a series. Follow **[part 1]({{}})** to install Crossplane and connect your Kubernetes cluster to AWS. Follow **[part 2]({{}})** to create a _composition_, _custom resource definition_ and a _claim_. {{< /hint >}} [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]({{}}) and [Part 2]({{}}) to install Crossplane and the quickstart configurations. {{}} 1. Add the Crossplane Helm repository and install Crossplane ```shell helm repo add \ crossplane-stable https://charts.crossplane.io/stable helm repo update && helm install crossplane \ crossplane-stable/crossplane \ --namespace crossplane-system \ --create-namespace ``` 2. When the Crossplane pods finish installing and are ready, apply the AWS Provider ```yaml {label="provider",copy-lines="all"} cat <}} ```ini {copy-lines="all"} [default] aws_access_key_id = $@$@ aws_secret_access_key = $@$@ ``` {{}} 4. Create a Kubernetes secret from the AWS keys ```shell {label="kube-create-secret",copy-lines="all"} kubectl create secret \ generic aws-secret \ -n crossplane-system \ --from-file=creds=./aws-credentials.txt ``` 5. Create a _ProviderConfig_ ```yaml {label="providerconfig",copy-lines="all"} cat <}} ## 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{{}}. ```yaml {label="compResources"} 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{{}}. ```yaml {label="xrdSnip"} 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." ```yaml {label="patch"} 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_. ```yaml cat <}}region{{}} to "EU." ```yaml {label="claim"} cat < 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_. {{}} The _managed resources_ take up to 5 minutes to delete. {{< /hint >}} ```shell 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](https://opencontainers.org/faq/) 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](https://hub.docker.com/) or the [Upbound Marketplace](https://marketplace.upbound.io/). 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](https://www.docker.com/) or [Upbound's Up CLI)](https://github.com/upbound/up). {{< /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. {{}} Crossplane automatically installs dependencies. Dependencies can include other configuration packages. {{< /hint >}} ```yaml {label="xpyaml"} 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. ```yaml mkdir crossplane-aws-quickstart cat < 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. ```yaml cat < 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`. ```yaml cat < 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. ```shell 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` ```shell crossplane --help Usage: crossplane 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. ```shell crossplane build configuration -f crossplane-aws-quickstart/ --name="crossplane-aws-quickstart" ``` Now an `.xpkg` OCI image is inside the `crossplane-aws-quickstart` directory. ```shell 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](https://marketplace.upbound.io/providers/upbound/provider-family-aws/). * Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with Crossplane users and contributors. * Read more about [Crossplane concepts]({{}})