diff --git a/content/v1.13/_index.md b/content/v1.13/_index.md
new file mode 100644
index 00000000..da1ff2f8
--- /dev/null
+++ b/content/v1.13/_index.md
@@ -0,0 +1,49 @@
+---
+title: "Overview"
+weight: -1
+cascade:
+ version: "master"
+---
+
+{{< img src="/media/banner.png" alt="Crossplane Popsicle Truck" size="large" >}}
+
+
+
+Crossplane is an open source Kubernetes extension that transforms your Kubernetes
+cluster into a **universal control plane**.
+
+Crossplane lets you manage anything, anywhere, all through standard Kubernetes
+APIs. Crossplane can even let you
+[order a pizza](https://blog.crossplane.io/providers-101-ordering-pizza-with-kubernetes-and-crossplane/)
+directly from Kubernetes. If it has an API, Crossplane can connect to it.
+
+With Crossplane, platform teams can create new abstractions and custom
+APIs with the full power of Kubernetes policies, namespaces, role-based access
+controls and more. Crossplane brings all your non-Kubernetes resources under
+one roof.
+
+Custom APIs, created by platform teams, allow security and compliance
+enforcement across resources or clouds, without exposing any complexity to the
+developers. A single API call can create multiple resources, in multiple clouds
+and use Kubernetes as the control plane for everything.
+
+{{< hint "tip" >}}
+**What's a control plane?**
+Control planes create and manage the lifecycle of resources. Control planes
+constantly _check_ that the intended resources exist, _report_ when the intended
+state doesn't match reality and _act_ to make things right.
+
+Crossplane extends the Kubernetes control plane to be a **universal control
+plane** to check, report and act on any resource, anywhere.
+{{< /hint >}}
+
+
+# Get Started
+* [Install Crossplane]({{[}}) in your Kubernetes cluster
+* Learn more about how Crossplane works in the
+[Crossplane introduction]({{][}})
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and start a
+conversation with a community of over 7,000 operators.
+
+
+Crossplane is a [Cloud Native Compute Foundation](https://www.cncf.io/) project.
diff --git a/content/v1.13/concepts/_index.md b/content/v1.13/concepts/_index.md
new file mode 100644
index 00000000..4c41bfe4
--- /dev/null
+++ b/content/v1.13/concepts/_index.md
@@ -0,0 +1,56 @@
+---
+title: Concepts
+weight: 100
+description: Understand Crossplane's core components
+---
+
+Crossplane introduces multiple building blocks that enable you to provision,
+compose, and consume infrastructure using the Kubernetes API. These individual
+concepts work together to allow for powerful separation of concern between
+different personas in an organization, meaning that each member of a team
+interacts with Crossplane at an appropriate level of abstraction.
+
+## Packages
+
+[Packages] allow Crossplane to be extended to include new functionality. This
+typically looks like bundling a set of Kubernetes [CRDs] and [controllers] that
+represent and manage external infrastructure (i.e. a provider), then installing
+them into a cluster where Crossplane is running. Crossplane handles making sure
+any new CRDs do not conflict with existing ones, as well as manages the RBAC and
+security of new packages. Packages are not strictly required to be providers,
+but it is the most common use-case for packages at this time.
+
+## Providers
+
+Providers are packages that enable Crossplane to provision infrastructure on an
+external service. They bring CRDs (i.e. managed resources) that map one-to-one
+to external infrastructure resources, as well as controllers to manage the
+life-cycle of those resources. You can read more about providers, including how
+to install and configure them, in the [providers documentation].
+
+## Managed Resources
+
+Managed resources are Kubernetes custom resources that represent infrastructure
+primitives. Managed resources with an API version of `v1beta1` or higher support
+every field that the cloud provider does for the given resource. You can find
+the Managed Resources and their API specifications for each provider on
+the [Upbound Marketplace] and learn more in the [managed resources documentation].
+
+## Composite Resources
+
+A composite resource (XR) is a special kind of custom resource that is defined
+by a `CompositeResourceDefinition`. It composes one or more managed resources
+into a higher level infrastructure unit. Composite resources are infrastructure
+operator facing, but may optionally offer an application developer facing
+composite resource claim that acts as a proxy for a composite resource. You can
+learn more about all of these concepts in the [composition documentation].
+
+
+
+[Packages]: {{][}}
+[CRDs]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
+[controllers]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-controllers
+[providers documentation]: {{][}}
+[Upbound Marketplace]: https://marketplace.upbound.io
+[managed resources documentation]: {{][}}
+[composition documentation]: {{][}}
diff --git a/content/v1.13/concepts/claims.md b/content/v1.13/concepts/claims.md
new file mode 100644
index 00000000..e5f8f729
--- /dev/null
+++ b/content/v1.13/concepts/claims.md
@@ -0,0 +1,208 @@
+---
+title: Claims
+weight: 60
+description: "Claims are a way to consume Crossplane resources with namespace scoping"
+---
+
+Claims represents a set of managed resources as a single
+Kubernetes object, inside a namespace.
+
+Users create claims when they access the
+custom API, defined in the CompositeResourceDefinition.
+
+{{< hint "tip" >}}
+
+Claims are like [composite resources]({{][}}). The
+difference between Claims and composite resources is Crossplane can create
+Claims in a namespace, while composite resources are cluster scoped.
+{{< /hint >}}
+
+{{]}}
+Crossplane has four core components that users commonly mix up:
+
+* [Compositions]({{[}}) - A template to define how to create resources.
+* [Composite Resource Definition]({{][}})
+ (`XRD`) - A custom API specification.
+* [Composite Resources]({{][}}) (`XR`) - Created by
+ using the custom API defined in a Composite Resource Definition. XRs use the
+ Composition template to create new managed resources.
+* Claims (`XRC`) - This page. Like a Composite Resource, but
+ with namespace scoping.
+{{] }}
+
+## Creating a Claim
+
+Creating a Claim requires a
+[Composition]({{[}}) and a
+[CompositeResourceDefinition]({{][}})
+(`XRD`) already installed.
+
+{{]}}
+The XRD must
+[enable Claims]({{[}}).
+{{< /hint >}}
+
+The Composition defines the set of resources to create.
+The XRD defines the custom API users call to request the set of resources.
+
+
+
+For example,
+this {{]}}CompositeResourceDefinition{{ }}
+creates a composite resource API endpoint
+{{}}xmydatabases.example.org{{ }} and
+enables a Claim API endpoint
+{{}}database.example.org{{ }}
+
+```yaml {label="xrd1",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xmydatabases.example.org
+spec:
+ group: example.org
+ names:
+ kind: XMyDatabase
+ plural: xmydatabases
+ claimNames:
+ kind: Database
+ plural: databases
+ # Removed for brevity
+```
+
+The Claim uses the XRD's
+{{}}kind{{ }} API endpoint to request
+resources.
+
+The Claim's {{}}apiVersion{{ }} matches
+the XRD {{}}group{{ }} and the
+{{}}kind{{ }} matches the XRD
+{{}}claimNames.kind{{ }}
+
+```yaml {label="claim1",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: database
+metadata:
+ name: my-claimed-database
+spec:
+ # Removed for brevity
+```
+
+When a user creates a Claim in a namespace Crossplane also creates a composite
+resource.
+
+Use {{}}kubectl describe{{ }} on the
+Claim to view the related composite resource.
+
+The {{}}Resource Ref{{ }} is the
+composite resource Crossplane created for this Claim.
+
+```shell {label="claimcomp",copy-lines="1"}
+kubectl describe database.example.org/my-claimed-database
+Name: my-claimed-database
+API Version: example.org/v1alpha1
+Kind: database
+Spec:
+ Resource Ref:
+ API Version: example.org/v1alpha1
+ Kind: XMyDatabase
+ Name: my-claimed-database-rr4ll
+# Removed for brevity.
+```
+
+Use {{}}kubectl describe{{ }} on the
+composite resource to view the
+{{}}Claim Ref{{ }} linking the
+composite resource to the original Claim.
+
+```shell {label="getcomp",copy-lines="1"}
+kubectl describe xmydatabase.example.org/my-claimed-database-rr4ll
+Name: my-claimed-database-rr4ll
+API Version: example.org/v1alpha1
+Kind: XMyDatabase
+Spec:
+ Claim Ref:
+ API Version: example.org/v1alpha1
+ Kind: database
+ Name: my-claimed-database
+ Namespace: default
+```
+
+{{}}
+Crossplane supports directly creating composite resources. Claims allow
+namespace scoping and isolation for users consuming the custom APIs.
+
+If you don't use namespaces in your Kubernetes deployment Claims aren't necessary.
+{{< /hint >}}
+
+### Claiming existing composite resources
+
+By default, creating a Claim creates a new composite resource. Claims can also
+link to existing composite resources.
+
+A use case for claiming existing composite resources may be slow to provision
+resources. Composite resources can be pre-provisioned and a Claim can
+use those resources without waiting for their creation.
+
+Set the Claim's {{}}resourceRef{{ }}
+and match the pre-existing composite resource
+{{}}name{{ }}.
+
+```yaml {label="resourceref",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: database
+metadata:
+ name: my-claimed-database
+spec:
+ resourceRef:
+ apiVersion: example.org/v1alpha1
+ kind: XMyDatabase
+ name: my-pre-created-xr
+```
+
+If a Claim specifies a
+{{}}resourceRef{{ }} that doesn't
+exist, Crossplane doesn't create a composite resource.
+
+{{}}
+All Claims have a
+{{}}resourceRef{{ }}. Manually
+defining the
+{{}}resourceRef{{ }}
+isn't required. Crossplane fills in the
+{{}}resourceRef{{ }}
+with the information from the composite resource created for the Claim.
+{{< /hint >}}
+
+## Claim connection secrets
+
+If a Claim expects connection secrets the Claim must define a
+{{}}writeConnectionSecretToRef{{ }}
+object.
+
+The
+{{}}writeConnectionSecretToRef{{ }}
+object defines the name of the Kubernetes secret object where Crossplane saves
+the connection details.
+
+{{}}
+The Crossplane creates the secret object in the same namespace as the Claim.
+{{< /hint >}}
+
+For example, to a new secret object named
+{{}}my-claim-secret{{ }} use
+{{}}writeConnectionSecretToRef{{ }} with
+the
+{{}}name: my-claim-secret{{ }}.
+```yaml {label="claimSec"}
+apiVersion: example.org/v1alpha1
+kind: database
+metadata:
+ name: my-claimed-database
+spec:
+ writeConnectionSecretToRef:
+ name: my-claim-secret
+```
+
+For more information on connection secrets read the [Connection Secrets
+knowledge base article]({{[}}).
\ No newline at end of file
diff --git a/content/v1.13/concepts/composite-resource-definitions.md b/content/v1.13/concepts/composite-resource-definitions.md
new file mode 100644
index 00000000..496db4d0
--- /dev/null
+++ b/content/v1.13/concepts/composite-resource-definitions.md
@@ -0,0 +1,841 @@
+---
+title: Composite Resource Definitions
+weight: 40
+description: "Composite Resource Definitions or XRDs define custom API schemas"
+---
+
+Composite resource definitions (`XRDs`) define the schema for a custom API.
+Users create composite resources (`XRs`) and Claims (`XCs`) using the API
+schema defined by an `XRD`.
+
+
+{{< hint "note" >}}
+
+Read the [composite resources]({{][}}) page for more
+information about composite resources.
+
+Read the [Claims]({{][}}) page for more
+information about Claims.
+{{] }}
+
+
+{{}}
+Crossplane has four core components that users commonly mix up:
+
+* [Compositions]({{[}}) - A template to define how to create resources.
+* Composite Resource Definition (`XRD`) - This page. A custom API specification.
+* [Composite Resource]({{][}}) (`XR`) - Created by
+ using the custom API defined in a Composite Resource Definition. XRs use the
+ Composition template to create new managed resources.
+* [Claims]({{][}}) (`XRC`) - Like a Composite Resource, but
+ with namespace scoping.
+{{] }}
+
+Crossplane XRDs are like
+[Kubernetes custom resource definitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/).
+XRDs require fewer fields and add options related to Crossplane, like Claims and
+connection secrets.
+
+## Creating a CompositeResourceDefinition
+
+Creating a CompositeResourceDefinition consists of:
+* [Defining a custom API group](#xrd-groups).
+* [Defining a custom API name](#xrd-names).
+* [Defining a custom API schema and version](#xrd-versions).
+
+Optionally, CompositeResourceDefinitions also support:
+* [Offering a Claim](#enable-claims).
+* [Defining connection secrets](#manage-connection-secrets).
+* [Setting composite resource defaults](#set-composite-resource-defaults).
+
+Composite resource definitions (`XRDs`) create new API endpoints inside a
+Kubernetes cluster.
+
+Creating a new API requires defining an API
+{{}}group{{ }},
+{{}}name{{ }} and
+{{}}version{{ }}.
+
+```yaml {label="xrd1",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xmydatabases.example.org
+spec:
+ group: example.org
+ names:
+ kind: XMyDatabase
+ plural: xmydatabases
+ versions:
+ - name: v1alpha1
+ # Removed for brevity
+```
+
+After applying an XRD, Crossplane creates a new Kubernetes custom resource
+definition matching the defined API.
+
+For example, the XRD
+{{}}xmydatabases.example.org{{ }}
+creates a custom resource definition
+{{}}xmydatabases.example.org{{ }}.
+
+```shell {label="kubeapi",copy-lines="3"}
+kubectl api-resources
+NAME SHORTNAMES APIVERSION NAMESPACED KIND
+xmydatabases.example.org v1alpha1 false xmydatabases
+# Removed for brevity
+```
+
+{{}}
+You can't change the XRD
+{{}}group{{ }} or
+{{}}names{{ }}.
+You must delete and
+recreate the XRD to change the
+{{}}group{{ }} or
+{{}}names{{ }}.
+{{ }}
+
+### XRD groups
+
+Groups define a collection of related API endpoints. The `group` can be any
+value, but common convention is to map to a fully qualified domain name.
+
+
+Many XRDs may use the same `group` to create a logical collection of APIs.
+
+For example a `database` group may have a `relational` and `nosql` kinds.
+
+{{}}
+Group names are cluster scoped. Choose group names that don't conflict with
+Providers.
+Avoid Provider names in the group.
+{{< /hint >}}
+
+### XRD names
+
+The `names` field defines how to refer to this specific XRD.
+The required name fields are:
+
+* `kind` - the `kind` value to use when calling this API. The kind is
+ [UpperCamelCased](https://kubernetes.io/docs/contribute/style/style-guide/#use-upper-camel-case-for-api-objects).
+ Crossplane recommends starting XRD `kinds` with an `X` to show
+ it's a custom Crossplane API definition.
+* `plural` - the plural name used for the API URL. The plural name must be
+ lowercase.
+
+{{}}
+The XRD
+{{}}metadata.name{{ }} must be
+{{}}plural{{ }} name, `.` (dot character),
+{{}}group{{ }}.
+
+For example, {{}}xmydatabases.example.org{{ }} matches the {{}}plural{{ }} name
+{{}}xmydatabases{{ }}, `.`
+{{}}group{{ }} name,
+{{}}example.org{{ }}.
+
+```yaml {label="xrdName",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xmydatabases.example.org
+spec:
+ group: example.org
+ names:
+ kind: XMyDatabase
+ plural: xmydatabases
+ # Removed for brevity
+```
+{{ }}
+
+### XRD versions
+
+
+The XRD `version` is like the
+[API versioning used by Kubernetes](https://kubernetes.io/docs/reference/using-api/#api-versioning).
+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](https://kubernetes.io/docs/reference/using-api/#api-versioning)
+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.
+
+#### Define a schema
+
+
+
+The `schema` defines the names
+of the parameters, the data types of the parameters and which parameters are
+required or optional.
+
+
+
+{{}}
+All `schemas` follow the Kubernetes custom resource definition
+[OpenAPIv3 structural schema](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
+{{< /hint >}}
+
+Each
+{{}}version{{ }} of the API has a unique
+{{}}schema{{ }}.
+
+All XRD {{}}schemas{{ }} validate against
+the {{}}openAPIV3Schema{{ }}. The schema
+is an OpenAPI
+{{}}object{{ }} with the
+{{}}properties{{ }} of a
+{{}}spec{{ }}
+{{}}object{{ }}.
+
+Inside the {{}}spec.properties{{ }} is the custom
+API definition.
+
+In this example, the key {{}}region{{ }}
+is a {{}}string{{ }}.
+
+```yaml {label="schema",copy-lines="none"}
+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
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ region:
+ type: string
+ # Removed for brevity
+```
+
+A composite resource using this API references the
+{{}}group/version{{ }} and
+{{}}kind{{ }}. The
+{{}}spec{{ }} has the
+{{}}region{{ }} key with a string value.
+
+```yaml {label="xr"}
+apiVersion: custom-api.example.org/v1alpha1
+kind: xDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ region: "US"
+```
+
+
+{{}}
+The custom API defined inside the
+{{}}spec.properties{{ }} is an OpenAPIv3
+specification. The
+[data models page](https://swagger.io/docs/specification/data-models/) of
+the Swagger documentation provides a list of examples using data types and input
+restrictions.
+
+The Kubernetes documentation lists
+[the set of special restrictions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation)
+on what your OpenAPIv3 custom API can use.
+{{< /hint >}}
+
+{{}}
+
+Changing or expanding the XRD schema requires restarting the [Crossplane
+pod]({{[}}) to take effect.
+{{< /hint >}}
+
+##### Required fields
+
+By default all fields in a schema are optional. Define a parameter as required
+with the
+{{< hover label="required" line="25">}}required{{}} attribute.
+
+In this example the XRD requires
+{{< hover label="required" line="19">}}region{{}} and
+{{< hover label="required" line="21">}}size{{}} but
+{{< hover label="required" line="23">}}name{{}} is optional.
+```yaml {label="required",copy-lines="none"}
+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
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ region:
+ type: string
+ size:
+ type: string
+ name:
+ type: string
+ required:
+ - region
+ - size
+ # Removed for brevity
+```
+
+According to the OpenAPIv3 specification, the `required` field is per-object. If
+a schema contains multiple objects the schema may need multiple `required`
+fields.
+
+This XRD defines two objects:
+ 1. the top-level {{]}}spec{{ }} object
+ 2. a second {{}}location{{ }} object
+
+The {{}}spec{{ }} object
+{{}}requires{{ }} the
+{{}}size{{ }} and
+{{}}location{{ }} but
+{{}}name{{ }} is optional.
+
+Inside the required {{}}location{{ }}
+object,
+{{}}country{{ }} is
+{{}}required{{ }} and
+{{}}zone{{ }} is optional.
+
+```yaml {copy-lines="none",label="required2"}
+# Removed for brevity
+- name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ size:
+ type: string
+ name:
+ type: string
+ location:
+ type: object
+ properties:
+ country:
+ type: string
+ zone:
+ type: string
+ required:
+ - country
+ required:
+ - size
+ - location
+```
+
+The Swagger "[Describing
+Parameters](https://swagger.io/docs/specification/describing-parameters/)"
+documentation has more examples.
+
+##### Crossplane reserved fields
+
+Crossplane doesn't allow the following fields in a schema:
+* `spec.resourceRef`
+* `spec.resourceRefs`
+* `spec.claimRef`
+* `spec.writeConnectionSecretToRef`
+* `status.conditions`
+* `status.connectionDetails`
+
+Crossplane ignores any fields matching the reserved fields.
+
+#### Serve and reference a schema
+
+To use a schema it must be
+{{}}served: true{{ }}
+and
+{{}}referenceable: true{{ }}.
+
+```yaml {label="served"}
+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
+```
+
+Composite resources can use any schema version set as
+{{}}served: true{{ }}.
+Kubernetes rejects any composite resource using a schema version set as `served:
+false`.
+
+{{< hint "tip" >}}
+Setting a schema version as `served:false` causes errors for users using an older
+schema. This can be an effective way to identify and upgrade users before
+deleting the older schema version.
+{{< /hint >}}
+
+The {{}}referenceable: true{{ }}
+field indicates which version of the schema Compositions use. Only one
+version can be `referenceable`.
+
+{{< hint "note" >}}
+Changing which version is `referenceable:true` requires [updating the
+`compositeTypeRef.apiVersion`]({{[}})
+of any Compositions referencing that XRD.
+{{< /hint >}}
+
+
+#### Multiple schema versions
+
+{{]}}
+Crossplane supports defining multiple `versions`, but the schema of each version
+can't change any existing fields, also called "making a breaking change."
+
+Breaking schema changes between versions requires the use of [conversion
+webhooks](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion).
+
+New versions may define new optional parameters, but new required fields are
+a "breaking change."
+
+
+
+
+Crossplane XRDs use Kubernetes custom resource definitions for versioning.
+Read the Kubernetes documentation on
+[versions in CustomResourceDefinitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/)
+for more background on versions and breaking changes.
+
+
+Crossplane recommends implementing breaking schema changes as brand new XRDs.
+{{< /hint >}}
+
+For XRDs, to create a new version of an API add a new
+{{}}name{{ }} in the
+{{}}versions{{ }}
+list.
+
+For example, this XRD version
+{{}}v1alpha1{{ }} only has the field
+{{}}region{{ }}.
+
+A second version,
+{{}}v1{{ }} expands the API to have both
+{{}}region{{ }} and
+{{}}size{{ }}.
+
+```yaml {label="ver",copy-lines="none"}
+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
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ region:
+ type: string
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ region:
+ type: string
+ size:
+ type: string
+```
+
+{{}}
+
+Changing or expanding the XRD schema requires restarting the [Crossplane
+pod]({{[}}) to take effect.
+{{< /hint >}}
+
+### Enable Claims
+
+Optionally, XRDs can allow Claims to use the XRD API.
+
+{{]}}
+
+Read the [Claims]({{[}}) page for more
+information about Claims.
+{{] }}
+
+XRDs offer Claims with a
+{{}}claimNames{{ }} object.
+
+The {{}}claimNames{{ }} defines a
+{{}}kind{{ }} and
+{{}}plural{{ }} like the XRD
+{{}}names{{ }} object.
+Also like XRD
+{{}}names{{ }}, use UpperCamelCase
+for the
+{{}}kind{{ }} and lowercase for the
+{{}}plural{{ }}.
+
+The Claim
+{{}}kind{{ }} and
+{{}}plural{{ }} must be unique. They
+can't match any other Claim or other XRD
+{{}}kind{{ }}.
+
+{{}}
+Common Crossplane convention is to use
+{{}}claimNames{{ }} that match the XRD
+{{}}names{{ }}, but without the beginning
+"x."
+{{ }}
+
+```yaml {label="claim",copy-lines="none"}
+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
+ claimNames:
+ kind: Database
+ plural: databases
+ versions:
+ # Removed for brevity
+```
+
+{{}}
+You can't change the
+{{}}claimNames{{ }}
+after they're defined. You must delete and
+recreate the XRD to change the
+{{}}claimNames{{ }}.
+{{ }}
+
+### Manage connection secrets
+
+When a composite resource creates managed resources, Crossplane provides any
+[connection secrets]({{[}})
+to the composite resource or Claim. This requires the creators of composite
+resources and Claims to know the secrets provided by a managed resource.
+In other cases, Crossplane administrators may not want to expose some or all the
+generated connection secrets.
+
+XRDs can define a list of
+{{]}}connectionSecretKeys{{ }}
+to limit what's provided to a composite resource or Claim.
+
+Crossplane only provides the keys listed in the
+{{}}connectionSecretKeys{{ }}
+to the composite resource or Claim using this XRD. Any other connection
+secrets aren't passed to the composite resource or Claim.
+
+{{}}
+The keys listed in the
+{{}}connectionSecretKeys{{ }} must match the
+key names listed in the Composition's `connectionDetails`.
+
+An XRD ignores any keys listed that aren't created by a managed resource.
+
+For more information read the
+[Composition documentation]({{[}}).
+{{< /hint >}}
+
+
+For example, an XRD passes the keys
+{{]}}username{{ }},
+{{}}password{{ }} and
+{{}}address{{ }}.
+
+Composite resources or Claims save these in the secret defined by their
+`writeConnectionSecretToRef` field.
+
+```yaml {label="key",copy-lines="none"}
+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
+ connectionSecretKeys:
+ - username
+ - password
+ - address
+ versions:
+ # Removed for brevity
+```
+
+{{}}
+You can't change the `connectionSecretKeys` of an XRD. You must delete and
+recreate the XRD to change the `connectionSecretKeys`.
+{{ }}
+
+For more information on connection secrets read the [Connection Secrets
+knowledge base article]({{[}}).
+
+### Set composite resource defaults
+XRDs can set default parameters for composite resources and Claims.
+
+
+#### defaultCompositeDeletePolicy
+
+The `defaultCompositeDeletePolicy` defines the deletion policy for composite
+resources and claims.
+
+Using a `defaultCompositeDeletePolicy: Background` policy deletes
+the composite resource or Claim and relies on Kubernetes to delete the remaining
+dependent objects, like managed resources or secrets.
+
+Using `defaultCompositeDeletePolicy: Foreground` causes Kubernetes to attach a
+`foregroundDeletion` finalizer to the composite resource or Claim. Kubernetes
+deletes all the dependent objects before deleting the composite resource or
+Claim.
+
+The default value is `defaultCompositeDeletePolicy: Background`.
+
+Set
+{{]}}defaultCompositeDeletePolicy: Foreground{{ }}
+to change the XRD deletion policy.
+
+```yaml {label="delete",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xdatabases.custom-api.example.org
+spec:
+ defaultCompositeDeletePolicy: Foreground
+ group: custom-api.example.org
+ names:
+ # Removed for brevity
+ versions:
+ # Removed for brevity
+```
+
+
+#### defaultCompositionRef
+
+It's possible for multiple [Compositions]({{[}}) to
+reference the same XRD. If more than one Composition references the same XRD,
+the composite resource or Claim must select which Composition to use.
+
+An XRD can define the default Composition to use with the
+`defaultCompositionRef` value.
+
+Set a
+{{]}}defaultCompositionRef{{ }}
+to set the default Composition.
+
+```yaml {label="defaultComp",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xdatabases.custom-api.example.org
+spec:
+ defaultCompositionRef:
+ name: myComposition
+ group: custom-api.example.org
+ names:
+ # Removed for brevity
+ versions:
+ # Removed for brevity
+```
+
+
+#### defaultCompositionUpdatePolicy
+
+
+Changes to a Composition generate a new Composition revision. By default all
+composite resources and Claims use the updated Composition revision.
+
+Set the XRD `defaultCompositionUpdatePolicy` to `Manual` to prevent composite
+resources and Claims from automatically using the new revision.
+
+The default value is `defaultCompositionUpdatePolicy: Automatic`.
+
+Set {{}}defaultCompositionUpdatePolicy: Manual{{ }}
+to set the default Composition update policy for composite resources and Claims
+using this XRD.
+
+```yaml {label="compRev",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xdatabases.custom-api.example.org
+spec:
+ defaultCompositionUpdatePolicy: Manual
+ group: custom-api.example.org
+ names:
+ # Removed for brevity
+ versions:
+ # Removed for brevity
+```
+
+
+#### enforcedCompositionRef
+
+To require all composite resources or Claims to use a specific Composition use
+the `enforcedCompositionRef` setting in the XRD.
+
+For example, to require all composite resources and Claims using this XRD to use
+the Composition
+{{}}myComposition{{ }}
+set
+{{}}enforcedCompositionRef.name: myComposition{{ }}.
+
+```yaml {label="defaultComp",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xdatabases.custom-api.example.org
+spec:
+ enforcedCompositionRef:
+ name: myComposition
+ group: custom-api.example.org
+ names:
+ # Removed for brevity
+ versions:
+ # Removed for brevity
+```
+
+## Verify a CompositeResourceDefinition
+
+Verify an XRD with `kubectl get compositeresourcedefinition` or the short form,
+{{}}kubectl get xrd{{ }}.
+
+```yaml {label="getxrd",copy-lines="1"}
+kubectl get xrd
+NAME ESTABLISHED OFFERED AGE
+xdatabases.custom-api.example.org True True 22m
+```
+
+The `ESTABLISHED` field indicates Crossplane installed the Kubernetes custom
+resource definition for this XRD.
+
+The `OFFERED` field indicates this XRD offers a Claim and Crossplane installed
+the Kubernetes custom resource definitions for the Claim.
+
+### XRD conditions
+Crossplane uses a standard set of `Conditions` for XRDs.
+View the conditions of a XRD under their `Status` with
+`kubectl describe xrd`.
+
+```yaml {copy-lines="none"}
+kubectl describe xrd
+Name: xpostgresqlinstances.database.starter.org
+API Version: apiextensions.crossplane.io/v1
+Kind: CompositeResourceDefinition
+# Removed for brevity
+Status:
+ Conditions:
+ Reason: WatchingCompositeResource
+ Status: True
+ Type: Established
+ Reason: WatchingCompositeResourceClaim
+ Status: True
+ Type: Offered
+# Removed for brevity
+```
+
+
+#### WatchingCompositeResource
+
+`Reason: WatchingCompositeResource` indicates Crossplane defined the new
+Kubernetes custom resource definitions related to the composite resource and is
+watching for the creation of new composite resources.
+
+```yaml
+Type: Established
+Status: True
+Reason: WatchingCompositeResource
+```
+
+
+#### TerminatingCompositeResource
+
+`Reason: TerminatingCompositeResource` indicates Crossplane is deleting the
+custom resource definitions related to the composite resource and is
+terminating the composite resource controller.
+
+```yaml
+Type: Established
+Status: False
+Reason: TerminatingCompositeResource
+```
+
+
+#### WatchingCompositeResourceClaim
+
+`Reason: WatchingCompositeResourceClaim` indicates Crossplane defined the new
+Kubernetes custom resource definitions related to the offered Claims and is
+watching for the creation of new Claims.
+
+```yaml
+Type: Offered
+Status: True
+Reason: WatchingCompositeResourceClaim
+```
+
+
+#### TerminatingCompositeResourceClaim
+
+`Reason: TerminatingCompositeResourceClaim` indicates Crossplane is deleting the
+custom resource definitions related to the offered Claims and is
+terminating the Claims controller.
+
+```yaml
+Type: Offered
+Status: False
+Reason: TerminatingCompositeResourceClaim
+```
\ No newline at end of file
diff --git a/content/v1.13/concepts/composite-resources.md b/content/v1.13/concepts/composite-resources.md
new file mode 100644
index 00000000..41c89a6c
--- /dev/null
+++ b/content/v1.13/concepts/composite-resources.md
@@ -0,0 +1,472 @@
+---
+title: Composite Resources
+weight: 50
+description: "Composite resources, an XR or XRs, represent a collection of related cloud resources."
+---
+
+A composite resource represents a set of managed resources as a single
+Kubernetes object. Crossplane creates composite resources when users access a
+custom API, defined in the CompositeResourceDefinition.
+
+{{}}
+Composite resources are a _composite_ of managed resources.
+A _Composition_ defines how to _compose_ the managed resources together.
+{{< /hint >}}
+
+{{}}
+Crossplane has four core components that users commonly mix up:
+
+* [Compositions]({{[}}) - A template to define how to create resources.
+* [Composite Resource Definition]({{][}})
+ (`XRD`) - A custom API specification.
+* Composite Resource (`XR`) - This page. Created by
+ using the custom API defined in a Composite Resource Definition. XRs use the
+ Composition template to create new managed resources.
+* [Claims]({{][}}) (`XRC`) - Like a Composite Resource, but
+ with namespace scoping.
+{{] }}
+
+## Creating composite resources
+
+Creating composite resources requires a
+[Composition]({{[}}) and a
+[CompositeResourceDefinition]({{][}})
+(`XRD`).
+The Composition defines the set of resources to create.
+The XRD defines the custom API users call to request the set of resources.
+
+
+
+XRDs define the API used to create a composite resource.
+For example,
+this {{]}}CompositeResourceDefinition{{ }}
+creates a custom API endpoint
+{{}}xmydatabases.example.org{{ }}.
+
+```yaml {label="xrd1",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xmydatabases.example.org
+spec:
+ group: example.org
+ names:
+ kind: xMyDatabase
+ plural: xmydatabases
+ # Removed for brevity
+```
+
+When a user calls the custom API,
+{{}}xmydatabases.example.org{{ }},
+Crossplane chooses the Composition to use based on the Composition's
+{{}}compositeTypeRef{{ }}
+
+```yaml {label="typeref",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: my-composition
+spec:
+ compositeTypeRef:
+ apiVersion: example.org/v1alpha1
+ kind: xMyDatabase
+ # Removed for brevity
+```
+
+The Composition
+{{}}compositeTypeRef{{ }} matches the
+XRD {{}}group{{ }} and
+{{}}kind{{ }}.
+
+Crossplane creates the resources defined in the matching Composition and
+represents them as a single `composite` resource.
+
+```shell{copy-lines="1"}
+kubectl get composite
+NAME SYNCED READY COMPOSITION AGE
+my-composite-resource True True my-composition 4s
+```
+
+### Naming external resources
+By default, managed resources created by a composite resource have the name of
+the composite resource, followed by a random suffix.
+
+
+
+For example, a composite resource named "my-composite-resource" creates external
+resources named "my-composite-resource-fqvkw."
+
+
+
+Resource names can be deterministic by applying an
+{{}}annotation{{ }} to the composite
+resource.
+
+```yaml {label="annotation",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+ annotations:
+ crossplane.io/external-name: my-custom-name
+# Removed for brevity
+```
+
+Inside the Composition, use a
+{{}}patch{{ }}
+to apply the external-name to the resources.
+
+The {{}}fromFieldPath{{ }} patch copies the
+{{}}metadata.annotations{{ }} field from
+the composite resource to the
+{{}}metadata.annotations{{ }} inside the
+managed resource.
+
+{{}}
+If a managed resource has the `crossplane.io/external-name` annotation
+Crossplane uses the annotation value to name the external resource.
+{{ }}
+
+```yaml {label="comp",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: my-composition
+spec:
+ resources:
+ - name: database
+ base:
+ # Removed for brevity
+ patches:
+ - fromFieldPath: metadata.annotations
+ toFieldPath: metadata.annotations
+```
+
+For more information on patching resources refer to the [Patch and
+Transform]({{[}}) documentation.
+
+### Composition selection
+
+Select a specific Composition for a composite resource to use with
+{{]}}compositionRef{{ }}
+
+{{}}
+The selected Composition must allow the composite resource to use it with a
+`compositeTypeRef`. Read more about the `compositeTypeRef` field in the
+[Enabling Composite Resources]({{[}})
+section of the Composition documentation.
+{{< /hint >}}
+
+```yaml {label="compref",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ compositionRef:
+ name: my-other-composition
+ # Removed for brevity
+```
+
+A composite resource can also select a Composition based on labels instead of
+the exact name with a
+{{]}}compositionSelector{{ }}.
+
+Inside the {{}}matchLabels{{ }} section
+provide one or more Composition labels to match.
+
+```yaml {label="complabel",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ compositionSelector:
+ matchLabels:
+ environment: production
+ # Removed for brevity
+```
+
+### Composition revision policy
+
+Crossplane tracks changes to Compositions as
+[Composition revisions]({{[}}) .
+
+A composite resource can use
+a {{]}}compositionUpdatePolicy{{ }} to
+manually or automatically reference newer Composition revisions.
+
+The default
+{{}}compositionUpdatePolicy{{ }} is
+"Automatic." Composite resources automatically use the latest Composition
+revision.
+
+Change the policy to
+{{}}Manual{{ }} to prevent composite
+resources from automatically upgrading.
+
+```yaml {label="comprev",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ compositionUpdatePolicy: Manual
+ # Removed for brevity
+```
+
+### Composition revision selection
+
+Crossplane records changes to Compositions as
+[Composition revisions]({{[}}).
+A composite resource can
+select a specific Composition revision.
+
+
+Use {{]}}compositionRevisionRef{{ }} to
+select a specific Composition revision by name.
+
+For example, to select a specific Composition revision use the name of the
+desired Composition revision.
+
+```yaml {label="comprevref",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ compositionRevisionRef: my-composition-b5aa1eb
+ # Removed for brevity
+```
+
+{{}}
+Find the Composition revision name from
+{{}}kubectl get compositionrevision{{ }}
+
+```shell {label="getcomprev",copy-lines="1"}
+kubectl get compositionrevision
+NAME REVISION XR-KIND XR-APIVERSION AGE
+my-composition-5c976ad 1 xmydatabases example.org/v1alpha1 65m
+my-composition-b5aa1eb 2 xmydatabases example.org/v1alpha1 64m
+```
+{{< /hint >}}
+
+A Composite resource can also select Composition revisions based on labels
+instead of the exact name with a
+{{}}compositionRevisionSelector{{ }}.
+
+Inside the {{}}matchLabels{{ }}
+section provide one or more Composition revision labels to match.
+
+
+```yaml {label="comprevsel",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ compositionRevisionSelector:
+ matchLabels:
+ channel: dev
+ # Removed for brevity
+```
+
+### Manage connection secrets
+
+When a composite resource creates resources, Crossplane provides any
+[connection secrets]({{[}})
+to the composite resource.
+
+{{]}}
+
+A resource may only access connection secrets allowed by the XRD. By
+default XRDs provide access to all connection secrets generated by managed
+resources.
+Read more about [managing connection
+secrets]({{[}})
+in the XRD documentation.
+{{< /hint >}}
+
+Use
+{{]}}writeConnectionSecretToRef{{ }}
+to specify where the composite resource writes their connection secrets to.
+
+For example, this composite resource saves the connection secrets in a
+Kubernetes secret object named
+{{}}my-secret{{ }} in the namespace
+{{}}crossplane-system{{ }}.
+
+```yaml {label="writesecret",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ writeConnectionSecretToRef:
+ name: my-secret
+ namespace: crossplane-system
+ # Removed for brevity
+```
+
+Composite resources can write connection secrets to an
+[external secret store]({{[}}),
+like HashiCorp Vault.
+
+{{]}}
+External secret stores are an alpha feature. Alpha features aren't enabled by
+default.
+{{< /hint >}}
+
+Use the {{}}publishConnectionDetailsTo{{ }} field to save connection
+secrets to an external secrets store.
+
+```yaml {label="publishsecret",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+spec:
+ publishConnectionDetailsTo:
+ name: my-external-secret-store
+ # Removed for brevity
+```
+
+Read the [External Secrets Store]({{[}}) documentation for more information on using
+external secret stores.
+
+For more information on connection secrets read the [Connection Secrets
+knowledge base article]({{][}}).
+
+### Pausing composite resources
+
+
+Crossplane supports pausing composite resources. A paused composite resource
+doesn't check or make changes on its external resources.
+
+
+To pause a composite resource apply the
+{{]}}crossplane.io/paused{{ }} annotation.
+
+```yaml {label="pause",copy-lines="none"}
+apiVersion: example.org/v1alpha1
+kind: xMyDatabase
+metadata:
+ name: my-composite-resource
+ annotations:
+ crossplane.io/paused: "true"
+spec:
+ # Removed for brevity
+```
+
+## Verify composite resources
+Use
+{{}}kubectl get composite{{ }}
+to view all the composite resources Crossplane created.
+
+```shell{copy-lines="1",label="getcomposite"}
+kubectl get composite
+NAME SYNCED READY COMPOSITION AGE
+my-composite-resource True True my-composition 4s
+```
+
+Use `kubectl get` for the specific custom API endpoint to view
+only those resources.
+
+```shell {copy-lines="1"}
+kubectl get xMyDatabase.example.org
+NAME SYNCED READY COMPOSITION AGE
+my-composite-resource True True my-composition 12m
+```
+
+Use
+{{}}kubectl describe composite{{ }}
+to view the linked
+{{}}Composition Ref{{ }},
+and unique managed resources created in the
+{{}}Resource Refs{{ }}.
+
+
+```yaml {copy-lines="1",label="desccomposite"}
+kubectl describe composite my-composite-resource
+Name: my-composite-resource
+API Version: example.org/v1alpha1
+Kind: xMyDatabase
+Spec:
+ Composition Ref:
+ Name: my-composition
+ Composition Revision Ref:
+ Name: my-composition-cf2d3a7
+ Composition Update Policy: Automatic
+ Resource Refs:
+ API Version: s3.aws.upbound.io/v1beta1
+ Kind: Bucket
+ Name: my-composite-resource-fmrks
+ API Version: dynamodb.aws.upbound.io/v1beta1
+ Kind: Table
+ Name: my-composite-resource-wnr9t
+# Removed for brevity
+```
+
+### Composite resource conditions
+
+The conditions of composite resources match the conditions of their managed
+resources.
+
+Read the
+[conditions section]({{[}}) of the
+managed resources documentation for details.
+
+## Composite resource labels
+
+Crossplane adds labels to composite resources to show their relationship to
+other Crossplane components.
+
+### Composite label
+Crossplane adds the
+{{]}} crossplane.io/composite{{ }} label
+to all composite resources. The label matches the name of the composite.
+Crossplane applies the composite label to any manged resource created by a
+composite, creating a reference between the managed resource and owning
+composite resource.
+
+```shell {label="claimname",copy-lines="1"}
+kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
+Name: my-claimed-database2-x9rx9
+Namespace:
+Labels: crossplane.io/composite=my-claimed-database-x9rx9
+```
+
+### Claim name label
+Crossplane adds the
+{{}}crossplane.io/claim-name{{ }}
+label to composite resources created from a Claim. The label indicates the name
+of the Claim linked to this composite resource.
+
+```shell {label="claimname",copy-lines="1"}
+kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
+Name: my-claimed-database2-x9rx9
+Namespace:
+Labels: crossplane.io/claim-name=my-claimed-database
+```
+
+Composite resources created directly, without using a Claim, don't have a
+{{}}crossplane.io/claim-name{{ }}
+label.
+
+### Claim namespace label
+Crossplane adds the
+{{}}crossplane.io/claim-namespace{{ }}
+label to composite resources created from a Claim. The label indicates the
+namespace of the Claim linked to this composite resource.
+
+```shell {label="claimname",copy-lines="1"}
+kubectl describe xmydatabase.example.org/my-claimed-database-x9rx9
+Name: my-claimed-database2-x9rx9
+Namespace:
+Labels: crossplane.io/claim-namespace=default
+```
+
+Composite resources created directly, without using a Claim, don't have a
+{{}}crossplane.io/claim-namespace{{ }}
+label.
\ No newline at end of file
diff --git a/content/v1.13/concepts/composition-functions.md b/content/v1.13/concepts/composition-functions.md
new file mode 100644
index 00000000..6f0e0aee
--- /dev/null
+++ b/content/v1.13/concepts/composition-functions.md
@@ -0,0 +1,1019 @@
+---
+title: Composition Functions
+state: alpha
+alphaVersion: "1.11"
+weight: 80
+description: "Composition Functions or XFNs allow for complex Composition patches"
+aliases:
+ - /knowledge-base/guides/composition-functions
+---
+
+
+
+Composition Functions allow you to supplement or replace your Compositions with
+advanced logic not implementable through available patching strategies.
+
+
+You can build a Function using general purpose programming
+languages such as Go or Python, or relevant tools such as Helm,
+[Kustomize](https://kustomize.io/), or
+[CUE](https://cuelang.org/).
+
+Functions compliment contemporary "Patch and Transform" (P&T) style
+Composition. It's possible to use only P&T, only Functions, or a mix of both in
+the same Composition.
+
+```yaml
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example
+spec:
+ compositeTypeRef:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ functions:
+ - name: my-cool-Function
+ type: Container
+ container:
+ image: xpkg.upbound.io/my-cool-Function:0.1.0
+```
+
+A Composition Function is a short-lived OCI container that tells Crossplane how
+to reconcile a Composite Resource (XR). The preceding example shows a minimal
+`Composition` that uses a Composition Function. Note that it has a `functions`
+array rather than the typical P&T style array of `resources`.
+
+## Enabling functions
+
+Enable support for Composition Functions by enabling the alpha feature flag in Crossplane with `helm install --args`.
+
+```shell
+helm install crossplane --namespace crossplane-system crossplane-stable/crossplane \
+ --create-namespace \
+ --set "args={--debug,--enable-composition-functions}" \
+ --set "xfn.enabled=true" \
+ --set "xfn.args={--debug}"
+```
+
+The preceding Helm command installs Crossplane with the Composition Functions
+feature flag enabled, and with the reference _xfn_ Composition Function runner
+deployed as a sidecar container. Confirm Composition Functions were enabled by
+looking for a log line:
+
+```shell {copy-lines="1"}
+ kubectl -n crossplane-system logs -l app=crossplane
+{"level":"info","ts":1674535093.36186,"logger":"crossplane","msg":"Alpha feature enabled","flag":"EnableAlphaCompositionFunctions"}
+```
+
+You should see the log line emitted shortly after Crossplane starts.
+
+
+## Using functions
+
+To use Composition Functions you must:
+
+1. Find one or more Composition Functions, or write your own.
+2. Create a `Composition` that uses your Functions.
+3. Create an XR that uses your `Composition`.
+
+Your XRs, claims, and providers don't need to be updated or otherwise aware
+of Composition Functions to use them. They need only use a `Composition` that
+includes one or more entries in its `spec.functions` array.
+
+Composition Functions are designed to be run in a pipeline, so you can 'stack'
+several of them together. Each Function is passed the output of the previous
+Function as its input. Functions can also be used in conjunction with P&T
+Composition (a `spec.resources` array).
+
+In the following example P&T Composition composes an RDS instance. A pipeline of
+(hypothetical) Composition Functions then mutates the desired RDS instance by
+adding a randomly generated password, and composes an RDS security group.
+
+```yaml
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example
+spec:
+ compositeTypeRef:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ resources:
+ - name: rds-instance
+ base:
+ apiVersion: rds.aws.upbound.io/v1beta1
+ kind: Instance
+ spec:
+ forProvider:
+ dbName: exmaple
+ instanceClass: db.t3.micro
+ region: us-west-2
+ skipFinalSnapshot: true
+ username: exampleuser
+ engine: postgres
+ engineVersion: "12"
+ patches:
+ - fromFieldPath: spec.parameters.storageGB
+ toFieldPath: spec.forProvider.allocatedStorage
+ connectionDetails:
+ - type: FromFieldPath
+ name: username
+ fromFieldPath: spec.forProvider.username
+ - type: FromConnectionSecretKey
+ name: password
+ fromConnectionSecretKey: attribute.password
+ functions:
+ - name: rds-instance-password
+ type: Container
+ container:
+ image: xpkg.upbound.io/provider-aws-xfns/random-rds-password:v0.1.0
+ - name: compose-dbsecuritygroup
+ type: Container
+ container:
+ image: xpkg.upbound.io/example-org/compose-rds-securitygroup:v0.9.0
+```
+
+
+Use `kubectl explain` to explore the configuration options available when using
+Composition Functions, or take a look at the following example.
+
+{{< expand "View Composition Function configuration options" >}}
+```shell {copy-lines="1"}
+kubectl explain composition.spec.functions
+KIND: Composition
+VERSION: apiextensions.crossplane.io/v1
+
+RESOURCE: Functions <[]Object>
+
+DESCRIPTION:
+ Functions is list of Composition Functions that will be used when a
+ composite resource referring to this composition is created. At least one
+ of resources and Functions must be specified. If both are specified the
+ resources will be rendered first, then passed to the Functions for further
+ processing. THIS IS AN ALPHA FIELD. Do not use it in production. It is not
+ honored unless the relevant Crossplane feature flag is enabled, and may be
+ changed or removed without notice.
+
+ A Function represents a Composition Function.
+
+FIELDS:
+ config <>
+ Config is an optional, arbitrary Kubernetes resource (i.e. a resource with
+ an apiVersion and kind) that will be passed to the Composition Function as
+ the 'config' block of its FunctionIO.
+
+ container
+ Container configuration of this Function.
+
+ name -required-
+ Name of this Function. Must be unique within its Composition.
+
+ type -required-
+ Type of this Function.
+```
+{{< /expand >}}
+
+{{< expand "An example of most Composition Function configuration options" >}}
+```yaml
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example
+spec:
+ compositeTypeRef:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ functions:
+ - name: my-cool-Function
+ # Currently only Container is supported. Other types may be added in future.
+ type: Container
+ # Configuration specific to type: Container.
+ container:
+ # The OCI image to pull and run.
+ image: xkpg.io/my-cool-Function:0.1.0
+ # Whether to pull the Function image Never, Always, or IfNotPresent.
+ imagePullPolicy: IfNotPresent
+ # Note that only resource limits are supported - not requests.
+ # The Function will be run with the specified resource limits, specified
+ # in Kubernetes-style resource.Quantity form.
+ resources:
+ limits:
+ # Defaults to 128Mi
+ memory: 64Mi
+ # Defaults to 100m (a 10th of a core)
+ cpu: 250m
+ # Defaults to 'Isolated' - an isolated network namespace with no network
+ # access. Use 'Runner' to allow a Function access to the runner's (the xfn
+ # container's) network namespace.
+ network:
+ policy: Runner
+ # How long the Function may run before it's killed. Defaults to 20s.
+ # Keep in mind the Function pipeline is typically invoked once every
+ # 30 to 60 seconds - sometimes more frequently during error conditions.
+ timeout: 30s
+ # An arbitrary Kubernetes resource. Passed to the Function as the config
+ # block of its FunctionIO. Doesn't need to exist as a Custom Resource (CR),
+ # since this resource doesn't exist by itself in the API server but must be
+ # a valid Kubernetes resource (have an apiVersion and kind).
+ config:
+ apiVersion: database.example.org/v1alpha1
+ kind: Config
+ metadata:
+ name: cloudsql
+ spec:
+ version: POSTGRES_9_6
+```
+{{< /expand >}}
+
+Use `kubectl describe ` to debug Composition Functions. Look
+for status conditions and events. Most Functions will emit events associated
+with the XR if they experience issues.
+
+## Building a function
+
+ Crossplane doesn't have opinions about how a Composition Function is
+ implemented. Functions must:
+
+ * Be packaged as an OCI image, where the `ENTRYPOINT` is the Function.
+ * Accept input in the form of a `FunctionIO` document on stdin.
+ * Return the `FunctionIO` they were passed, optionally mutated, on stdout.
+ * Run within the constraints specified by the Composition that includes them,
+ such as timeouts, compute, network access.
+
+This means Functions may be written using a general purpose programming language
+like Python, Go, or TypeScript. They may also be implemented using a shell
+script, or an existing tool like Helm or Kustomize.
+
+### FunctionIO
+
+When a Composition Function runner like `xfn` runs your Function it will write
+`FunctionIO` to its stdin. A `FunctionIO` is a Kubernetes style YAML manifest.
+It's not a custom resource (it never gets created in the API server) but it
+follows Kubernetes conventions.
+
+A `FunctionIO` consists of:
+
+* An optional, arbitrary `config` object.
+* The `observed` state of the XR, any existing composed resources, and their connection details.
+* The `desired` state of the XR and any composed resources.
+* Optional `results` of the Function pipeline.
+
+Here's a brief example of a `FunctionIO`:
+
+```yaml
+apiVersion: apiextensions.crossplane.io/v1alpha1
+kind: FunctionIO
+config:
+ apiVersion: database.example.org/v1alpha1
+ kind: Config
+ metadata:
+ name: cloudsql
+ spec:
+ version: POSTGRES_9_6
+observed:
+ composite:
+ resource:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ metadata:
+ name: platform-ref-gcp-db-p9wrj
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+ resources:
+ - name: db-instance
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ metadata:
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+desired:
+ composite:
+ resource:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ metadata:
+ name: platform-ref-gcp-db-p9wrj
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+ resources:
+ - name: db-instance
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ metadata:
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ - name: db-user
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: User
+ metadata:
+ name: platform-ref-gcp-db-p9wrj-z8lpz
+ connectionDetails:
+ - name: password
+ type: FromValue
+ value: very-secret
+ readinessChecks:
+ - type: None
+results:
+- severity: Normal
+ message: "Successfully composed GCP SQL user"
+```
+
+The `config` object is copied from the `Composition`. It will match what's
+passed as your Function's `config` in the `Functions` array. It must be a valid
+Kubernetes object - have an `apiVersion` and `kind`.
+
+The `observed` state of the XR and any existing composed resources reflects the
+observed state at the beginning of a reconcile, before any Composition happens.
+Your Function will only see composite and composed resources that _actually
+exist_ in the API server in the `observed` state. The `observed` state also
+includes any observed connection details. Initial function invocations
+might see empty connection details, but once external resources are created,
+connection details will be passed to the functions. Access to the connection
+details enables us to implement quite sophisticated tweaks on composed resources.
+
+For example, if a composition is declared on two or more resources, it is possible
+to use one resource's connection details to update another. This ability is not available
+with any of the available patch types available.
+
+The `desired` state of the XR and composed resources is how your Function tells
+Crossplane what it should do. Crossplane 'bootstraps' the initial desired state
+passed to a Function pipeline with:
+
+* A copy of the observed state of the XR.
+* A copy of the observed state of any existing composed resources.
+* Any new composed resources or modifications to observed resources produced
+ from the `resources` array.
+
+When adding a new desired resource to the `desired.resources` array you don't
+need to:
+
+* Update the XR's resource references.
+* Add any composition annotations like `crossplane.io/composite-resource-name`.
+* Set the XR as a controller/owner reference of the desired resource.
+
+Crossplane will take care of all of these for you. It won't do anything else,
+including setting a sensible `metadata.name` for the new composed resource -
+this is up to your Function.
+
+Finally, the `results` array allows your Function to surface events and debug
+logs on the XR. Results support the following severities:
+
+* `Normal` emits a debug log and a `Normal` event associated with the XR.
+* `Warning` emits a debug log and a `Warning` event associated with the XR.
+* `Fatal` stops the Composition process before applying any changes.
+
+When Crossplane encounters a `Fatal` result it will finish running the
+Composition Function pipeline. Crossplane will then return an error without
+applying any changes to the API server. Crossplane surfaces this error as a
+`Warning` event, a debug log, and by setting the `Synced` status condition of
+the XR to "False".
+
+The preceding example is heavily edited for brevity. Expand the following
+example for a more detailed, realistic, and commented example of a `FunctionIO`.
+
+{{< expand "A more detailed example" >}}
+In this example a `XPostgreSQLInstance` XR has one existing composed resource -
+`db-instance`. The composition Function returns a `desired` object with one new
+composed resource, a `db-user`, to tell Crossplane it should also create a
+database user.
+
+```yaml
+apiVersion: apiextensions.crossplane.io/v1alpha1
+kind: FunctionIO
+config:
+ apiVersion: database.example.org/v1alpha1
+ kind: Config
+ metadata:
+ name: cloudsql
+ spec:
+ version: POSTGRES_9_6
+observed:
+ # The observed state of the Composite Resource.
+ composite:
+ resource:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ metadata:
+ creationTimestamp: "2023-01-27T23:47:12Z"
+ finalizers:
+ - composite.apiextensions.crossplane.io
+ generateName: platform-ref-gcp-db-
+ generation: 5
+ labels:
+ crossplane.io/claim-name: platform-ref-gcp-db
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: platform-ref-gcp-db-p9wrj
+ name: platform-ref-gcp-db-p9wrj
+ resourceVersion: "6817"
+ uid: 96623f41-be2e-4eda-84d4-9668b48e284d
+ spec:
+ claimRef:
+ apiVersion: database.example.org/v1alpha1
+ kind: PostgreSQLInstance
+ name: platform-ref-gcp-db
+ namespace: default
+ compositionRef:
+ name: xpostgresqlinstances.database.example.org
+ compositionRevisionRef:
+ name: xpostgresqlinstances.database.example.org-eb6c684
+ compositionUpdatePolicy: Automatic
+ parameters:
+ storageGB: 10
+ resourceRefs:
+ - apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ writeConnectionSecretToRef:
+ name: 96623f41-be2e-4eda-84d4-9668b48e284d
+ namespace: upbound-system
+ status:
+ conditions:
+ - lastTransitionTime: "2023-01-27T23:47:12Z"
+ reason: ReconcileSuccess
+ status: "True"
+ type: Synced
+ - lastTransitionTime: "2023-01-28T00:09:12Z"
+ reason: Creating
+ status: "False"
+ type: Ready
+ connectionDetails:
+ lastPublishedTime: "2023-01-28T00:08:12Z"
+ # Any observed Composite Resource connection details.
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+ # The observed state of any existing Composed Resources.
+ resources:
+ - name: db-instance
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ metadata:
+ annotations:
+ crossplane.io/composition-resource-name: db-instance
+ crossplane.io/external-name: platform-ref-gcp-db-p9wrj-tvvtg
+ creationTimestamp: "2023-01-27T23:47:12Z"
+ finalizers:
+ - finalizer.managedresource.crossplane.io
+ generateName: platform-ref-gcp-db-p9wrj-
+ generation: 80
+ labels:
+ crossplane.io/claim-name: platform-ref-gcp-db
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: platform-ref-gcp-db-p9wrj
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ ownerReferences:
+ - apiVersion: database.example.org/v1alpha1
+ blockOwnerDeletion: true
+ controller: true
+ kind: XPostgreSQLInstance
+ name: platform-ref-gcp-db-p9wrj
+ uid: 96623f41-be2e-4eda-84d4-9668b48e284d
+ resourceVersion: "7992"
+ uid: 43919834-fdce-427e-85d9-d03eab9501f1
+ spec:
+ forProvider:
+ databaseVersion: POSTGRES_13
+ deletionProtection: false
+ project: example
+ region: us-west2
+ settings:
+ - diskSize: 10
+ ipConfiguration:
+ - privateNetwork: projects/example/global/networks/platform-ref-gcp-cluster
+ privateNetworkRef:
+ name: platform-ref-gcp-cluster
+ tier: db-f1-micro
+ providerConfigRef:
+ name: default
+ writeConnectionSecretToRef:
+ name: 96623f41-be2e-4eda-84d4-9668b48e284d-gcp-postgresql
+ namespace: upbound-system
+ status:
+ atProvider:
+ connectionName: example:us-west2:platform-ref-gcp-db-p9wrj-tvvtg
+ firstIpAddress: 34.102.103.85
+ id: platform-ref-gcp-db-p9wrj-tvvtg
+ privateIpAddress: 10.135.0.3
+ publicIpAddress: 34.102.103.85
+ settings:
+ - version: 1
+ conditions:
+ - lastTransitionTime: "2023-01-28T00:07:30Z"
+ reason: Available
+ status: "True"
+ type: Ready
+ - lastTransitionTime: "2023-01-27T23:47:14Z"
+ reason: ReconcileSuccess
+ status: "True"
+ type: Synced
+ # Any observed composed resource connection details.
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+desired:
+ # The observed state of the Composite Resource.
+ composite:
+ resource:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ metadata:
+ creationTimestamp: "2023-01-27T23:47:12Z"
+ finalizers:
+ - composite.apiextensions.crossplane.io
+ generateName: platform-ref-gcp-db-
+ generation: 5
+ labels:
+ crossplane.io/claim-name: platform-ref-gcp-db
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: platform-ref-gcp-db-p9wrj
+ name: platform-ref-gcp-db-p9wrj
+ resourceVersion: "6817"
+ uid: 96623f41-be2e-4eda-84d4-9668b48e284d
+ spec:
+ claimRef:
+ e apiVersion: database.example.org/v1alpha1
+ kind: PostgreSQLInstance
+ name: platform-ref-gcp-db
+ namespace: default
+ compositionRef:
+ name: xpostgresqlinstances.database.example.org
+ compositionRevisionRef:
+ name: xpostgresqlinstances.database.example.org-eb6c684
+ compositionUpdatePolicy: Automatic
+ parameters:
+ storageGB: 10
+ resourceRefs:
+ - apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ writeConnectionSecretToRef:
+ name: 96623f41-be2e-4eda-84d4-9668b48e284d
+ namespace: upbound-system
+ status:
+ conditions:
+ - lastTransitionTime: "2023-01-27T23:47:12Z"
+ reason: ReconcileSuccess
+ status: "True"
+ type: Synced
+ - lastTransitionTime: "2023-01-28T00:09:12Z"
+ reason: Creating
+ status: "False"
+ type: Ready
+ connectionDetails:
+ lastPublishedTime: "2023-01-28T00:08:12Z"
+ # Any desired Composite Resource connection details. Your Composition
+ # Function can add new entries to this array and Crossplane will record them
+ # as the XR's connection details.
+ connectionDetails:
+ - name: privateIP
+ value: 10.135.0.3
+ # The desired composed resources.
+ resources:
+ # This db-instance matches the entry in observed. Functions must include any
+ # observed resources in their desired resources array. If you omit an observed
+ # resource from the desired resources array Crossplane will delete it.
+ # Crossplane will 'bootstrap' the desired state passed to the Function
+ # pipeline by copying all observed resources into the desired resources array.
+ - name: db-instance
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: DatabaseInstance
+ metadata:
+ annotations:
+ crossplane.io/composition-resource-name: DBInstance
+ crossplane.io/external-name: platform-ref-gcp-db-p9wrj-tvvtg
+ creationTimestamp: "2023-01-27T23:47:12Z"
+ finalizers:
+ - finalizer.managedresource.crossplane.io
+ generateName: platform-ref-gcp-db-p9wrj-
+ generation: 80
+ labels:
+ crossplane.io/claim-name: platform-ref-gcp-db
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: platform-ref-gcp-db-p9wrj
+ name: platform-ref-gcp-db-p9wrj-tvvtg
+ ownerReferences:
+ - apiVersion: database.example.org/v1alpha1
+ blockOwnerDeletion: true
+ controller: true
+ kind: XPostgreSQLInstance
+ name: platform-ref-gcp-db-p9wrj
+ uid: 96623f41-be2e-4eda-84d4-9668b48e284d
+ resourceVersion: "7992"
+ uid: 43919834-fdce-427e-85d9-d03eab9501f1
+ spec:
+ forProvider:
+ databaseVersion: POSTGRES_13
+ deletionProtection: false
+ project: example
+ region: us-west2
+ settings:
+ - diskSize: 10
+ ipConfiguration:
+ - privateNetwork: projects/example/global/networks/platform-ref-gcp-cluster
+ privateNetworkRef:
+ name: platform-ref-gcp-cluster
+ tier: db-f1-micro
+ providerConfigRef:
+ name: default
+ writeConnectionSecretToRef:
+ name: 96623f41-be2e-4eda-84d4-9668b48e284d-gcp-postgresql
+ namespace: upbound-system
+ status:
+ atProvider:
+ connectionName: example:us-west2:platform-ref-gcp-db-p9wrj-tvvtg
+ firstIpAddress: 34.102.103.85
+ id: platform-ref-gcp-db-p9wrj-tvvtg
+ privateIpAddress: 10.135.0.3
+ publicIpAddress: 34.102.103.85
+ settings:
+ - version: 1
+ conditions:
+ - lastTransitionTime: "2023-01-28T00:07:30Z"
+ reason: Available
+ status: "True"
+ type: Ready
+ - lastTransitionTime: "2023-01-27T23:47:14Z"
+ reason: ReconcileSuccess
+ status: "True"
+ type: Synced
+ # This db-user is a desired composed resource that doesn't yet exist. This
+ # Composition Function is requesting it be created.
+ - name: db-user
+ resource:
+ apiVersion: sql.gcp.upbound.io/v1beta1
+ kind: User
+ metadata:
+ annotations:
+ crossplane.io/composition-resource-name: db-user
+ crossplane.io/external-name: platform-ref-gcp-db-p9wrj-z8lpz
+ creationTimestamp: "2023-01-27T23:47:12Z"
+ finalizers:
+ - finalizer.managedresource.crossplane.io
+ generateName: platform-ref-gcp-db-p9wrj-
+ generation: 115
+ labels:
+ crossplane.io/claim-name: platform-ref-gcp-db
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: platform-ref-gcp-db-p9wrj
+ name: platform-ref-gcp-db-p9wrj-z8lpz
+ ownerReferences:
+ - apiVersion: database.example.org/v1alpha1
+ blockOwnerDeletion: true
+ controller: true
+ kind: XPostgreSQLInstance
+ name: platform-ref-gcp-db-p9wrj
+ uid: 96623f41-be2e-4eda-84d4-9668b48e284d
+ resourceVersion: "9951"
+ uid: ab5dafbe-2bc8-47ea-8b5b-9bcb40183e45
+ spec:
+ forProvider:
+ instance: platform-ref-gcp-db-p9wrj-tvvtg
+ project: example
+ providerConfigRef:
+ name: default
+ # Any desired connection details for the new db-user composed resource.
+ # Desired connection details can be FromValue, FromFieldPath, or
+ # FromConnectionSecretKey, just like their P&T Composition equivalents.
+ connectionDetails:
+ - name: password
+ type: FromValue
+ value: very-secret
+ # Any desired readiness checks for the new db-user composed resource.
+ # Desired readiness checks can be NonEmpty, MatchString, MatchInteger, or
+ # None, just like their P&T Composition equivalents.
+ readinessChecks:
+ - type: None
+# An optional array of results.
+results:
+- severity: Normal
+ message: "Successfully composed GCP SQL user"
+```
+{{< /expand >}}
+
+### An example Function
+
+You can write a Composition Function using any programming language that can be
+containerized, or existing tools like Helm or Kustomize.
+
+Here's a Python Composition Function that doesn't create any new desired
+resources, but instead annotates any existing desired resources with a quote.
+Because this function accesses the internet it needs to be run with the `Runner`
+network policy.
+
+```python
+import sys
+
+import requests
+import yaml
+
+ANNOTATION_KEY_AUTHOR = "quotable.io/author"
+ANNOTATION_KEY_QUOTE = "quotable.io/quote"
+
+
+def get_quote() -> tuple[str, str]:
+ """Get a quote from quotable.io"""
+ rsp = requests.get("https://api.quotable.io/random")
+ rsp.raise_for_status()
+ j = rsp.json()
+ return (j["author"], j["content"])
+
+
+def read_Functionio() -> dict:
+ """Read the FunctionIO from stdin."""
+ return yaml.load(sys.stdin.read(), yaml.Loader)
+
+
+def write_Functionio(Functionio: dict):
+ """Write the FunctionIO to stdout and exit."""
+ sys.stdout.write(yaml.dump(Functionio))
+ sys.exit(0)
+
+
+def result_warning(Functionio: dict, message: str):
+ """Add a warning result to the supplied FunctionIO."""
+ if "results" not in Functionio:
+ Functionio["results"] = []
+ Functionio["results"].append({"severity": "Warning", "message": message})
+
+
+def main():
+ """Annotate all desired composed resources with a quote from quotable.io"""
+ try:
+ Functionio = read_Functionio()
+ except yaml.parser.ParserError as err:
+ sys.stdout.write("cannot parse FunctionIO: {}\n".format(err))
+ sys.exit(1)
+
+ # Return early if there are no desired resources to annotate.
+ if "desired" not in Functionio or "resources" not in Functionio["desired"]:
+ write_Functionio(Functionio)
+
+ # If we can't get our quote, add a warning and return early.
+ try:
+ quote, author = get_quote()
+ except requests.exceptions.RequestException as err:
+ result_warning(Functionio, "Cannot get quote: {}".format(err))
+ write_Functionio(Functionio)
+
+ # Annotate all desired resources with our quote.
+ for r in Functionio["desired"]["resources"]:
+ if "resource" not in r:
+ # This shouldn't happen - add a warning and continue.
+ result_warning(
+ Functionio,
+ "Desired resource {name} missing resource body".format(
+ name=r.get("name", "unknown")
+ ),
+ )
+ continue
+
+ if "metadata" not in r["resource"]:
+ r["resource"]["metadata"] = {}
+
+ if "annotations" not in r["resource"]["metadata"]:
+ r["resource"]["metadata"]["annotations"] = {}
+
+ if ANNOTATION_KEY_QUOTE in r["resource"]["metadata"]["annotations"]:
+ continue
+
+ r["resource"]["metadata"]["annotations"][ANNOTATION_KEY_AUTHOR] = author
+ r["resource"]["metadata"]["annotations"][ANNOTATION_KEY_QUOTE] = quote
+
+ write_Functionio(Functionio)
+
+
+if __name__ == "__main__":
+ main()
+```
+
+Building this function requires its `requirements.txt` and a `Dockerfile`:
+
+{{< expand "The Function's requirements" >}}
+```python
+certifi==2022.12.7
+charset-normalizer==3.0.1
+click==8.1.3
+idna==3.4
+pathspec==0.10.3
+platformdirs==2.6.2
+PyYAML==6.0
+requests==2.28.2
+tomli==2.0.1
+urllib3==1.26.14
+```
+{{< /expand >}}
+
+{{< expand "The Function's Dockerfile" >}}
+```Dockerfile
+FROM debian:11-slim AS build
+RUN apt-get update && \
+ apt-get install --no-install-suggests --no-install-recommends --yes python3-venv && \
+ python3 -m venv /venv && \
+ /venv/bin/pip install --upgrade pip setuptools wheel
+
+FROM build AS build-venv
+COPY requirements.txt /requirements.txt
+RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt
+
+FROM gcr.io/distroless/python3-debian11
+COPY --from=build-venv /venv /venv
+COPY . /app
+WORKDIR /app
+ENTRYPOINT ["/venv/bin/python3", "main.py"]
+```
+{{< /expand >}}
+
+Create and push the Function just like you would any Docker image.
+
+Build the function.
+
+```shell {copy-lines="1"}
+docker build .
+Sending build context to Docker daemon 38.99MB
+Step 1/10 : FROM debian:11-slim AS build
+ ---> 4810399f6c13
+Step 2/10 : RUN apt-get update && apt-get install --no-install-suggests --no-install-recommends --yes python3-venv gcc && python3 -m venv /venv && /venv/bin/pip install --upgrade pip setuptools wheel
+ ---> Using cache
+ ---> 9b34960c88d7
+Step 3/10 : FROM build AS build-venv
+ ---> 9b34960c88d7
+Step 4/10 : COPY requirements.txt /requirements.txt
+ ---> Using cache
+ ---> fae19dad52af
+Step 5/10 : RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt
+ ---> Using cache
+ ---> f4b811c75812
+Step 6/10 : FROM gcr.io/distroless/python3-debian11
+ ---> 2a0e74a2b005
+Step 7/10 : COPY --from=build-venv /venv /venv
+ ---> Using cache
+ ---> cf727d3f20d3
+Step 8/10 : COPY . /app
+ ---> a044aef45e32
+Step 9/10 : WORKDIR /app
+ ---> Running in d08a6144815b
+Removing intermediate container d08a6144815b
+ ---> 7250f5aa653e
+Step 10/10 : ENTRYPOINT ["/venv/bin/python3", "main.py"]
+ ---> Running in 3f4d9dc55bad
+Removing intermediate container 3f4d9dc55bad
+ ---> bfd2f920c591
+Successfully built bfd2f920c591
+```
+
+Tag the function.
+```shell
+docker tag bfd2f920c591 example-org/xfn-quotable-simple:v0.1.0
+```
+
+Push the function.
+
+```shell {copy-lines="1"}
+docker push xpkg.upbound.io/example-org/xfn-quotable-simple:v0.1.0
+The push refers to repository [xpkg.upbound.io/example-org/xfn-quotable-simple]
+cf6d94b88843: Pushed
+77646fd315d2: Mounted from example-org/xfn-quotable
+50630ee42b6e: Mounted from example-org/xfn-quotable
+7e2cf97ed8c4: Mounted from example-org/xfn-quotable
+96e320b34b54: Mounted from example-org/xfn-quotable
+fba4381f2bb7: Mounted from example-org/xfn-quotable
+v0.1.0: digest: sha256:d8a6404e5fe38936aa8dadd861fea35ede0aded6168d501052f91cdabab0135e size: 1584
+```
+
+You can now use this Function in your Composition. The following example will
+create an `RDSInstance` using P&T Composition, then run the Function to annotate
+it with a quote.
+
+```yaml
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example
+spec:
+ compositeTypeRef:
+ apiVersion: database.example.org/v1alpha1
+ kind: XPostgreSQLInstance
+ resources:
+ - name: rds-instance
+ base:
+ apiVersion: rds.aws.upbound.io/v1beta1
+ kind: Instance
+ spec:
+ forProvider:
+ dbName: example
+ instanceClass: db.t3.micro
+ region: us-west-2
+ skipFinalSnapshot: true
+ username: exampleuser
+ engine: postgres
+ engineVersion: "12"
+ patches:
+ - fromFieldPath: spec.parameters.storageGB
+ toFieldPath: spec.forProvider.allocatedStorage
+ connectionDetails:
+ - type: FromFieldPath
+ name: username
+ fromFieldPath: spec.forProvider.username
+ - type: FromConnectionSecretKey
+ name: password
+ fromConnectionSecretKey: attribute.password
+ functions:
+ - name: quotable
+ type: Container
+ container:
+ image: xpkg.upbound.io/example-org/xfn-quotable-simple:v0.1.0
+ network:
+ policy: Runner
+```
+
+### Tips for new functions
+
+Here are some things to keep in mind when building a Composition Function:
+
+* Your Function may be running as part of a pipeline. This means your Function
+ _must_ pass through any desired state that it's unconcerned with. If your
+ Function is passed a desired composed resource and doesn't return that
+ composed resource in its output, it will be deleted. Crossplane considers the
+ desired state of the XR and any composed resources to be whatever `FunctionIO`
+ is returned by the last Function in the pipeline.
+* Crossplane won't set a `metadata.name` for your desired resources resources.
+ It's a good practice to match P&T Composition's behavior by setting
+ `metadata.generateName: "name-of-the-xr-"` for any new desired resources.
+* Don't add new entries to the desired resources array every time your function
+ is invoked. Remember to check whether your desired resource is already in the
+ `observed` and/or `desired` objects. You may need to update it rather than
+ create it.
+* Don't bypass providers. Composition Functions are designed to tell Crossplane
+ how to orchestrate managed resources - not to directly orchestrate external
+ systems.
+* Include your function name and version in any results you return to aid in
+ debugging.
+* Write tests for your function. Pass it a `FunctionIO` on stdin in and ensure
+ it returns the expected `FunctionIO` on stdout.
+* Keep your Functions fast and lightweight. Remember that Crossplane runs them
+ approximately once every 30-60 seconds.
+
+## The xfn runner
+
+Composition Function runners are designed to be pluggable. Each time Crossplane
+needs to invoke a Composition Function it makes a gRPC call to a configurable
+endpoint. The default, reference Composition Function runner is named `xfn`.
+
+{{< hint "note" >}}
+The default runner endpoint is `unix-abstract:crossplane/fn/default.sock`. It's
+possible to run Functions using a different endpoint, for example:
+
+```yaml
+ functions:
+ - name: my-cool-Function
+ type: Container
+ container:
+ image: xkpg.io/my-cool-Function:0.1.0
+ runner:
+ endpoint: unix-abstract:/your/custom/runner.sock
+```
+
+Currently Crossplane uses unauthenticated, unencrypted gRPC requests to run
+Functions, so requests shouldn't be sent over the network. Encryption and
+authentication will be added in a future release.
+{{< /hint >}}
+
+`xfn` runs as a sidecar container within the Crossplane pod. It runs each
+Composition Function as a nested [rootless container][rootless-containers].
+
+{{< img src="media/composition-functions-xfn-runner.png" alt="Crossplane running Functions using xfn via gRPC" size="tiny" >}}
+
+The Crossplane Helm chart deploys `xfn` with:
+
+* The [`Unconfined` seccomp profile][kubernetes-seccomp].
+* The `CAP_SETUID` and `CAP_SETGID` capabilities.
+
+The `Unconfined` seccomp profile allows Crossplane to make required syscalls
+such as `unshare` and `mount` that are not allowed by most `RuntimeDefault`
+profiles. It's possible to run `xfn` with nearly the same restrictions as most
+`RuntimeDefault` profiles by authoring a custom `Localhost` profile. Refer to
+the [seccomp documentation][kubernetes-seccomp] for information on how to do so.
+
+Granting `CAP_SETUID` and `CAP_SETGID` allows `xfn` to create Function
+containers that support up to 65,536 UIDs and GIDs. If `xfn` is run without
+these capabilities it will be restricted to creating Function containers that
+support only UID and GID 0.
+
+Regardless of capabilities `xfn` always runs each Composition Function as an
+unprivileged user. That user will appear to be root inside the Composition
+Function container thanks to [`user_namespaces(7)`].
+
+[rootless-containers]: https://rootlesscontaine.rs
+[kubernetes-seccomp]: https://kubernetes.io/docs/tutorials/security/seccomp/
+[`user_namespaces(7)`]: https://man7.org/linux/man-pages/man7/user_namespaces.7.html
diff --git a/content/v1.13/concepts/compositions.md b/content/v1.13/concepts/compositions.md
new file mode 100644
index 00000000..ac92acca
--- /dev/null
+++ b/content/v1.13/concepts/compositions.md
@@ -0,0 +1,1226 @@
+---
+title: Compositions
+weight: 30
+aliases:
+ - composition
+description: "Compositions are a template for creating Crossplane resources"
+---
+
+Compositions are a template for creating multiple managed resources as a single
+object.
+
+A Composition _composes_ individual managed resources together into a larger,
+reusable, solution.
+
+An example Composition may combine a virtual machine, storage resources and
+networking policies. A Composition template links all these individual
+resources together.
+
+{{}}
+Crossplane has four core components that users commonly mix up:
+
+* Compositions - This page. A template to define how to create resources.
+* [Composite Resource Definition]({{[}})
+ (`XRD`) - A custom API specification.
+* [Composite Resource]({{][}}) (`XR`) - Created by
+ using the custom API defined in a Composite Resource Definition. XRs use the
+ Composition template to create new managed resources.
+* [Claims]({{][}}) (`XRC`) - Like a Composite Resource, but
+ with namespace scoping.
+{{] }}
+
+## Creating Compositions
+
+Creating Compositions consists of:
+* [Resource templates](#resource-templates) defining the resources to create.
+* [Enabling Composite Resources](#enabling-composite-resources) to use this
+ Composition template.
+
+
+Optionally, Compositions also support:
+* [Modifying and patching](#changing-resource-fields) resource settings.
+* [Storing connection details](#storing-connection-details) and secrets
+ generated by the managed resources.
+* Using [Composition functions](#composition-functions) to allow custom
+ programs to run alongside the Composition.
+* Creating a
+ [custom check of when a resource is ready](#resource-readiness-checks)
+ to use.
+
+
+### Resource templates
+The
+{{}}resources{{ }} field of a
+Composition's
+{{}}spec{{ }}
+defines the set of things that a Composite Resource creates.
+
+{{}}
+Read more about Composite Resources in the
+[Composite Resources page]({{[}}).
+{{< /hint >}}
+
+
+For example, a Composition can define a template to create a virtual machine
+and an associated storage bucket at the same time.
+
+The {{]}}resources{{ }} field lists the
+individual resources with a
+{{}}name{{ }}.
+This name identifies the
+resource inside the Composition and isn't related to the external name used with
+the Provider.
+
+#### Template a managed resource
+The contents of the
+{{}}base{{ }} are identical to
+creating a standalone [managed resource]({{[}}).
+
+This example uses
+[Upbound's Provider AWS](https://marketplace.upbound.io/providers/upbound/provider-aws/v0.35.0)
+to define a
+S3 storage {{]}}Bucket{{ }} and
+EC2 compute {{}}Instance{{ }}.
+
+After defining the
+{{}}apiVersion{{ }} and
+{{}}kind{{ }}, define the
+{{}}spec.forProvider{{ }} fields
+defining the settings of the resource.
+
+```yaml {copy-lines="none",label="resources"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - name: StorageBucket
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: "us-east-2"
+ - name: VM
+ base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: Instance
+ spec:
+ forProvider:
+ ami: ami-0d9858aa3c6322f73
+ instanceType: t2.micro
+ region: "us-east-2"
+```
+
+When a [Composite Resource]({{[}}) uses this
+Composition template, the Composite Resource creates two new managed resources
+with all the provided
+{{]}}spec.forProvider{{ }} settings.
+
+The {{}}spec{{ }}
+supports any settings used in a managed resource including
+applying `annotations` and `labels` or using a specific
+`providerConfigRef`.
+
+{{}}
+Compositions allow applying a `metadata.name` to a resource's
+{{}}spec{{ }} but ignores it. The
+`metadata.name` field doesn't influence the name
+of the managed resource in Crossplane or the external resource inside the
+Provider.
+
+Use the `crossplane.io/external-name` annotation on the resource to influence
+the external resource name.
+{{< /hint >}}
+
+#### Template a ProviderConfig
+
+Compositions can define a ProviderConfig like it defines managed resources.
+Generating a ProviderConfig may be useful in providing unique credentials to
+each deployment.
+
+
+```yaml {copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - name: my-aws-provider-config
+ base:
+ apiVersion: aws.upbound.io/v1beta1
+ kind: ProviderConfig
+ spec:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: aws-secret
+ key: creds
+```
+
+
+#### Template another Composite Resource
+
+Compositions can use other Composite Resources to define more complicated
+templates.
+
+A common use case is a Composition that uses other
+Compositions. For example, creating a Composition to create a standard set of
+networking resources that other Compositions reference.
+
+{{< hint "note" >}}
+Both Compositions must have corresponding XRDs.
+{{< /hint >}}
+
+This example networking Composition defines the set of resources required to
+create a new AWS virtual network. This includes a
+{{}}VPC{{ }},
+{{}}InternetGateway{{ }} and
+{{}}Subnet{{ }}.
+
+```yaml {copy-lines="none",label="xnetwork"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - name: vpc-resource
+ base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: VPC
+ # Removed for Brevity
+ - name: gateway-resource
+ base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: InternetGateway
+ # Removed for Brevity
+ - name: subnet-resource
+ base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: Subnet
+ # Removed for Brevity
+ compositeTypeRef:
+ apiVersion: aws.platformref.upbound.io/v1alpha1
+ kind: XNetwork
+```
+
+The {{}}compositeTypeRef{{ }} gives
+this Composition an
+{{}}apiVersion{{ }} and
+{{}}kind{{ }} to reference in another
+Composition.
+
+{{}}
+The [Enabling a Composite Resource](#enabling-composite-resources) section
+describes the
+{{}}compositeTypeRef{{ }} field.
+{{< /hint >}}
+
+A second Composition, defining other resources, in this example, an AWS Elastic
+Kubernetes Cluster, can reference the previous
+{{}}XNetwork{{ }}
+
+```yaml {copy-lines="none",label="xcluster"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - name: nested-network-composition
+ base:
+ apiVersion: aws.platformref.upbound.io/v1alpha1
+ kind: XNetwork
+ # Removed for brevity
+ - name: eks-cluster-resource
+ base:
+ apiVersion: eks.aws.upbound.io/v1beta1
+ kind: Cluster
+ # Removed for brevity
+```
+
+When a Composite Resource creates all the managed resources from this
+Composition, the resources defined by the
+{{}}XNetwork{{ }} get created along with
+the EKS {{}}cluster{{ }}.
+
+{{}}
+This abbreviated example is from the Upbound [AWS Reference
+Platform](https://github.com/upbound/platform-ref-aws).
+
+View the complete Compositions in the reference platform's
+[package directory](https://github.com/upbound/platform-ref-aws/blob/main/package/cluster/composition.yaml).
+{{ }}
+
+#### Cross-resource references
+
+Inside a Composition some resources use identifiers or names of other resources.
+For example, creating a new `network` and applying the network identifier to a
+virtual machine.
+
+Resources inside a Composition can cross-reference other resources by matching
+a label or a _controller reference_.
+
+{{}}
+Providers allow matching of labels and controller references on a
+per-resource basis. Check the documentation for the specific Provider resource
+to see what's supported.
+
+Matching labels and controllers isn't supported across different Providers.
+{{< /hint >}}
+
+##### Match resource labels
+
+To match a resource label, first apply a
+{{}}label{{ }} to the resource to
+match and use
+{{}}matchLabels{{ }}
+in the second resource.
+
+This example creates a AWS
+{{}}Role{{ }} and applies a
+{{}}label{{ }}. The second resource
+is a {{}}RolePolicyAttachment{{ }},
+which requires attaching to an existing `Role`.
+
+Using the resource's
+{{}}roleSelector.matchLabels{{ }}
+ensures this
+{{}}RolePolicyAttachment{{ }}
+references the matching
+{{}}Role{{ }}, even if the unique role
+identifier isn't known.
+
+```yaml {label="matchlabel",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - base:
+ apiVersion: iam.aws.upbound.io/v1beta1
+ kind: Role
+ name: iamRole
+ metadata:
+ labels:
+ role: controlplane
+ - base:
+ apiVersion: iam.aws.upbound.io/v1beta1
+ kind: RolePolicyAttachment
+ name: iamPolicy
+ spec:
+ forProvider:
+ roleSelector:
+ matchLabels:
+ role: controlplane
+ # Removed for brevity
+```
+
+##### Match a controller reference
+
+Matching a controller reference ensures that the matching resource is
+in the same composite resource.
+
+Matching only a controller reference simplifies the matching process without
+requiring labels or more information.
+
+For example, creating an AWS
+{{}}InternetGateway{{ }} requires a
+{{}}VPC{{ }}.
+
+The {{}}InternetGateway{{ }} could
+match a label, but every VPC created by this Composition share the same label.
+
+Using {{}}matchControllerRef{{ }}
+matches only the VPC created in the same composite resource that created the
+{{}}InternetGateway{{ }}.
+
+```yaml {label="controller1",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: VPC
+ name: my-vpc
+ spec:
+ forProvider:
+ # Removed for brevity
+ - base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: InternetGateway
+ name: my-gateway
+ spec:
+ forProvider:
+ vpcIdSelector:
+ matchControllerRef: true
+# Removed for brevity
+```
+
+
+Resources can match both labels and a controller reference to match a specific
+resource in the larger composite resource.
+
+For example, this Composition creates two
+{{}}VPC{{ }}
+resources, but the
+{{}}InternetGateway{{ }}
+must match only one.
+
+Applying a {{}}label{{ }} to the
+second {{}}VPC{{ }} allows the
+{{}}InternetGateway{{ }} to match
+the label
+{{}}type: internet{{ }} and only
+match objects in the same composite resource with
+{{}}matchControllerRef{{ }}.
+
+```yaml {label="controller2",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: VPC
+ name: my-first-vpc
+ metadata:
+ labels:
+ type: backend
+ spec:
+ forProvider:
+ # Removed for brevity
+ - base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: VPC
+ name: my-second-vpc
+ metadata:
+ labels:
+ type: internet
+ spec:
+ forProvider:
+ # Removed for brevity
+ - base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: InternetGateway
+ name: my-gateway
+ spec:
+ forProvider:
+ vpcIdSelector:
+ matchControllerRef: true
+ matchLabels:
+ type: internet
+# Removed for brevity
+```
+### Enabling Composite Resources
+
+A Composition is only a template defining how to create managed
+resources. A Composition limits which Composite Resources can use this
+template.
+
+A Composition's {{}}compositeTypeRef{{ }}
+defines which Composite Resource type can use this Composition.
+
+{{}}
+Read more about Composite Resources in the
+[Composite Resources page]({{[}}).
+{{< /hint >}}
+
+Inside a Composition's
+{{]}}spec{{ }}
+define the Composite Resource
+{{}}apiVersion{{ }} and
+{{}}kind{{ }}
+that the Composition allows to use this template.
+
+```yaml {label="typeref",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: dynamodb-with-bucket
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: database
+ # Removed for brevity
+```
+
+### Changing resource fields
+
+Most Compositions require customizing the fields of the resources. This can
+include applying unique passwords, modifying where to deploy resources,
+or applying labels or annotations.
+
+The primary method to change resources is using a resource [patch and
+transform]({{[}}). Patch and transforms allow
+matching specific input fields, modifying them and applying them to the managed
+resource.
+
+{{]}}
+The details of creating patch and transforms and their options are in the
+[Patch and Transform page]({{[}}).
+
+This section describes applying patches and transforms to Compositions.
+{{< /hint >}}
+
+Apply patches to individual `resources` with the
+{{]}}patches{{ }}
+field.
+
+For example, taking the
+{{}}location{{ }} provided in a Claim
+and applying it to the
+{{}}region{{ }} value in the managed
+resource.
+
+```yaml {copy-lines="none",label="patchClaim"}
+apiVersion: example.org/v1alpha1
+kind: ExampleClaim
+metadata:
+ name: my-example-claim
+spec:
+ location: "eu-north-1"
+```
+
+The Composition patch uses the
+{{}}fromFieldPath{{ }} to match the
+{{}}location{{ }}
+field in the Claim and the
+{{}}toFieldPath{{ }} to define which field
+to change inside the Composition.
+
+```yaml {copy-lines="none",label="patch"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ - name: s3Bucket
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: "us-east-2"
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: "spec.location"
+ toFieldPath: "spec.forProvider.region"
+```
+
+#### Patch sets
+
+Some Compositions have resources which need identical patches applied. Instead
+of repeating the same `patches` field, resources can reference a single
+`patchSet`.
+
+Define a {{}}patchSet{{ }} with a
+{{}}name{{ }}
+and
+{{}}patch{{ }}
+operations.
+
+Then apply the
+{{}}patchSet{{ }}
+to each resource with
+{{}}type: patchSet{{< /hover >}}, referencing
+the {{}}name{{< /hover >}} in the
+{{}}patchSetName{{< /hover >}} field.
+
+```yaml {copy-lines="none",label="patchset"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ patchSets:
+ - name: reusable-patch
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: "location"
+ toFieldPath: "spec.forProvider.region"
+ resources:
+ - name: first-resource
+ base:
+ # Removed for Brevity
+ patches:
+ - type: PatchSet
+ patchSetName: reusable-patch
+ - name: second-resource
+ base:
+ # Removed for Brevity
+ patches:
+ - type: PatchSet
+ patchSetName: reusable-patch
+```
+
+#### Patch with EnvironmentConfigs
+
+Crossplane uses EnvironmentConfigs as an in-memory data store. Compositions can
+read and write from this data store as part of the patch process.
+
+{{}}
+EnvironmentConfigs are an alpha feature. Alpha features aren't enabled by
+default.
+{{< /hint >}}
+
+ EnvironmentConfigs can predefine data that Compositions can use
+ or a Composite Resource can write data to the EnvironmentConfig for other
+ resources to read.
+
+
+{{< hint "note" >}}
+
+Read the [EnvironmentConfigs]({{[}}) page for
+more information on using EnvironmentConfigs.
+{{< /hint >}}
+
+To apply a patch using EnvironmentConfigs, first define which EnvironmentConfig
+to use with
+{{]}}environment.environmentConfigs{{ }}.
+
+
+
+
+Use either a
+[reference]({{[}})
+or a [selector]({{][}}) to
+identify the EnvironmentConfig to use.
+
+
+```yaml {label="envselect",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ environment:
+ environmentConfigs:
+ - ref:
+ name: example-environment
+ resources:
+ # Removed for Brevity
+```
+
+Inside the {{]}}patches{{ }} of the
+resource, use
+{{}}ToEnvironmentFieldPath{{ }} to copy
+data from the resource to the EnvironmentConfig.
+Use {{}}FromEnvironmentFieldPath{{ }}
+to copy data to the resource from the EnvironmentConfig.
+
+```yaml {label="envpatch",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ environment:
+ # Removed for Brevity
+ resources:
+ # Removed for Brevity
+ - name: vpc
+ base:
+ apiVersion: ec2.aws.upbound.io/v1beta1
+ kind: VPC
+ spec:
+ forProvider:
+ cidrBlock: 172.16.0.0/16
+ patches:
+ - type: ToEnvironmentFieldPath
+ fromFieldPath: status.atProvider.id
+ toFieldPath: vpcId
+ - type: FromEnvironmentFieldPath
+ fromFieldPath: tags
+ toFieldPath: spec.forProvider.tags
+```
+
+The [EnvironmentConfigs]({{[}}) page has
+more information on EnvironmentConfigs options and usage.
+
+### Composition functions
+
+Composition functions (`XFNs`) are containers executing any code you define.
+Composition functions can read and write to any resource in the Composition
+they're attached to. This allows composition functions to perform complex
+operations to patch fields, determine if a resource is ready for use or notify
+an external system about the details of resource.
+
+{{]}}
+Composition functions are an alpha feature. Alpha features aren't enabled by
+default.
+{{< /hint >}}
+
+To attach a composition function to a Composition define a
+{{}}function{{ }} inside the Composition
+{{}}spec{{ }}.
+
+Provide a {{}}name{{ }} for the function.
+The {{}}type{{ }} is always `Container`.
+The {{}}container.image{{ }} is the
+location of the composition function container image.
+
+```yaml {label="xfn",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ functions:
+ - name: rds-instance-password
+ type: Container
+ container:
+ image: xpkg.upbound.io/provider-aws-xfns/random-rds-password:v0.1.0
+```
+
+Read the [composition functions]({{[}}) page for
+details on building and using composition functions.
+
+### Storing connection details
+
+Some managed resources generate unique details like usernames, passwords,
+IP addresses, ports or other connection details.
+
+When resources inside a Composition create connection details Crossplane creates
+a Kubernetes secret object for each managed resource generating connection
+details.
+
+{{]}}
+This section discusses creating Kubernetes secrets.
+Crossplane also supports using external secret stores like [HashiCorp Vault](https://www.vaultproject.io/).
+
+Read the [external secrets store guide]({{[}}) for more information on using Crossplane
+with an external secret store.
+{{] }}
+
+#### Composite resource combined secret
+Crossplane can combine all the secrets generated by the resources inside a
+Composition into a single Kubernetes secret and optionally copy the
+secret object for [Claims]({{[}}).
+
+Set the value of
+{{]}}writeConnectionSecretsToNamespace{{ }}
+to the namespace where Crossplane should store the combined secret object.
+
+```yaml {copy-lines="none",label="writeConn"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ writeConnectionSecretsToNamespace: my-namespace
+ resources:
+ # Removed for brevity
+```
+
+#### Composed resource secrets
+Inside the
+{{}}spec{{ }} of
+each resource producing connection details, define the
+{{}}writeConnectionSecretToRef{{ }}, with
+a
+{{}}namespace{{ }} and
+{{}}name{{ }} of the secret object for
+the resource.
+
+If a
+{{}}writeConnectionSecretToRef{{ }}
+isn't defined, Crossplane doesn't write any keys to the secret.
+
+
+```yaml {label="writeConnRes"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ writeConnectionSecretsToNamespace: other-namespace
+ resources:
+ - name: key
+ base:
+ apiVersion: iam.aws.upbound.io/v1beta1
+ kind: AccessKey
+ spec:
+ forProvider:
+ # Removed for brevity
+ writeConnectionSecretToRef:
+ namespace: docs
+ name: key1
+```
+
+Crossplane saves a secret with the
+{{}}name{{ }}
+in the
+{{}}namespace{{ }} provided.
+
+```shell {label="viewComposedSec"}
+kubectl get secrets -n docs
+NAME TYPE DATA AGE
+key1 connection.crossplane.io/v1alpha1 4 4m30s
+```
+
+{{}}
+
+Crossplane recommends using a [Patch]({{[}}) to
+create a unique name for each secret.
+
+For example, a
+{{]}}patch{{ }}
+to add the unique identifier of the resource as the key
+name.
+
+```yaml {label="tipPatch",copy-lines="14-20"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ # Removed for brevity
+ resources:
+ - name: key
+ base:
+ apiVersion: iam.aws.upbound.io/v1beta1
+ kind: AccessKey
+ spec:
+ # Removed for brevity
+ writeConnectionSecretToRef:
+ namespace: docs
+ name: key1
+ patches:
+ - fromFieldPath: "metadata.uid"
+ toFieldPath: "spec.writeConnectionSecretToRef.name"
+ transforms:
+ - type: string
+ string:
+ fmt: "%s-secret"
+```
+{{< /hint >}}
+
+#### Define secret keys
+
+
+A Composition must define the specific secret keys a resource creates with
+the
+{{}}connectionDetails{{ }} object.
+
+{{}}
+| Secret Type | Description |
+| --- | --- |
+| {{}}fromConnectionSecretKey{{ }} | Create a secret key matching the key of a secret generated by the resource. |
+| {{}}fromFieldPath{{ }} | Create a secret key matching a field path of the resource. |
+| {{}}value{{ }} | Create a secret key with a predefined value. |
+{{< /table >}}
+
+{{}}
+The {{}}value{{ }} type must use a
+string value.
+
+The {{}}value{{ }} isn't added to the
+individual resource secret object. The
+{{}}value{{ }} only appears in the
+combined composite resource secret.
+{{< /hint >}}
+
+```yaml {label="conDeet",copy-lines="none"}
+kind: Composition
+spec:
+ writeConnectionSecretsToNamespace: other-namespace
+ resources:
+ - name: key
+ base:
+ # Removed for brevity
+ spec:
+ forProvider:
+ # Removed for brevity
+ writeConnectionSecretToRef:
+ namespace: docs
+ name: key1
+ connectionDetails:
+ - name: myUsername
+ fromConnectionSecretKey: username
+ - name: myFieldSecret
+ fromFieldPath: spec.forProvider.user
+ - name: myStaticSecret
+ value: "docs.crossplane.io"
+```
+
+The
+{{}}connectionDetails{{ }}
+in a resource can reference a secret from a resource with
+{{}}fromConnectionSecretKey{{ }},
+from another field in the resource with
+{{}}fromFieldPath{{ }}
+or a statically defined value with
+{{}}value{{ }}.
+
+Crossplane sets the secret key to the
+{{}}name{{ }} value.
+
+Describe the secret to view the secret keys inside the secret object.
+
+{{}}
+If more than one resource generates secrets with the same secret key name,
+Crossplane only saves one value.
+
+Use a custom {{}}name{{ }} to create
+unique secret keys.
+{{< /hint >}}
+
+{{}}
+Crossplane only adds connection details listed in the
+{{}}connectionDetails{{ }}
+to the combined secret object.
+Any connection secrets in a managed resource, not defined in the
+{{}}connectionDetails{{ }}
+aren't added to the combined secret object.
+{{< /hint >}}
+
+
+```shell {copy-lines="1"}
+kubectl describe secret
+Name: my-access-key-secret
+Namespace: default
+Labels:
+Annotations:
+
+Type: connection.crossplane.io/v1alpha1
+
+Data
+====
+myUsername: 20 bytes
+myFieldSecret: 24 bytes
+myStaticSecret: 18 bytes
+```
+
+{{}}
+The CompositeResourceDefinition can also limit which keys Crossplane stores from
+the composite resources.
+By default an XRD writes all secret keys listed in the composed resources
+`connectionDetails` to the combined secret object.
+
+Read the
+[CompositeResourceDefinition documentation]({{[}})
+for more information on restricting secret keys.
+{{< /hint >}}
+
+For more information on connection secrets read the [Connection Secrets
+knowledge base article]({{][}}).
+
+{{]}}
+You can't change the
+{{}}connectionDetails{{ }}
+of a Composition.
+You must delete and
+recreate the Composition to change the
+{{}}connectionDetails{{ }} .
+{{ }}
+
+
+#### Save connection details to an external secret store
+
+Crossplane
+[External Secret Stores]({{[}})
+write secrets and connection details to external secret stores like HashiCorp
+Vault.
+
+{{]}}
+External Secret Stores are an alpha feature.
+
+They're not recommended for production use. Crossplane disables External Secret
+Stores by default.
+{{< /hint >}}
+
+Use
+{{}}publishConnectionDetailsWithStoreConfigRef{{ }}
+in place of
+`writeConnectionSecretsToNamespace` to define the
+{{}}StoreConfig{{ }}
+to save connection details to.
+
+For example, using a
+{{}}StoreConfig{{ }} with the
+{{}}name{{ }} "vault,"
+use
+{{}}publishConnectionDetailsWithStoreConfigRef.name{{ }}
+matching the {{}}StoreConfig.name{{ }},
+in this example, "vault."
+
+
+```yaml {label="gcp-storeconfig",copy-lines="none"}
+apiVersion: gcp.crossplane.io/v1alpha1
+kind: StoreConfig
+metadata:
+ name: vault
+# Removed for brevity.
+---
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ publishConnectionDetailsWithStoreConfigRef:
+ name: vault
+ resources:
+ # Removed for brevity
+```
+
+For more details read the [External Secret Stores]({{[}})
+integration guide.
+
+### Resource readiness checks
+
+By default Crossplane considers a Composite Resource or Claim as `READY` when
+the status of all created resource are `Type: Ready` and `Status: True`
+
+Some resources, for example, a ProviderConfig, don't have a Kubernetes status
+and are never considered `Ready`.
+
+Custom readiness checks allow Compositions to define what custom conditions
+to meet for a resource to be `Ready`.
+
+{{< hint "tip" >}}
+Use multiple readiness checks if a resource must meet multiple conditions for it
+to be `Ready`.
+{{< /hint >}}
+
+
+Define a custom readiness check with the
+{{]}}readinessChecks{{ }} field on a
+resource.
+
+
+Checks have a
+{{}}type{{ }} defining how to match the
+resource and a {{}}fieldPath{{ }} of
+which field in the resource to compare.
+
+```yaml {label="check",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ - name: my-resource
+ base:
+ # Removed for brevity
+ readinessChecks:
+ - type:
+ fieldPath:
+```
+
+Compositions support matching resource fields by:
+ * [string match](#match-a-string)
+ * [integer match](#match-an-integer)
+ * [non-empty match](#match-that-a-field-exists)
+ * [always ready](#always-consider-a-resource-ready)
+
+#### Match a string
+
+{{}}MatchString{{ }} considers the composed resource to be ready when the value of a
+field within that resource matches a specified string.
+
+{{}}
+
+Crossplane only supports exact string matches. Substrings and regular
+expressions aren't supported in a readiness check.
+
+{{ }}
+
+
+For example, matching the string
+{{}}Online{{ }}
+in the resource's
+{{}}status.atProvider.state{{ }}
+field.
+
+```yaml {label="matchstring",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ - name: my-resource
+ base:
+ # Removed for brevity
+ readinessChecks:
+ - type: MatchString
+ fieldPath: status.atProvider.state
+ matchString: "Online"
+```
+
+#### Match an integer
+
+{{}}MatchInteger{{ }} considers the composed resource to be ready when the value of a
+field within that resource matches a specified integer.
+
+{{}}
+
+Crossplane doesn't support matching `0`.
+
+{{ }}
+
+For example, matching the number
+{{}}4{{ }}
+in the resource's
+{{}}status.atProvider.state{{ }}
+field.
+
+```yaml {label="matchint",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ - name: my-resource
+ base:
+ # Removed for brevity
+ readinessChecks:
+ - type: MatchInteger
+ fieldPath: status.atProvider.state
+ matchInteger: 4
+```
+
+#### Match that a field exists
+{{}}NonEmpty{{ }} considers the
+composed resource to be ready when a field exists with a value.
+
+{{}}
+
+Crossplane considers a value of `0` or an empty string as empty.
+{{ }}
+
+For example, to check that a resource's
+{{}}status.atProvider.state{{ }}
+field isn't empty.
+
+
+```yaml {label="NonEmpty",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ - name: my-resource
+ base:
+ # Removed for brevity
+ readinessChecks:
+ - type: NonEmpty
+ fieldPath: status.atProvider.state
+```
+
+{{}}
+Checking {{}}NonEmpty{{ }} doesn't
+require a `match` field.
+{{< /hint >}}
+
+#### Always consider a resource ready
+{{}}None{{ }} considers the
+composed resource to be ready as soon as it's created. Crossplane doesn't wait
+for any other conditions before declaring the resource ready.
+
+For example, consider
+{{}}my-resource{{ }}
+ready as soon as it's created.
+
+
+```yaml {label="none",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for Brevity
+spec:
+ resources:
+ # Removed for Brevity
+ - name: my-resource
+ base:
+ # Removed for brevity
+ readinessChecks:
+ - type: None
+```
+
+## Verify a Composition
+
+View all available Compositions with `kubectl get composition`.
+
+```shell {copy-lines="1"}
+kubectl get composition
+NAME XR-KIND XR-APIVERSION AGE
+xapps.aws.platformref.upbound.io XApp aws.platformref.upbound.io/v1alpha1 123m
+xclusters.aws.platformref.upbound.io XCluster aws.platformref.upbound.io/v1alpha1 123m
+xeks.aws.platformref.upbound.io XEKS aws.platformref.upbound.io/v1alpha1 123m
+xnetworks.aws.platformref.upbound.io XNetwork aws.platformref.upbound.io/v1alpha1 123m
+xservices.aws.platformref.upbound.io XServices aws.platformref.upbound.io/v1alpha1 123m
+xsqlinstances.aws.platformref.upbound.io XSQLInstance aws.platformref.upbound.io/v1alpha1 123m
+```
+
+The `XR-KIND` lists the Composite Resource `kind` that's allowed to use the
+Composition template.
+The `XR-APIVERSION` lists the Composite Resource API versions allowed to use the
+Composition template.
+
+{{}}
+The output of `kubectl get composition` is different than `kubectl get
+composite`.
+
+`kubectl get composition` lists all available Compositions.
+
+`kubectl get composite` lists all created Composite Resources and their related
+Composition.
+{{< /hint >}}
+
+## Composition validation
+
+When creating a Composition Crossplane automatically validates specific
+parameters in the Composition.
+
+* All resources either use a `name` or don't. Compositions can't use both named
+ and unnamed resources.
+* No duplicate resource names.
+* Patch sets must have names.
+* Patches that require a `fromFieldPath` value provide it.
+* Patches that require a `toFieldPath` value provide it.
+* Patches that require a `combine` field provide it.
+* Readiness checks using `matchString` aren't empty.
+* Readiness checks using `matchInteger` isn't `0`.
+* Readiness checks requiring a `fieldPath` value provide it.
+* If using composition functions, all resources must have names.
+* Composition function container field isn't empty.
+* Composition function `type` is `container`.
+* Composition function names are unique.
+
+### Resource schema validation
+
+Optionally, Crossplane can also validate the schema of the resources defined
+inside a Composition. This verifies that the resource `apiVersion` and `kinds`
+are valid.
+
+
+Enable "schema validation" with the
+`--enable-composition-webhook-schema-validation` flag on the Crossplane pod.
+The [Crossplane Pods]({{[}}) page has
+more information on enabling Crossplane flags.
+
+{{]}}
+
+Schema validation only checks the `apiVersion` and `kind` are valid. Schema
+validation doesn't validate the fields of a specific resource.
+
+{{< /hint >}}
+
+The default validations are still checked with schema validation enabled.
+#### Validation modes
+
+Schema validation supports two modes:
+* `loose` (default) - Sends an warning for each schema error and installs the
+ Composition if the default validations pass.
+* `strict` - Send an error for every schema validation error and rejects the
+ Composition.
+
+Change the validation mode for a Composition with the
+{{}}crossplane.io/composition-validation-mode{{ }}
+annotation.
+
+For example, to enable `strict` mode checking:
+
+```yaml {copy-lines="none",label="mode"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ annotations:
+ crossplane.io/composition-validation-mode: strict
+ # Removed for brevity
+spec:
+ # Removed for brevity
+```
diff --git a/content/v1.13/concepts/environment-configs.md b/content/v1.13/concepts/environment-configs.md
new file mode 100644
index 00000000..74dc3f13
--- /dev/null
+++ b/content/v1.13/concepts/environment-configs.md
@@ -0,0 +1,303 @@
+---
+title: Environment Configurations
+weight: 90
+state: alpha
+alphaVersion: "1.11"
+description: "Environment Configurations or EnvironmentConfigs are an in-memory datastore used in patching Compositions"
+---
+
+A Crossplane EnvironmentConfig is an in-memory data store. Composition
+patches can read from and write to an environment.
+
+Crossplane supports multiple EnvironmentConfigs, each acting as a unique
+data store.
+
+## Enable EnvironmentConfigs
+EnvironmentConfigs are an alpha feature. Alpha features aren't enabled by
+default.
+
+Enable EnvironmentConfig support by
+[changing the Crossplane pod setting]({{[}})
+and enabling
+{{]}}--enable-environment-configs{{ }}
+argument.
+
+```yaml {label="deployment",copy-lines="12"}
+$ kubectl edit deployment crossplane --namespace crossplane-system
+apiVersion: apps/v1
+kind: Deployment
+spec:
+# Removed for brevity
+ template:
+ spec:
+ containers:
+ - args:
+ - core
+ - start
+ - --enable-environment-configs
+```
+
+{{}}
+
+The [Crossplane install guide]({{[}})
+describes enabling feature flags like
+{{]}}--enable-environment-configs{{ }}
+with Helm.
+{{< /hint >}}
+
+
+## Create an EnvironmentConfig
+
+
+An {{}}EnvironmentConfig{{ }} has a single
+object field,
+{{}}data{{ }}.
+
+An EnvironmentConfig supports any data inside the
+{{}}data{{ }} field.
+
+Here an example
+{{}}EnvironmentConfig{{ }}.
+
+```yaml {label="env1"}
+apiVersion: apiextensions.crossplane.io/v1alpha1
+kind: EnvironmentConfig
+metadata:
+ name: example-environment
+data:
+ locations:
+ us: us-east-2
+ eu: eu-north-1
+ key1: value1
+ key2: value2
+ key3:
+ - item1
+ - item2
+```
+
+## Patching with EnvironmentConfigs
+
+To patch data from or to an EnvironmentConfig, reference the EnvironmentConfig
+inside a Composition's
+{{}}environment{{ }} field.
+
+The {{}}environmentConfigs{{ }} field is a
+list of environments this Composition can use.
+
+{{}}
+Read about EnvironmentConfig patch types in the
+[Patch and Transform]({{[}}) documentation.
+{{< /hint >}}
+
+Select an environment by
+{{]}}Reference{{ }} or
+by
+{{}}Selector{{ }}.
+
+A
+{{}}Reference{{ }}
+selects an environment by
+{{}}name{{ }}.
+The
+{{}}Selector{{ }} selects an environment
+based on the
+{{}}Labels{{ }} applied to the environment.
+
+```yaml {label="comp",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ environment:
+ environmentConfigs:
+ - type: Reference
+ ref:
+ name: example-environment
+ - type: Selector
+ selector:
+ matchLabels:
+ # Removed for brevity
+```
+
+If a Composition uses multiple
+{{}}environmentConfigs{{ }}
+Crossplane merges them together in the order they're listed.
+
+{{}}
+If multiple
+{{}}environmentConfigs{{ }}
+use the same key, the Composition uses the value of the last environment listed.
+{{ }}
+
+### Select by name
+
+Select an environment by name with
+{{}}type: Reference{{ }}.
+
+Define the
+{{}}ref{{ }} object and the
+{{}}name{{ }} matching the exact name of
+the environment.
+
+
+For example, select the
+{{}}environmentConfig{{ }}
+named
+{{}}example-environment{{ }}
+
+```yaml {label="byName",copy-lines="all"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ environment:
+ environmentConfigs:
+ - type: Reference
+ ref:
+ name: example-environment
+```
+
+### Select by label
+
+Select an environment by labels with a
+{{}}type: Selector{{ }}.
+
+Define the {{}}selector{{ }} object.
+
+The
+{{}}matchLabels{{ }} object contains a
+list of labels to match on.
+
+Selecting a label requires matching both the label
+{{}}key{{ }}
+and the value of key.
+
+When matching the label's value, provide an exact value with a
+{{}}type: Value{{ }} and provide the value
+to match in the
+{{}}value{{ }} field.
+
+Crossplane can also match a label's value based on an input in the composite
+resource. Use
+{{}}type: FromCompositeFieldPath{{ }}
+and provide the field to match in the
+{{}}valueFromFieldPath{{ }} field.
+
+```yaml {label="byLabel",copy-lines="all"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ environment:
+ environmentConfigs:
+ - type: Selector
+ selector:
+ matchLabels:
+ - key: my-label-key
+ type: Value
+ value: my-label-value
+ - key: my-label-key
+ type: FromCompositeFieldPath
+ valueFromFieldPath: spec.parameters.deploy
+ resources:
+ # Removed for brevity
+```
+
+#### Manage selector results
+
+Selecting environments by labels may return more than one environment.
+The Composition sorts all the results by the name of the environments and
+only uses the first environment in the sorted list.
+
+Set the {{}}mode{{ }} as
+{{}}mode: Multiple{{ }} to return
+all matched environments. Use
+{{}}mode: Single{{ }} to
+return a single environment.
+
+{{}}
+Sorting and the selection
+{{}}mode{{ }}
+only applies to a single
+{{}}type: Selector{{ }}.
+
+This doesn't change how Compositions merge multiple
+{{}}environmentConfigs{{ }}.
+{{< /hint >}}
+
+
+```yaml {label="selectResults"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ environment:
+ environmentConfigs:
+ - type: Selector
+ selector:
+ mode: Multiple
+ matchLabels:
+ - key: my-label-key
+ type: Value
+ value: my-label-value
+ - key: my-label-key
+ type: FromCompositeFieldPath
+ valueFromFieldPath: spec.parameters.deploy
+ - type: Selector
+ selector:
+ mode: Single
+ matchLabels:
+ - key: my-other-label-key
+ type: Value
+ value: my-other-label-value
+ - key: my-other-label-key
+ type: FromCompositeFieldPath
+ valueFromFieldPath: spec.parameters.deploy
+```
+
+When using
+{{}}mode: Multiple{{ }} limit the
+number of returned environments with
+{{}}maxMatch{{ }} and define the
+maximum number of environments returned.
+
+The Composition sorts the returned environments alphabetically by name. Sort the
+environments on a different field with
+{{}}sortByFieldPath{{ }} and define
+the field to sort by.
+
+
+```yaml {label="maxMatch"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ environment:
+ environmentConfigs:
+ - type: Selector
+ selector:
+ mode: Multiple
+ maxMatch: 4
+ sortByFieldPath: metadata.annotations[sort.by/weight]
+ matchLabels:
+ - key: my-label-key
+ type: Value
+ value: my-label-value
+ - key: my-label-key
+ type: FromCompositeFieldPath
+ valueFromFieldPath: spec.parameters.deploy
+```
+
+The environments selected by
+{{}}matchLabels{{ }} are then merged
+into any other environments listed in the
+{{}}environmentConfigs{{ }}.
+
diff --git a/content/v1.13/concepts/managed-resources.md b/content/v1.13/concepts/managed-resources.md
new file mode 100644
index 00000000..ecc4fddb
--- /dev/null
+++ b/content/v1.13/concepts/managed-resources.md
@@ -0,0 +1,760 @@
+---
+title: Managed Resources
+weight: 10
+description: "Managed resources are the Crossplane representation of external provider resources"
+---
+
+A _managed resource_ (`MR`) represents an external service in a Provider. When
+users create a new managed resource, the Provider reacts by creating an external
+resource inside the Provider's environment. Every external service managed by
+Crossplane maps to a managed resource.
+
+{{< hint "note" >}}
+Crossplane calls the object inside Kubernetes a _managed resource_ and the
+external object inside the Provider an _external resource_.
+{{< /hint >}}
+
+Examples of managed resources include:
+* Amazon AWS EC2 [`Instance`](https://marketplace.upbound.io/providers/upbound/provider-aws/latest/resources/ec2.aws.upbound.io/Instance/v1beta1)
+* Google Cloud GKE [`Cluster`](https://marketplace.upbound.io/providers/upbound/provider-gcp/latest/resources/container.gcp.upbound.io/Cluster/v1beta1)
+* Microsoft Azure PostgreSQL [`Database`](https://marketplace.upbound.io/providers/upbound/provider-azure/latest/resources/dbforpostgresql.azure.upbound.io/Database/v1beta1)
+
+{{< hint "tip" >}}
+
+You can create individual managed resources, but Crossplane recommends using
+[Compositions]({{[}}) and Claims to create
+managed resources.
+{{< /hint >}}
+
+## Managed resource fields
+
+The Provider defines the group, kind and version of a managed resource. The
+Provider also define the available settings of a managed resource.
+
+### Group, kind and version
+Each managed resource is a unique API endpoint with their own
+group, kind and version.
+
+For example the [Upbound AWS
+Provider](https://marketplace.upbound.io/providers/upbound/provider-aws/latest/)
+defines the {{]}}Instance{{ }} kind from the
+group {{}}ec2.aws.upbound.io{{ }}
+
+```yaml {label="gkv",copy-lines="none"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Instance
+```
+
+
+### deletionPolicy
+
+
+A managed resource's `deletionPolicy` tells the Provider what to do after
+deleting the managed resource. If the `deletionPolicy` is `delete` the Provider
+deletes the external resource as well. If the `deletionPolicy` is `orphan` the
+Provider deletes the managed resource but doesn't delete the external resource.
+
+#### Options
+* `deletionPolicy: Delete` - **Default** - Delete the external resource when deleting the managed resource.
+* `deletionPolicy: Orphan` - Leave the external resource when deleting the managed resource.
+
+
+### forProvider
+
+
+The {{}}spec.forProvider{{ }} of a
+managed resource maps to the parameters of the external resource.
+
+For example, when creating an AWS EC2 instance, the Provider supports defining
+the AWS {{}}region{{ }} and the VM
+size, called the
+{{}}instanceType{{ }}.
+
+{{< hint "note" >}}
+The Provider defines the settings and their valid values. Providers also define
+required and optional values in the `forProvider` definition.
+
+Refer to the documentation of your specific Provider for details.
+{{< /hint >}}
+
+
+```yaml {label="forProvider",copy-lines="none"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Instance
+# Removed for brevity
+spec:
+ forProvider:
+ region: us-west-1
+ instanceType: t2.micro
+```
+
+{{< hint "important">}}
+Crossplane considers the `forProvider` field of a managed resource
+the "source of truth" for external resources. Crossplane overrides any changes
+made to an external resource outside of Crossplane. If a user makes a change
+inside a Provider's web console, Crossplane reverts that change back to what's
+configured in the `forProvider` setting.
+{{< /hint >}}
+
+Providers add any settings not manually set to the `forProvider` field of the
+created managed resource object.
+Use `kubectl describe ` to view the applied values.
+
+#### Referencing other resources
+
+Some fields in a managed resource may depend on values from other managed
+resources. For example a VM may need the name of a virtual network to use.
+
+Managed resources can reference other managed resources by external name, name
+reference or selector.
+
+##### Matching by external name
+
+When matching a resource by name Crossplane looks for the name of the external
+resource in the Provider.
+
+For example, a AWS VPC object named `my-test-vpc` has the external name
+`vpc-01353cfe93950a8ff`.
+
+```shell {copy-lines="1"
+kubectl get vpc
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-test-vpc True True vpc-01353cfe93950a8ff 49m
+```
+
+To match the VPC by name, use the external name. For example, creating a Subnet
+managed resource attached to this VPC.
+
+```yaml {copy-lines="none"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Subnet
+spec:
+ forProvider:
+ # Removed for brevity
+ vpcId: vpc-01353cfe93950a8ff
+```
+
+##### Matching by name reference
+
+To match a resource based on the name of the managed resource and not the
+external resource name inside the Provider, use a `nameRef`.
+
+For example, a AWS VPC object named `my-test-vpc` has the external name
+`vpc-01353cfe93950a8ff`.
+
+```shell {copy-lines="1"}
+kubectl get vpc
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-test-vpc True True vpc-01353cfe93950a8ff 49m
+```
+
+To match the VPC by name reference, use the managed resource name. For example,
+creating a Subnet managed resource attached to this VPC.
+
+```yaml {copy-lines="none"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Subnet
+spec:
+ forProvider:
+ # Removed for brevity
+ vpcIdRef:
+ name: my-test-vpc
+```
+
+
+##### Matching by selector
+
+Matching by selector is the most flexible matching method.
+
+{{}}
+
+The [Compositions]({{[}}) section covers the
+`matchControllerRef` selector.
+{{] }}
+
+Use `matchLabels` to match the labels applied to a resource. For example, this
+Subnet resource only matches VPC resources with the label
+`my-label: label-value`.
+
+```yaml {copy-lines="none"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Subnet
+spec:
+ forProvider:
+ # Removed for brevity
+ vpcIdSelector:
+ matchLabels:
+ my-label: label-value
+```
+
+
+#### Immutable fields
+
+Some providers don't support changing the fields of some managed resources after
+creation. For example, you can't change the `region` of an Amazon AWS
+`RDSInstance`. These fields are _immutable fields_. Amazon requires you delete
+and recreate the resource.
+
+Crossplane allows you to edit the immutable field of a managed resource, but
+doesn't apply the change. Crossplane never deletes a resource based on a
+`forProvider` change.
+
+{{}}
+
+Crossplane behaves differently than other tools like Terraform. Terraform
+deletes and recreates a resource to change an immutable field. Crossplane only
+deletes an external resource if their corresponding managed
+resource object is deleted from Kubernetes and the `deletionPolicy` is
+`delete`.
+
+{{< /hint >}}
+
+
+
+### managementPolicy
+
+
+{{}}
+The managed resource `managementPolicy` option is an alpha feature.
+
+Enable the `managementPolicy` in a provider with `--enable-management-policies`
+in a
+[ControllerConfig]({{[}}).
+{{< /hint >}}
+
+A `managementPolicy` determines if Crossplane can make changes to managed
+resources. The `ObserveOnly` policy imports existing external resources not
+originally created by Crossplane.
+This allows new managed resources to reference
+the `ObserveOnly` resource, for example, a shared database or network.
+The `ObserveOnly` policy can also place existing resources under the control of
+Crossplane.
+
+{{< hint "tip" >}}
+Read the [Import Existing Resources]({{][}})
+guide for more
+information on using the `managementPolicy` to import existing resources.
+{{< /hint >}}
+
+#### Options
+* `managementPolicy: FullControl` - **Default** - Crossplane can create, change
+ and delete the managed resource.
+* `managementPolicy: ObserveOnly` - Crossplane only imports the details of the
+ external resource, but doesn't make any changes to the managed resource.
+
+
+
+### providerConfigRef
+
+
+The `providerConfigRef` on a managed resource tells the Provider which
+[ProviderConfig]({{][}}) to
+use when creating the managed resource.
+
+Use a ProviderConfig to define the authentication method to use when
+communicating to the Provider.
+
+{{< hint "important" >}}
+If `providerConfigRef` isn't applied, Providers use the ProviderConfig named `default`.
+{{< /hint >}}
+
+For example, a managed resource references a ProviderConfig named
+{{]}}user-keys{{ }}.
+
+This matches the {{}}name{{ }} of a ProviderConfig.
+
+```yaml {label="pcref",copy-lines="none"}}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Instance
+spec:
+ forProvider:
+ # Removed for brevity
+ providerConfigRef: user-keys
+```
+
+```yaml {label="pc"}
+apiVersion: aws.crossplane.io/v1beta1
+kind: ProviderConfig
+metadata:
+ name: user-keys
+# Removed for brevity
+```
+
+{{< hint "tip" >}}
+Each managed resource can reference different ProviderConfigs. This allows
+different managed resources to authenticate with different credentials to the
+same Provider.
+{{< /hint >}}
+
+
+### providerRef
+
+
+
+Crossplane deprecated the `providerRef` field in `crossplane-runtime`
+[v0.10.0](https://github.com/crossplane/crossplane-runtime/releases/tag/v0.10.0).
+Managed resources using `providerRef`must use [`providerConfigRef`](#providerconfigref).
+
+
+
+### writeConnectionSecretToRef
+
+
+When a Provider creates a managed resource it may generate resource-specific
+details, like usernames, passwords or connection details like an IP address.
+
+Crossplane stores these details in a Kubernetes Secret object specified by the
+`writeConnectionSecretToRef` values.
+
+For example, when creating an AWS RDS database instance with the Crossplane
+[community AWS provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-aws/v0.40.0)
+generates an endpoint, password, port and username data. The Provider saves
+these variables in the Kubernetes secret
+{{}}rds-secret{{ }}, referenced by
+the
+{{}}writeConnectionSecretToRef{{ }}
+field.
+
+```yaml {label="secretname",copy-lines="none"}
+apiVersion: database.aws.crossplane.io/v1beta1
+kind: RDSInstance
+metadata:
+ name: my-rds-instance
+spec:
+ forProvider:
+ # Removed for brevity
+ writeConnectionSecretToRef:
+ name: rds-secret
+```
+
+Viewing the Secret object shows the saved fields.
+
+```yaml {copy-lines="1"}
+kubectl describe secret rds-secret
+Name: rds-secret
+# Removed for brevity
+Data
+====
+port: 4 bytes
+username: 10 bytes
+endpoint: 54 bytes
+password: 27 bytes
+```
+
+{{}}
+The Provider determines the data written to the Secret object. Refer to the
+specific Provider documentation for the generated Secret data.
+{{< /hint >}}
+
+
+### publishConnectionDetailsTo
+
+
+The `publishConnectionDetailsTo` field expands on
+[`writeConnectionSecretToRef`](#writeconnectionsecrettoref) supporting storing
+managed resource information as a Kubernetes Secret object or in an external
+secrets store like [HashiCorp Vault](https://www.vaultproject.io/).
+
+Using `publishConnectionDetailsTo` requires enabling Crossplane
+External Secrets Stores (ESS). Enable ESS inside a Provider with a
+[ControllerConfig]({{[}}) and
+in Crossplane with the `--enable-external-secret-stores` argument.
+
+{{< hint "note" >}}
+Not all Providers support `publishConnectionDetailsTo`. Check your Provider
+documentation for details.
+{{< /hint >}}
+
+#### Publish secrets to Kubernetes
+
+To publish the data generated by a managed resource as a Kubernetes Secret
+object provide a
+{{]}}publishConnectionDetailsTo.name{{< /hover >}}
+
+```yaml {label="k8secret",copy-lines="none"}
+apiVersion: rds.aws.upbound.io/v1beta1
+kind: Instance
+spec:
+ forProvider:
+ # Removed for brevity
+ publishConnectionDetailsTo:
+ name: rds-kubernetes-secret
+```
+
+Crossplane can apply labels and annotations to the Kubernetes secret as well
+using
+{{}}publishConnectionDetailsTo.metadata{{ }}.
+
+```yaml {label="k8label",copy-lines="none"}
+apiVersion: rds.aws.upbound.io/v1beta1
+kind: Instance
+spec:
+ forProvider:
+ # Removed for brevity
+ publishConnectionDetailsTo:
+ name: rds-kubernetes-secret
+ metadata:
+ labels:
+ label-tag: label-value
+ annotations:
+ annotation-tag: annotation-value
+```
+
+#### Publish secrets to an external secrets store
+
+Publishing secrets data to an external secret store like
+[HashiCorp Vault](https://www.vaultproject.io/) relies on a
+{{}}publishConnectionDetailsTo.configRef{{ }}.
+
+The
+{{}}configRef.name{{ }} references a
+{{}}StoreConfig{{ }}
+object.
+
+```yaml {label="configref",copy-lines="none"}
+apiVersion: rds.aws.upbound.io/v1beta1
+kind: Instance
+spec:
+ forProvider:
+ # Removed for brevity
+ publishConnectionDetailsTo:
+ name: rds-kubernetes-secret
+ configRef:
+ name: my-vault-storeconfig
+```
+
+```yaml {label="storeconfig",copy-lines="none"}
+apiVersion: secrets.crossplane.io/v1alpha1
+kind: StoreConfig
+metadata:
+ name: my-vault-storeconfig
+# Removed for brevity
+```
+
+{{}}
+Read the
+[Vault as an External Secrets Store]({{[}})
+guide for details on using StoreConfig objects.
+{{< /hint >}}
+
+
+## Annotations
+
+Crossplane applies a standard set of Kubernetes `annotations` to managed
+resources.
+
+{{]}}
+| Annotation | Definition |
+| --- | --- |
+| `crossplane.io/external-name` | The name of the managed resource inside the Provider. |
+| `crossplane.io/external-create-pending` | The timestamp of when Crossplane
+began creating a new managed resource. |
+| `crossplane.io/external-create-succeeded` | The timestamp of when the Provider successfully created the managed resource. |
+| `crossplane.io/external-create-failed` | The timestamp of when the Provider failed to create the managed resource. |
+| `crossplane.io/paused` | Indicates Crossplane isn't reconciling this resource. Read the [Pause Annotation](#paused) for more details. |
+| `crossplane.io/composition-resource-name` | For managed resource created by a Composition, this is the Composition's `resources.name` value. |
+{{
}}
+
+### Naming external resources
+By default Providers give external resources the same name as the Kubernetes
+object.
+
+For example, a managed resource named
+{{}}my-rds-instance{{ }} has
+the name `my-rds-instance` as an external resource inside the Provider's
+environment.
+
+```yaml {label="external-name",copy-lines="none"}
+apiVersion: database.aws.crossplane.io/v1beta1
+kind: RDSInstance
+metadata:
+ name: my-rds-instance
+```
+
+```shell
+kubectl get rdsinstance
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-rds-instance True True my-rds-instance 11m
+```
+
+Managed resource created with a `crossplane.io/external-name`
+annotation already provided use the annotation value as the external
+resource name.
+
+For example, the Provider creates managed resource named
+{{< hover label="custom-name" line="6">}}my-rds-instance{{ }} but uses
+the name {{}}my-custom-name{{ }}
+for the external resource inside AWS.
+
+```yaml {label="custom-name",copy-lines="none"}
+apiVersion: database.aws.crossplane.io/v1beta1
+kind: RDSInstance
+metadata:
+ name: my-rds-instance
+ annotations:
+ crossplane.io/external-name: my-custom-namee
+```
+
+```shell {copy-lines="1"}
+kubectl get rdsinstance
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-rds-instance True True my-custom-name 11m
+```
+
+### Creation annotations
+
+Providers create new managed resources with the
+`crossplane.io/external-create-pending` annotation.
+
+The Provider applies the `crossplane.io/external-create-succeeded` or
+`crossplane.io/external-create-failed` annotation after making the external API
+call and receiving a response.
+
+{{}}
+If a Provider restarts before creating the `succeed` or `fail` annotations the
+Provider can't reconcile the manged resource.
+
+Read Crossplane [issue
+#3037](https://github.com/crossplane/crossplane/issues/3037#issuecomment-1110142427)
+for more details
+{{< /hint >}}
+
+
+### Paused
+Manually applying the `crossplane.io/paused` annotation causes the Provider to
+stop reconciling the managed resource.
+
+Pausing a resource is useful when modifying Providers or preventing
+race-conditions when editing Kubernetes objects.
+
+Apply a {{}}crossplane.io/paused: "true"{{ }}
+annotation to a managed resource to pause reconciliation.
+
+{{< hint "note" >}}
+Only the value `"true"` pauses reconciliation.
+{{< /hint >}}
+
+```yaml {label="pause"}
+apiVersion: ec2.aws.upbound.io/v1beta1
+kind: Instance
+metadata:
+ name: my-rds-instance
+ annotations:
+ crossplane.io/paused: "true"
+spec:
+ forProvider:
+ region: us-west-1
+ instanceType: t2.micro
+```
+
+Remove the annotation to resume reconciliation.
+
+## Finalizers
+Crossplane applies a
+[Finalizer](https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/)
+on managed resources to control their deletion.
+
+{{< hint "note" >}}
+Kubernetes can't delete objects with Finalizers.
+{{ }}
+
+When Crossplane deletes a managed resource the Provider begins deleting the
+external resource, but the managed resource remains until the external
+resource is fully deleted.
+
+When the external resource is fully deleted Crossplane removes the Finalizer and
+deletes the managed resource object.
+
+## Conditions
+
+Crossplane has a standard set of `Conditions` for a managed
+resource. View the `Conditions` of a managed resource with
+`kubectl describe `
+
+
+{{}}
+Providers may define their own custom `Conditions`.
+{{ }}
+
+
+### Available
+`Reason: Available` indicates the Provider created the managed resource and it's
+ready for use.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Ready
+ Status: True
+ Reason: Available
+```
+### Creating
+
+`Reason: Creating` indicates the Provider is attempting to create the managed
+resource.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Ready
+ Status: False
+ Reason: Creating
+```
+
+### Deleting
+`Reason: Deleting` indicates the Provider is attempting to delete the managed
+resource.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Ready
+ Status: False
+ Reason: Deleting
+```
+
+
+### ReconcilePaused
+
+`Reason: ReconcilePaused` indicates the managed resource has a [Pause](#paused)
+annotation
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Synced
+ Status: False
+ Reason: ReconcilePaused
+```
+
+
+### ReconcileError
+
+`Reason: ReconcileError` indicates Crossplane encountered an error while
+reconciling the managed resource. The `Message:` value of the `Condition` helps
+identify the Crossplane error.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Synced
+ Status: False
+ Reason: ReconcileError
+```
+
+
+### ReconcileSuccess
+
+`Reason: ReconcileSuccess` indicates the Provider created and is monitoring the
+managed resource.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Synced
+ Status: True
+ Reason: ReconcileSuccess
+```
+
+### Unavailable
+`Reason: Unavailable` indicates Crossplane expects the managed resource to be
+available, but the Provider reports the resource is unhealthy.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Ready
+ Status: False
+ Reason: Unavailable
+```
+
+### Unknown
+`Reason: Unknown` indicates the Provider has an unexpected error with the
+managed resource. The `conditions.message` provides more information on what
+went wrong.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: Unknown
+ Status: False
+ Reason: Unknown
+```
+
+
+### Upjet Provider conditions
+[Upjet](https://github.com/upbound/upjet), the open source tool to generate
+Crossplane Providers, also has a set of standard `Conditions`.
+
+
+
+#### AsyncOperation
+
+
+Some resources may take more than a minute to create. Upjet based providers can
+complete their Kubernetes command before creating the managed resource by using
+an asynchronous operation.
+
+
+##### Finished
+The `Reason: Finished` indicates the asynchronous operation completed
+successfully.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: AsyncOperation
+ Status: True
+ Reason: Finished
+```
+
+
+##### Ongoing
+
+`Reason: Ongoing` indicates the managed resource operation is still in progress.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: AsyncOperation
+ Status: True
+ Reason: Ongoing
+```
+
+
+#### LastAsyncOperation
+
+
+The Upjet `Type: LastAsyncOperation` captures the previous asynchronous
+operation status as either `Success` or a failure `Reason`.
+
+
+##### ApplyFailure
+
+
+`Reason: ApplyFailure` indicates the Provider failed to apply a setting to the
+managed resource. The `conditions.message` provides more information on what
+went wrong.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: LastAsyncOperation
+ Status: False
+ Reason: ApplyFailure
+```
+
+
+##### DestroyFailure
+
+
+`Reason: DestroyFailure` indicates the Provider failed to delete the managed
+resource. The `conditions.message` provides more information on what
+went wrong.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: LastAsyncOperation
+ Status: False
+ Reason: DestroyFailure
+```
+
+##### Success
+`Reason: Success` indicates the Provider successfully created the managed
+resource asynchronously.
+
+```yaml {copy-lines="none"}
+Conditions:
+ Type: LastAsyncOperation
+ Status: True
+ Reason: Success
+```
\ No newline at end of file
diff --git a/content/v1.13/concepts/packages.md b/content/v1.13/concepts/packages.md
new file mode 100644
index 00000000..0e90ae88
--- /dev/null
+++ b/content/v1.13/concepts/packages.md
@@ -0,0 +1,513 @@
+---
+title: Crossplane Packages
+weight: 104
+description: "Packages combine multiple Crossplane resources into a single, portable, OCI image."
+---
+
+
+Crossplane packages are opinionated [OCI images] that contain a stream of YAML
+that can be parsed by the Crossplane package manager. Crossplane packages come
+in two varieties: [Providers] and Configurations. Ultimately, the primary
+purposes of Crossplane packages are as follows:
+
+- **Convenient Distribution**: Crossplane packages can be pushed to or installed
+ from any OCI-compatible registry.
+- **Version Upgrade**: Crossplane can update packages in-place, meaning that you
+ can pick up support for new resource types or controller bug-fixes without
+ modifying your existing infrastructure.
+- **Permissions**: Crossplane allocates permissions to packaged controllers in a
+ manner that ensures they will not maliciously take over control of existing
+ resources owned by other packages. Installing CRDs via packages also allows
+ Crossplane itself to manage those resources, allowing for powerful
+ [composition] features to be enabled.
+- **Dependency Management**: Crossplane resolves dependencies between packages,
+ automatically installing a package's dependencies if they are not present in
+ the cluster, and checking if dependency versions are valid if they are already
+ installed.
+
+## Table of Contents
+
+The following packaging operations are covered in detail below:
+
+- [Table of Contents](#table-of-contents)
+- [Building a Package](#building-a-package)
+ - [Provider Packages](#provider-packages)
+ - [Configuration Packages](#configuration-packages)
+- [Pushing a Package](#pushing-a-package)
+- [Installing a Package](#installing-a-package)
+ - [spec.package](#specpackage)
+ - [spec.packagePullPolicy](#specpackagepullpolicy)
+ - [spec.revisionActivationPolicy](#specrevisionactivationpolicy)
+ - [spec.revisionHistoryLimit](#specrevisionhistorylimit)
+ - [spec.packagePullSecrets](#specpackagepullsecrets)
+ - [spec.skipDependencyResolution](#specskipdependencyresolution)
+ - [spec.ignoreCrossplaneConstraints](#specignorecrossplaneconstraints)
+ - [spec.controllerConfigRef](#speccontrollerconfigref)
+- [Upgrading a Package](#upgrading-a-package)
+ - [Package Upgrade Issues](#package-upgrade-issues)
+- [The Package Cache](#the-package-cache)
+ - [Pre-Populating the Package Cache](#pre-populating-the-package-cache)
+
+## Building a Package
+
+As stated above, Crossplane packages are just opinionated OCI images, meaning
+they can be constructed using any tool that outputs files that comply the the
+OCI specification. However, constructing packages using the Crossplane CLI is a
+more streamlined experience, as it will perform build-time checks on your
+packages to ensure that they are compliant with the Crossplane [package format].
+
+Providers and Configurations vary in the types of resources they may contain in
+their packages. All packages must have a `crossplane.yaml` file in the root
+directory with package contents. The `crossplane.yaml` contains the package's
+metadata, which governs how Crossplane will install the package.
+
+### Provider Packages
+
+A Provider package contains a `crossplane.yaml` with the following format:
+
+```yaml
+apiVersion: meta.pkg.crossplane.io/v1
+kind: Provider
+metadata:
+ name: provider-gcp
+spec:
+ crossplane:
+ version: ">=v1.0.0"
+ controller:
+ image: crossplane/provider-gcp-controller:v0.14.0
+ permissionRequests:
+ - apiGroups:
+ - apiextensions.crossplane.io
+ resources:
+ - compositions
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+```
+
+See all available fields in the [official documentation][provider-docs].
+
+> Note: The `meta.pkg.crossplane.io` group does not contain custom resources
+> that may be installed into the cluster. They are strictly used as metadata in
+> a Crossplane package.
+
+A Provider package may optionally contain one or more CRDs. These CRDs will be
+installed prior to the creation of the Provider's `Deployment`. Crossplane will
+not install _any_ CRDs for a package unless it can determine that _all_ CRDs can
+be installed. This guards against multiple Providers attempting to reconcile the
+same CRDs. Crossplane will also create a `ServiceAccount` with permissions to
+reconcile these CRDs and it will be assigned to the controller `Deployment`.
+
+The `spec.controller.image` fields specifies that the `Provider` desires for the
+controller `Deployment` to be created with the provided image. It is important
+to note that this image is separate from the package image itself. In the case
+above, it is an image containing the `provider-gcp` controller binary.
+
+The `spec.controller.permissionRequests` field allows a package author to
+request additional RBAC for the packaged controller. The controller's
+`ServiceAccount` will automatically give the controller permission to reconcile
+all types that its package installs, as well as `Secrets`, `ConfigMaps`, and
+`Events`. Any additional permissions must be explicitly requested.
+
+> Note that the Crossplane RBAC manager can be configured to reject permissions
+> for certain API groups. If a package requests permissions that Crossplane is
+> configured to reject, the package will fail to be installed.
+> Authorized permissions should be aggregated to the rbac manager clusterrole
+> (the cluster role defined by the provider-clusterrole flag in the rbac manager)
+> by using the label `rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"`
+
+The `spec.crossplane.version` field specifies the version constraints for core
+Crossplane that the `Provider` is compatible with. It is advisable to use this
+field if a package relies on specific features in a minimum version of
+Crossplane.
+
+> All version constraints used in packages follow the [specification] outlined
+> in the `Masterminds/semver` repository.
+
+For an example Provider package, see [provider-gcp].
+
+To build a Provider package, navigate to the package root directory and execute
+the following command:
+
+```
+kubectl crossplane build provider
+```
+
+If the Provider package is valid, you will see a file with the `.xpkg`
+extension.
+
+> Note that the Crossplane CLI will not follow symbolic links for files in the
+> root package directory.
+
+### Configuration Packages
+
+A Configuration package contains a `crossplane.yaml` with the following format:
+
+```yaml
+apiVersion: meta.pkg.crossplane.io/v1
+kind: Configuration
+metadata:
+ name: my-org-infra
+spec:
+ crossplane:
+ version: ">=v1.0.0"
+ dependsOn:
+ - provider: xpkg.upbound.io/crossplane-contrib/provider-gcp
+ version: ">=v0.14.0"
+```
+
+See all available fields in the [official documentation][configuration-docs].
+
+A Configuration package may also specify one or more of
+`CompositeResourceDefinition` and `Composition` types. These resources will be
+installed and will be solely owned by the Configuration package. No other
+package will be able to modify them.
+
+The `spec.crossplane.version` field serves the same purpose that it does in a
+`Provider` package.
+
+The `spec.dependsOn` field specifies packages that this package depends on. When
+installed, the package manager will ensure that all dependencies are present and
+have a valid version given the constraint. If a dependency is not installed, the
+package manager will install it at the latest version that fits within the
+provided constraints.
+
+> Dependency resolution is a `beta` feature and depends on the `v1beta1`
+> [`Lock` API][lock-api].
+
+For an example Configuration package, see [getting-started-with-gcp](https://github.com/crossplane/docs/tree/master/content/v1.10/snippets/package/gcp).
+
+To build a Configuration package, navigate to the package root directory and
+execute the following command:
+
+```
+kubectl crossplane build configuration
+```
+
+If the Provider package is valid, you will see a file with the `.xpkg`
+extension.
+
+## Pushing a Package
+
+Crossplane packages can be pushed to any OCI-compatible registry. If a specific
+registry is not specified they will be pushed to Docker Hub.
+
+To push a Provider package, execute the following command:
+
+```
+kubectl crossplane push provider xpkg.upbound.io/crossplane-contrib/provider-gcp:v0.22.0
+```
+
+To push a Configuration package, execute the following command:
+
+```
+kubectl crossplane push configuration xpkg.upbound.io/crossplane-contrib/my-org-infra:v0.1.0
+```
+
+> Note: Both of the above commands assume a single `.xpkg` file exists in the
+> directory. If multiple exist or you would like to specify a package in a
+> different directory, you can supply the `-f` flag with the path to the
+> package.
+
+## Installing a Package
+
+Packages can be installed into a Crossplane cluster using the Crossplane CLI.
+
+To install a Provider package, execute the following command:
+
+```
+kubectl crossplane install provider xpkg.upbound.io/crossplane-contrib/provider-gcp:v0.22.0
+```
+
+To install a Configuration package, execute the following command:
+
+```
+kubectl crossplane install configuration xpkg.upbound.io/crossplane-contrib/my-org-infra:v0.1.0
+```
+
+Packages can also be installed manually by creating a `Provider` or
+`Configuration` object directly. The preceding commands would result in the
+creation of the following two resources, which could have been authored by hand:
+
+```yaml
+apiVersion: pkg.crossplane.io/v1
+kind: Provider
+metadata:
+ name: provider-gcp
+spec:
+ package: xpkg.upbound.io/crossplane-contrib/provider-gcp:v0.22.0
+ packagePullPolicy: IfNotPresent
+ revisionActivationPolicy: Automatic
+ revisionHistoryLimit: 1
+```
+
+```yaml
+apiVersion: pkg.crossplane.io/v1
+kind: Configuration
+metadata:
+ name: my-org-infra
+spec:
+ package: xpkg.upbound.io/crossplane-contrib/my-org-infra:v0.1.0
+ packagePullPolicy: IfNotPresent
+ revisionActivationPolicy: Automatic
+ revisionHistoryLimit: 1
+```
+
+> Note: These types differ from the `Provider` and `Configuration` types we saw
+> earlier. They exist in the `pkg.crossplane.io` group rather than the
+> `meta.pkg.crossplane.io` group and are actual custom resources created in the
+> cluster.
+
+The default fields specified above can be configured with different values to
+modify the installation and upgrade behavior of a package. In addition, there
+are multiple other fields which can further customize how the package manager
+handles a specific revision.
+
+### spec.package
+
+This is the package image that we built, pushed, and are asking Crossplane to
+install. The tag we specify here is important. Crossplane will periodically
+check if the installed image matches the digest of the image in the remote
+registry. If it does not, Crossplane will create a new _Revision_ (either
+`ProviderRevision` or `ConfigurationRevision`). If you do not wish Crossplane to
+ever update your packages without explicitly instructing it to do so, you should
+consider specifying a tag which you know will not have the underlying contents
+change unexpectedly (e.g. a specific semantic version, such as `v0.1.0`) or, for
+an even stronger guarantee, providing the image with a `@sha256` extension
+instead of a tag.
+
+### spec.packagePullPolicy
+
+Valid values: `IfNotPresent`, `Always`, or `Never` (default: `IfNotPresent`)
+
+When a package is installed, Crossplane downloads the image contents into a
+cache. Depending on the image identifier (tag or digest) and the
+`packagePullPolicy`, the Crossplane package manager will decide if and when to
+check and see if newer package contents are available. The following table
+describes expected behavior based on the supplied fields:
+
+| | `IfNotPresent` | `Always` | `Never` |
+|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
+| Semver Tag (e.g. `v1.3.0`) | Package is downloaded when initially installed, and as long as it is present in the cache, it will not be downloaded again. If the cache is lost and the a new version of the package image has been pushed for the same tag, package could inadvertently be upgraded. **Upgrade Safety: Strong** | Package is downloaded when initially installed, but Crossplane will check every minute if new content is available. New content would have to be pushed for the same semver tag for upgrade to take place. **Upgrade Safety: Weak** | Crossplane will never download content. Must manually load package image in cache. **Upgrade Safety: Strongest** |
+| Digest (e.g. `@sha256:28b6...`) | Package is downloaded when initially installed, and as long as it is present in the cache, it will not be downloaded again. If the cache is lost but an image with this digest is still available, it will be downloaded again. The package will never be upgraded without a user changing the digest. **Upgrade Safety: Very Strong** | Package is downloaded when initially installed, but Crossplane will check every minute if new content is available. Because image digest is used, new content will never be downloaded. **Upgrade Safety: Strong** | Crossplane will never download content. Must manually load package image in cache. **Upgrade Safety: Strongest** |
+| Channel Tag (e.g. `latest`) | Package is downloaded when initially installed, and as long as it is present in the cache, it will not be downloaded again. If the cache is lost, the latest version of this package image will be downloaded again, which will frequently have different contents. **Upgrade Safety: Weak** | Package is downloaded when initially installed, but Crossplane will check every minute if new content is available. When the image content is new, Crossplane will download the new contents and create a new revision. **Upgrade Safety: Very Weak** | Crossplane will never download content. Must manually load package image in cache. **Upgrade Safety: Strongest** |
+
+### spec.revisionActivationPolicy
+
+Valid values: `Automatic` or `Manual` (default: `Automatic`)
+
+When Crossplane downloads new contents for a package, regardless of whether it
+was a manual upgrade (i.e. user updating package image tag), or an automatic one
+(enabled by the `packagePullPolicy`), it will create a new package revision.
+However, the new objects and / or controllers will not be installed until the
+new revision is marked as `Active`. This activation process is configured by the
+`revisionActivationPolicy` field.
+
+An `Active` package revision attempts to become the _controller_ of all
+resources it installs. There can only be one controller of a resource, so if two
+`Active` revisions both install the same resource, one will fail to install
+until the other cedes control.
+
+An `Inactive` package revision attempts to become the _owner_ of all resources
+it installs. There can be an arbitrary number of owners of a resource, so
+multiple `Inactive` revisions and a single `Active` revision can exist for a
+resource. Importantly, an `Inactive` package revision will not perform any
+auxiliary actions (such as creating a `Deployment` in the case of a `Provider`),
+meaning we will not encounter a situation where two revisions are fighting over
+reconciling a resource.
+
+With `revisionActivationPolicy: Automatic`, Crossplane will mark any new
+revision as `Active` when it is created, as well as transition any old revisions
+to `Inactive`. When `revisionActivationPolicy: Manual`, the user must manually
+edit a new revision and mark it as `Active`. This can be useful if you are using
+a `packagePullPolicy: Automatic` with a channel tag (e.g. `latest`) and you want
+Crossplane to create new revisions when a new version is available, but you
+don't want to automatically update to that newer revision.
+
+It is recommended for most users to use semver tags or image digests and
+manually update their packages, but use a `revisionActivationPolicy: Automatic`
+to avoid having to manually activate new versions. However, each user should
+consider their specific environment and choose a combination that makes sense
+for them.
+
+For security reasons, it's suggested using image digests instead or alongside
+tags (`vx.y.z@sha256:...`), to ensure that the package content wasn't tampered
+with.
+
+### spec.revisionHistoryLimit
+
+Valid values: any integer, disabled by explicitly setting to `0` (default `1`)
+
+When a revision transitions from `Inactive` to `Active`, its revision number
+gets set to one greater than the largest revision number of all revisions for
+its package. Therefore, as the number of revisions increases, the least recently
+`Active` revision will have the lowest revision number. Crossplane will garbage
+collect old `Inactive` revisions if they fall outside the
+`spec.revisionHistoryLimit`. For instance, if my revision history limit is `3`
+and I currently have three old `Inactive` revisions and one `Active` revision,
+when I upgrade the next time, the new revision will be given the highest
+revision number when it becomes `Active`, the previously `Active` revision will
+become `Inactive`, and the oldest `Inactive` revision will be garbage collected.
+
+> Note: In the case that `spec.revisionActivationPolicy: Manual` and you upgrade
+> enough times (but do not make `Active` the new revisions), it is possible that
+> activating a newer revision could cause the previously `Active` revision to
+> immediately be garbage collected if it is outside the
+> `spec.revisionHistoryLimit`.
+
+### spec.packagePullSecrets
+
+Valid values: slice of `Secret` names (secrets must exist in `namespace`
+Crossplane was installed in, typically `crossplane-system`)
+
+This field allows a user to provide credentials required to pull a package from
+a private repository on a registry. The credentials are passed along to a
+packaged controller if the package is a `Provider`, but are not passed along to
+any dependencies.
+
+### spec.skipDependencyResolution
+
+Valid values: `true` or `false` (default: `false`)
+
+If `skipDependencyResolution: true`, the package manager will install a package
+without considering its dependencies.
+
+### spec.ignoreCrossplaneConstraints
+
+Valid values: `true` or `false` (default: `false`)
+
+If `ignoreCrossplaneConstraints: true`, the package manager will install a
+package without considering the version of Crossplane that is installed.
+
+### spec.controllerConfigRef
+
+{{< hint "warning" >}}
+The `ControllerConfig` API has been deprecated and will be removed in a future
+release when a comparable alternative is available.
+{{< /hint >}}
+
+Valid values: name of a `ControllerConfig` object
+
+Packaged `Provider` controllers are installed in the form of a `Deployment`.
+Crossplane populates the `Deployment` with default values that may not be
+appropriate for every use-case. In the event that a user wants to override some
+of the defaults that Crossplane has set, they may create and reference a
+`ControllerConfig`.
+
+An example of when this may be useful is when a user is running Crossplane on
+EKS and wants to take advantage of [IAM Roles for Service Accounts]. This
+requires setting an `fsGroup` and annotating the `ServiceAccount` that
+Crossplane creates for the controller. This could be accomplished with the
+following `ControllerConfig` and `Provider`:
+
+```yaml
+apiVersion: pkg.crossplane.io/v1alpha1
+kind: ControllerConfig
+metadata:
+ name: aws-config
+ annotations:
+ eks.amazonaws.com/role-arn: arn:aws:iam::$AWS_ACCOUNT_ID\:role/$IAM_ROLE_NAME
+spec:
+ podSecurityContext:
+ fsGroup: 2000
+---
+apiVersion: pkg.crossplane.io/v1
+kind: Provider
+metadata:
+ name: provider-aws
+spec:
+ package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.33.0
+ controllerConfigRef:
+ name: aws-config
+```
+
+You can find all configurable values in the [official `ControllerConfig`
+documentation][controller-config-docs].
+
+## Upgrading a Package
+
+Upgrading a `Provider` or `Configuration` to a new version can be accomplished
+by editing the existing manifest and applying it with a new version tag in
+`spec.package`. Crossplane will observe the updated manifest and create a new
+`ProviderRevision` or `ConfigurationRevision` for the specified version. The new
+revision will be activated in accordance with `spec.revisionActivationPolicy`.
+
+### Package Upgrade Issues
+
+Upgrading a package can require manual intervention in the event that the
+previous version of the package supported a version of a custom resource that
+has been dropped and replaced by a new version in the new package revision.
+Kubernetes does not allow for applying a `CustomResourceDefinition` (CRD) that
+drops a version in the `spec` that is in the current `status.storedVersions`
+list, meaning that a revision cannot update and become the _controller_ of all
+of its resources.
+
+This situation can be remedied by manually deleting the offending CRD and
+letting the new revision re-create it. In the event that custom resources exist
+for the given CRD, they must be deleted before the CRD can be removed.
+
+## The Package Cache
+
+When a package is installed into a cluster, Crossplane fetches the package image
+and stores its contents in a dedicated package cache. By default, this cache is
+backed by an [`emptyDir` Volume][emptyDir-volume], meaning that all cached data
+is lost when a `Pod` restarts. Users who wish for cache contents to be persisted
+between `Pod` restarts may opt to instead use a [`persistentVolumeClaim`
+(PVC)][pvc] by setting the `packageCache.pvc` Helm chart parameter to the name
+of the PVC.
+
+### Pre-Populating the Package Cache
+
+Because the package cache can be backed by any storage medium, users are able to
+optionally to pre-populate the cache with images that are not present on an
+external [OCI registry]. To utilize a package that has been manually stored in
+the cache, users must specify the name of the package in `spec.package` and use
+`packagePullPolicy: Never`. For instance, if a user built a `Configuration`
+package named `mycoolpkg.xpkg` and loaded it into the volume that was to be used
+for the package cache (i.e. copied the `.xpkg` file into the storage medium
+backing the PVC), the package could be utilized with the following manifest:
+
+```yaml
+apiVersion: pkg.crossplane.io/v1
+kind: Configuration
+metadata:
+ name: my-cool-pkg
+spec:
+ package: mycoolpkg
+ packagePullPolicy: Never
+```
+
+Importantly, as long as a package is being used as the `spec.package` of a
+`Configuration` or `Provider`, it must remain in the cache. For this reason, it
+is recommended that users opt for a durable storage medium when manually loading
+packages into the cache.
+
+In addition, if manually loading a `Provider` package into the cache, users must
+ensure that the controller image that it references is able to be pulled by the
+cluster nodes. This can be accomplished either by pushing it to a registry, or
+by [pre-pulling images] onto nodes in the cluster.
+
+
+
+
+[OCI images]: https://github.com/opencontainers/image-spec
+[Providers]: {{[}}
+[provider-docs]: https://doc.crds.dev/github.com/crossplane/crossplane/meta.pkg.crossplane.io/Provider/v1
+[configuration-docs]: https://doc.crds.dev/github.com/crossplane/crossplane/meta.pkg.crossplane.io/Configuration/v1
+[lock-api]: https://doc.crds.dev/github.com/crossplane/crossplane/pkg.crossplane.io/Lock/v1beta1
+[specification]: https://github.com/Masterminds/semver#basic-comparisons
+[composition]: {{][}}
+[IAM Roles for Service Accounts]: https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html
+[controller-config-docs]: https://doc.crds.dev/github.com/crossplane/crossplane/pkg.crossplane.io/ControllerConfig/v1alpha1
+[package format]: https://github.com/crossplane/crossplane/blob/1aa83092172bdf0d2ed64754d33517c612ff7368/design/one-pager-package-format-v2.md
+[provider-gcp]: https://doc.crds.dev/github.com/crossplane/crossplane/meta.pkg.crossplane.io/Provider/v1
+[emptyDir-volume]: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
+[pvc]: https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim
+[OCI registry]: https://github.com/opencontainers/distribution-spec
+[pre-pulling images]: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images
diff --git a/content/v1.13/concepts/patch-and-transform.md b/content/v1.13/concepts/patch-and-transform.md
new file mode 100644
index 00000000..09769c3a
--- /dev/null
+++ b/content/v1.13/concepts/patch-and-transform.md
@@ -0,0 +1,1658 @@
+---
+title: Patch and Transforms
+weight: 70
+description: "Crossplane Compositions use patches and transforms to modify inputs from claims and composite resources before creating managed resources"
+---
+
+Crossplane Compositions allow for "patch and transform" operations. With patches
+a Composition can apply changes to the resources defined by the Composition.
+
+When users create Claims, Crossplane passes the settings in the Claim to
+the associated composite resource. Patches can use these settings to change the
+associated composite resource or managed resources.
+
+Examples of using patch and transforms include:
+ * changing the name of the external resource
+ * mapping generic terms like "east" or "west" to specific provider locations
+ * appending custom labels or strings to resource fields
+
+
+{{]}}
+
+Crossplane expects patch and transform operations to be simple changes.
+Use [Composition Functions]({{[}}) for more
+complex or programmatic modifications.
+
+{{] }}
+
+
+A Composition [patch](#create-a-patch) is the action of changing a field.
+A Composition [transform](#transform-a-patch) modifies the values before
+applying the patch.
+
+## Create a patch
+
+Patches are part of an individual
+{{}}resource{{ }} inside a
+{{}}Composition{{ }}.
+
+The {{}}patches{{ }} field takes a
+list of patches to apply to the individual resource.
+
+Each patch has a {{}}type{{ }}, which
+defines what kind of patch action Crossplane applies.
+
+Patches reference fields inside a composite resource or Composition differently
+depending on the patch type, but all patches reference a
+{{}}fromFieldPath{{ }} and
+{{}}toFieldPath{{ }}.
+
+The {{}}fromFieldPath{{ }} defines
+the patch's input values.
+The {{}}toFieldPath{{ }} defines the
+data to change with a patch.
+
+Here is an example patch applied to a resource in a Composition.
+```yaml {label="createComp",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+spec:
+ resources:
+ - name: my-composed-resource
+ base:
+ # Removed for brevity
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.labels["patchLabel"]
+```
+
+### Selecting fields
+
+Crossplane selects fields in a composite resource or managed
+resource with
+a subset of
+[JSONPath selectors](https://kubernetes.io/docs/reference/kubectl/jsonpath/),
+called "field selectors."
+
+Field selectors can select any field in a composite resource or managed resource
+object, including the `metadata`, `spec` or `status` fields.
+
+Field selectors can be a string matching a field name or an array index, in
+brackets. Field names may use a `.` character to select child elements.
+
+
+{{< expand "Example field selectors" >}}
+Here are some example selectors from a composite resource object.
+{{}}
+| Selector | Selected element |
+| --- | --- |
+| `kind` | {{}}kind{{ }} |
+| `metadata.labels['crossplane.io/claim-name']` | {{}}my-example-claim{{ }} |
+| `spec.desiredRegion` | {{}}eu-north-1{{ }} |
+| `spec.resourceRefs[0].name` | {{}}my-example-claim-978mh-r6z64{{ }} |
+{{
}}
+
+```yaml {label="select",copy-lines="none"}
+$ kubectl get composite -o yaml
+apiVersion: example.org/v1alpha1
+kind: xExample
+metadata:
+ # Removed for brevity
+ labels:
+ crossplane.io/claim-name: my-example-claim
+ crossplane.io/claim-namespace: default
+ crossplane.io/composite: my-example-claim-978mh
+spec:
+ desiredRegion: eu-north-1
+ field1: field1-text
+ resourceRefs:
+ - apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ name: my-example-claim-978mh-r6z64
+ - apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ name: my-example-claim-978mh-cnlhj
+ - apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ name: my-example-claim-978mh-rv5nm
+ # Removed for brevity
+```
+{{< /expand >}}
+
+## Reuse a patch
+
+A Composition can reuse a patch object on multiple resources with a
+PatchSet.
+
+To create a PatchSet, define a
+{{}}PatchSets{{ }} object inside the
+Composition's
+{{}}spec{{ }}.
+
+Each patch inside a PatchSet has a
+{{}}name{{ }} and a list of
+{{}}patches{{ }}.
+
+{{}}
+For multiple PatchSets only use a single
+{{}}PatchSets{{ }} object.
+
+Identify each unique PatchSet with a unique
+{{}}name{{ }}.
+{{ }}
+
+Apply the PatchSet to a resource with a patch
+{{}}type: PatchSet{{ }}.
+Set the
+{{}}patchSetName{{ }} to the
+{{}}name{{ }} of the PatchSet.
+
+```yaml {label="patchset"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+spec:
+ patchSets:
+ - name: my-patchset
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: spec.forProvider.region
+ resources:
+ - name: bucket1
+ base:
+ # Removed for brevity
+ patches:
+ - type: PatchSet
+ patchSetName: my-patchset
+ - name: bucket2
+ base:
+ # Removed for brevity
+ patches:
+ - type: PatchSet
+ patchSetName: my-patchset
+```
+
+{{}}
+A PatchSet can't contain other PatchSets.
+
+Crossplane ignores any [transforms](#transform-a-patch) or
+[policies](#patch-policies) in a PatchSet.
+{{< /hint >}}
+
+## Patching between resources
+
+Compositions can't directly patch between resources in the same Composition.
+For example, generating a network resource and patching the resource name to
+a compute resource.
+
+{{}}
+The [ToEnvironmentFieldPath](#toenvironmentfieldpath) patch can't read from a
+`Status` field.
+{{< /hint >}}
+
+A resource can patch to a user-defined
+{{}}Status{{ }}
+field in the composite resource.
+
+A resource can then read from that
+{{}}Status{{ }}
+field to patch a field.
+
+First, define a custom
+{{}}Status{{ }}
+in the Composite Resource Definition and a custom field, for example
+{{}}secondResource{{ }}
+
+```yaml {label="xrdPatch",copy-lines="13-17"}
+kind: CompositeResourceDefinition
+# Removed for brevity.
+spec:
+ # Removed for brevity.
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ # Removed for brevity.
+ status:
+ type: object
+ properties:
+ secondResource:
+ type: string
+```
+
+Inside the Composition the resource with the source data uses a
+{{}}ToCompositeFieldPath{{ }}
+patch to write data to the
+{{}}status.secondResource{{ }}
+field in the composite resource.
+
+The destination resource uses a
+{{}}FromCompositeFieldPath{{ }}
+patch to read data from the composite resource
+{{}}status.secondResource{{ }}
+field in the composite resource and write it to a label named
+{{}}secondResource{{ }} in the
+managed resource.
+
+```yaml {label="patchBetween",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ # Removed for brevity
+ patches:
+ - type: ToCompositeFieldPath
+ fromFieldPath: metadata.name
+ toFieldPath: status.secondResource
+ - name: bucket2
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ # Removed for brevity
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: status.secondResource
+ toFieldPath: metadata.labels['secondResource']
+```
+
+Describe the composite resource to view the
+{{}}resources{{ }} and the
+{{}}status.secondResource{{ }}
+value.
+
+```yaml {label="descCompPatch",copy-lines="none"}
+$ kubectl describe composite
+Name: my-example-claim-jp7rx
+Spec:
+ # Removed for brevity
+ Resource Refs:
+ Name: my-example-claim-jp7rx-gfg4m
+ # Removed for brevity
+ Name: my-example-claim-jp7rx-fttpj
+Status:
+ # Removed for brevity
+ Second Resource: my-example-claim-jp7rx-gfg4m
+```
+
+Describe the destination managed resource to see the label
+{{}}secondResource{{ }}.
+
+```yaml {label="bucketlabel",copy-lines="none"}
+$ kubectl describe bucket
+kubectl describe bucket my-example-claim-jp7rx-fttpj
+Name: my-example-claim-jp7rx-fttpj
+Labels: crossplane.io/composite=my-example-claim-jp7rx
+ secondResource=my-example-claim-jp7rx-gfg4m
+```
+
+## Types of patches
+Crossplane supports multiple patch types, each using a different source for data
+and applying the patch to a different location.
+
+Summary of Crossplane patches
+{{< table "table table-hover" >}}
+| Patch Type | Data Source | Data Destination |
+| --- | --- | --- |
+| [FromCompositeFieldPath](#fromcompositefieldpath) | A field in the composite resource. | A field in the patched managed resource. |
+| [ToCompositeFieldPath](#tocompositefieldpath) | A field in the patched managed resource. | A field in the composite resource. |
+| [CombineFromComposite](#tocompositefieldpath) | Multiple fields in the composite resource. | A field in the patched managed resource. |
+| [CombineToComposite](#tocompositefieldpath) | Multiple fields in the patched managed resource. | A field in the composite resource. |
+| [FromEnvironmentFieldPath](#tocompositefieldpath) | Data in the in-memory EnvironmentConfig Environment | A field in the patched managed resource. |
+| [ToEnvironmentFieldPath](#tocompositefieldpath) | A field in the patched managed resource. | The in-memory EnvironmentConfig Environment. |
+| [CombineFromEnvironment](#tocompositefieldpath) | Multiple fields in the in-memory EnvironmentConfig Environment. | A field in the patched managed resource. |
+| [CombineToEnvironment](#tocompositefieldpath) | Multiple fields in the patched managed resource. | A field in the in-memory EnvironmentConfig Environment. |
+{{< /table >}}
+
+{{}}
+All the following examples use the same set of Compositions,
+CompositeResourceDefinitions, Claims and EnvironmentConfigs.
+Only the applied patches change between
+examples.
+
+All examples rely on Upbound
+[provider-aws-s3](https://marketplace.upbound.io/providers/upbound/provider-aws-s3/)
+to create resources.
+
+{{< expand "Reference Composition" >}}
+```yaml {copy-lines="all"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: example-composition
+spec:
+ compositeTypeRef:
+ apiVersion: example.org/v1alpha1
+ kind: xExample
+ environment:
+ environmentConfigs:
+ - ref:
+ name: example-environment
+ resources:
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ - name: bucket2
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+```
+{{< /expand >}}
+
+{{}}
+```yaml {copy-lines="all"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xexamples.example.org
+spec:
+ group: example.org
+ names:
+ kind: xExample
+ plural: xexamples
+ claimNames:
+ kind: ExampleClaim
+ plural: exampleclaims
+ versions:
+ - name: v1alpha1
+ served: true
+ referenceable: true
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ field1:
+ type: string
+ field2:
+ type: string
+ field3:
+ type: string
+ desiredRegion:
+ type: string
+ boolField:
+ type: boolean
+ numberField:
+ type: integer
+ status:
+ type: object
+ properties:
+ url:
+ type: string
+```
+{{< /expand >}}
+
+
+{{< expand "Reference Claim" >}}
+```yaml {copy-lines="all"}
+apiVersion: example.org/v1alpha1
+kind: ExampleClaim
+metadata:
+ name: my-example-claim
+spec:
+ field1: "field1-text"
+ field2: "field2-text"
+ desiredRegion: "eu-north-1"
+ boolField: false
+ numberField: 10
+```
+{{< /expand >}}
+
+{{< expand "Reference EnvironmentConfig" >}}
+```yaml {copy-lines="all"}
+apiVersion: apiextensions.crossplane.io/v1alpha1
+kind: EnvironmentConfig
+metadata:
+ name: example-environment
+data:
+ locations:
+ us: us-east-2
+ eu: eu-north-1
+ key1: value1
+ key2: value2
+
+```
+{{< /expand >}}
+{{< /hint >}}
+
+
+### FromCompositeFieldPath
+
+
+The
+{{}}FromCompositeFieldPath{{ }}
+patch takes a value in a composite resource and applies it to a field in the
+managed resource.
+
+{{< hint "tip" >}}
+Use the
+{{}}FromCompositeFieldPath{{ }}
+patch to apply options from users in their Claims to settings in managed
+resource `forProvider` settings.
+{{< /hint >}}
+
+For example, to use the value
+{{}}desiredRegion{{ }} provided by
+a user in a composite resource to a managed resource's
+{{}}region{{ }}.
+
+The {{}}fromFieldPath{{ }} value
+is a field in the composite resource.
+
+The {{}}toFieldPath{{ }} value is
+the field in the managed resource to change.
+
+```yaml {label="fromComposite",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: spec.forProvider.region
+```
+
+View the managed resource to see the updated
+{{}}region{{ }}
+
+```yaml {label="fromCompMR",copy-lines="1"}
+$ kubectl describe bucket
+Name: my-example-claim-qlr68-29nqf
+# Removed for brevity
+Spec:
+ For Provider:
+ Region: eu-north-1
+```
+
+
+### ToCompositeFieldPath
+
+
+The
+{{}}ToCompositeFieldPath{{ }} writes
+data from an individual managed resource to
+the composite resource that created it.
+
+{{< hint "tip" >}}
+Use {{}}ToCompositeFieldPath{{ }}
+patches to take data from one managed resource in a Composition and use it in a
+second managed resource in the same Composition.
+{{< /hint >}}
+
+For example, after Crossplane creates a new managed resource, take the value
+{{}}hostedZoneID{{ }} and apply it
+as a
+{{}}label{{ }} in the composite
+resource.
+
+```yaml {label="toComposite",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: ToCompositeFieldPath
+ fromFieldPath: status.atProvider.hostedZoneId
+ toFieldPath: metadata.labels['ZoneID']
+```
+
+View the created managed resource to see the
+{{}}Hosted Zone Id{{ }} field.
+```yaml {label="toCompMR",copy-lines="none"}
+$ kubectl describe bucket
+Name: my-example-claim-p5pxf-5vnp8
+# Removed for brevity
+Status:
+ At Provider:
+ Hosted Zone Id: Z2O1EMRO9K5GLX
+ # Removed for brevity
+```
+
+Next view the composite resource and confirm the patch applied the
+{{}}label{{ }}
+```yaml {label="toCompositeXR",copy-lines="none"}
+$ kubectl describe composite
+Name: my-example-claim-p5pxf
+Labels: ZoneID=Z2O1EMRO9K5GLX
+```
+
+{{}}
+Crossplane doesn't apply the patch to the composite resource until the next
+reconcile loop, after creating the managed resource. This creates a delay
+between a managed resource being Ready and applying the patch.
+{{< /hint >}}
+
+
+
+### CombineFromComposite
+
+
+The
+{{}}CombineFromComposite{{ }}
+patch takes values from the composite resource, combines them and applies them
+to the managed resource.
+
+{{< hint "tip" >}}
+Use the
+{{}}CombineFromComposite{{ }}
+patch to create complex strings, like security policies and apply them to
+a managed resource.
+{{< /hint >}}
+
+For example, use the Claim value
+{{}}desiredRegion{{ }} and
+{{}}field2{{ }} to generate the
+managed resource's
+{{}}name{{ }}
+
+The
+{{}}CombineFromComposite{{ }}
+patch only supports the
+{{}}combine{{ }} option.
+
+The {{}}variables{{ }} are the
+list of
+{{}}fromFieldPath{{ }} values
+from the composite resource to combine.
+
+The only supported
+{{}}strategy{{ }} is
+{{}}strategy: string{{ }}.
+
+Optionally you can apply a
+{{}}string.fmt{{ }}, based on
+[Go string formatting](https://pkg.go.dev/fmt) to specify how to combine the
+strings.
+
+The {{}}toFieldPath{{ }} is the
+field in the managed resource to apply the new string to.
+
+```yaml {label="combineFromComp",copy-lines="11-20"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: CombineFromComposite
+ combine:
+ variables:
+ - fromFieldPath: spec.desiredRegion
+ - fromFieldPath: spec.field2
+ strategy: string
+ string:
+ fmt: "my-resource-%s-%s"
+ toFieldPath: metadata.name
+```
+
+Describe the managed resource to see the applied patch.
+
+```yaml {label="describeCombineFromComp",copy-lines="none"}
+$ kubectl describe bucket
+Name: my-resource-eu-north-1-field2-text
+```
+
+
+### CombineToComposite
+
+
+The
+{{}}CombineToComposite{{ }}
+patch takes values from the managed resource, combines them and applies them
+to the composite resource.
+
+{{}}
+Use {{}}CombineToComposite{{ }}
+patches to create a single field like a URL from multiple fields in a managed
+resource.
+{{< /hint >}}
+
+For example, use the managed resource
+{{}}name{{ }} and
+{{}}region{{ }} to generate a
+custom
+{{}}url{{ }}
+field.
+
+{{< hint "important" >}}
+Writing custom fields in the Status field of a composite resource requires
+defining the custom fields in the CompositeResourceDefinition first.
+
+{{< /hint >}}
+
+The
+{{}}CombineToComposite{{ }}
+patch only supports the
+{{}}combine{{ }} option.
+
+The {{}}variables{{ }} are the
+list of
+{{}}fromFieldPath{{ }}
+the managed resource to combine.
+
+The only supported
+{{}}strategy{{ }} is
+{{}}strategy: string{{ }}.
+
+Optionally you can apply a
+{{}}string.fmt{{ }}, based on
+[Go string formatting](https://pkg.go.dev/fmt) to specify how to combine the
+strings.
+
+The {{}}toFieldPath{{ }} is the
+field in the composite resource to apply the new string to.
+
+```yaml {label="combineToComposite",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: CombineToComposite
+ combine:
+ variables:
+ - fromFieldPath: metadata.name
+ - fromFieldPath: spec.forProvider.region
+ strategy: string
+ string:
+ fmt: "https://%s.%s.com"
+ toFieldPath: status.url
+```
+
+View the composite resource to verify the applied patch.
+
+```yaml {copy-lines="none"}
+$ kubectl describe composite
+Name: my-example-claim-bjdjw
+API Version: example.org/v1alpha1
+Kind: xExample
+# Removed for brevity
+Status:
+ # Removed for brevity
+ URL: https://my-example-claim-bjdjw-r6ncd.us-east-2.com
+```
+
+
+### FromEnvironmentFieldPath
+
+
+{{}}
+EnvironmentConfigs are an alpha feature. They aren't enabled by default.
+
+For more information about using an EnvironmentConfig, read the
+[EnvironmentConfigs]({{[}}) documentation.
+{{< /hint >}}
+
+The
+{{]}}FromEnvironmentFieldPath{{ }}
+patch takes values from the in-memory EnvironmentConfig environment and applies
+them to the managed resource.
+
+{{}}
+Use
+{{}}FromEnvironmentFieldPath{{ }}
+to apply custom managed resource settings based on the current environment.
+{{< /hint >}}
+
+For example, use the environment's
+{{}}locations.eu{{ }} value and
+apply it as the
+{{}}region{{ }}.
+
+```yaml {label="fromEnvField",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: FromEnvironmentFieldPath
+ fromFieldPath: locations.eu
+ toFieldPath: spec.forProvider.region
+```
+
+Verify managed resource to confirm the applied patch.
+
+```yaml {copy-lines="none"}
+kubectl describe bucket
+Name: my-example-claim-8vrvc-xx5sr
+Labels: crossplane.io/claim-name=my-example-claim
+# Removed for brevity
+Spec:
+ For Provider:
+ Region: eu-north-1
+ # Removed for brevity
+```
+
+
+### ToEnvironmentFieldPath
+
+
+{{}}
+EnvironmentConfigs are an alpha feature. They aren't enabled by default.
+
+For more information about using an EnvironmentConfig, read the
+[EnvironmentConfigs]({{[}}) documentation.
+{{< /hint >}}
+
+The
+{{]}}ToEnvironmentFieldPath{{ }}
+patch takes values the managed resource and applies them to the in-memory
+EnvironmentConfig environment.
+
+{{}}
+Use
+{{}}ToEnvironmentFieldPath{{ }}
+write data to the environment that any FromEnvironmentFieldPath
+patch can access.
+{{< /hint >}}
+
+For example, use the desired
+{{}}region{{ }} value and
+apply it as the environment's
+{{}}key1{{ }}.
+
+{{< hint "important" >}}
+The environment's key must already exist. Patches can't create new environment
+keys.
+{{< /hint >}}
+
+```yaml {label="toEnvField",copy-lines="9-11"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: ToEnvironmentFieldPath
+ fromFieldPath: spec.forProvider.region
+ toFieldPath: key1
+```
+
+Because the environment is in-memory, there is no command to confirm the patch
+wrote the value to the environment.
+
+{{}}
+The
+{{}}ToEnvironmentFieldPath{{ }}
+patch happens **before** creating a resource.
+The
+{{}}fromFieldPath{{ }} can't
+read from the `atProvider` or `Status` fields.
+{{< /hint >}}
+
+
+
+### CombineFromEnvironment
+
+
+{{}}
+EnvironmentConfigs are an alpha feature. They aren't enabled by default.
+
+For more information about using an EnvironmentConfig, read the
+[EnvironmentConfigs]({{[}}) documentation.
+{{< /hint >}}
+
+The
+{{]}}CombineFromEnvironment{{ }}
+patch combines multiple values from the in-memory EnvironmentConfig environment and applies
+them to the managed resource.
+
+{{}}
+Use
+{{}}CombineFromEnvironment{{ }}
+patch to create complex strings, like security policies and apply them to
+a managed resource.
+{{< /hint >}}
+
+For example, combine multiple fields in the environment to create a unique
+{{}}annotation{{ }}
+.
+
+The
+{{}}CombineFromEnvironment{{ }}
+patch only supports the
+{{}}combine{{ }} option.
+
+The only supported
+{{}}strategy{{ }} is
+{{}}strategy: string{{ }}.
+
+The {{}}variables{{ }} are the
+list of
+{{}}fromFieldPath{{ }} values
+from the in-memory environment to combine.
+
+Optionally you can apply a
+{{}}string.fmt{{ }}, based on
+[Go string formatting](https://pkg.go.dev/fmt) to specify how to combine the
+strings.
+
+The {{}}toFieldPath{{ }} is the
+field in the managed resource to apply the new string to.
+
+
+```yaml {label="combineFromEnv",copy-lines="11-20"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: CombineFromEnvironment
+ combine:
+ strategy: string
+ variables:
+ - fromFieldPath: key1
+ - fromFieldPath: key2
+ string:
+ fmt: "%s-%s"
+ toFieldPath: metadata.annotations[EnvironmentPatch]
+```
+
+Describe the managed resource to see new
+{{}}annotation{{ }}.
+
+```yaml {copy-lines="none",label="combineFromEnvDesc"}
+$ kubectl describe bucket
+Name: my-example-claim-zmxdg-grl6p
+# Removed for brevity
+Annotations: EnvironmentPatch: value1-value2
+# Removed for brevity
+```
+
+
+### CombineToEnvironment
+
+
+{{}}
+EnvironmentConfigs are an alpha feature. They aren't enabled by default.
+
+For more information about using an EnvironmentConfig, read the
+[EnvironmentConfigs]({{[}}) documentation.
+{{< /hint >}}
+
+The
+{{]}}CombineToEnvironment{{ }}
+patch combines multiple values from the managed resource and applies them to the in-memory EnvironmentConfig environment.
+
+{{}}
+Use
+{{}}CombineToEnvironment{{ }}
+patch to create complex strings, like security policies to use in other managed resources.
+{{< /hint >}}
+
+For example, combine multiple fields in the managed resource to create a unique
+string and store it in the environment's
+{{}}key2{{ }} value.
+
+The string combines the
+managed resource
+{{}}Kind{{ }} and
+{{}}region{{ }}.
+
+The
+{{}}CombineToEnvironment{{ }}
+patch only supports the
+{{}}combine{{ }} option.
+
+The only supported
+{{}}strategy{{ }} is
+{{}}strategy: string{{ }}.
+
+The {{}}variables{{ }} are the
+list of
+{{}}fromFieldPath{{ }}
+values in the managed resource to combine.
+
+Optionally you can apply a
+{{}}string.fmt{{ }}, based on
+[Go string formatting](https://pkg.go.dev/fmt) to specify how to combine the
+strings.
+
+The {{}}toFieldPath{{ }} is the
+key in the environment to write the new string to.
+
+{{< hint "important" >}}
+The environment's key must already exist. Patches can't create new environment
+keys.
+{{< /hint >}}
+
+```yaml {label="combineToEnv",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: CombineToEnvironment
+ combine:
+ strategy: string
+ variables:
+ - fromFieldPath: kind
+ - fromFieldPath: spec.forProvider.region
+ string:
+ fmt: "%s.%s"
+ toFieldPath: key2
+```
+
+Because the environment is in-memory, there is no command to confirm the patch
+wrote the value to the environment.
+
+## Transform a patch
+
+When applying a patch, Crossplane supports modifying the data before applying it
+as a patch. Crossplane calls this a "transform" operation.
+
+Summary of Crossplane transforms.
+{{< table "table table-hover" >}}
+| Transform Type | Action |
+| --- | --- |
+| [convert](#convert-transforms) | Converts an input data type to a different type. Also called "casting." |
+| [map](#map-transforms) | Selects a specific output based on a specific input. |
+| [match](#match-transform) | Selects a specific output based on a string or regular expression. |
+| [math](#math-transforms) | Applies a mathematical operation on the input. |
+| [string](#string-transforms) | Change the input string using [Go string formatting](https://pkg.go.dev/fmt). |
+{{< /table >}}
+
+Apply a transform directly to an individual patch with the
+{{}}transforms{{ }} field.
+
+A
+{{}}transform{{ }}
+requires a
+{{}}type{{ }}, indicating the
+transform action to take.
+
+The other transform field is the same as the
+{{}}type{{ }}, in this example,
+{{}}map{{ }}.
+
+The other fields depend on the patch type used.
+
+This example uses a
+{{}}type: map{{ }} transform, taking
+the input
+{{}}spec.desiredRegion{{ }}, matching
+it to either
+{{}}us{{ }} or
+{{}}eu{{ }} and returning the
+corresponding AWS region for the
+{{}}spec.forProvider.region{{ }}
+value.
+
+```yaml {label="transform1",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+# Removed for brevity
+ - name: bucket1
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ spec:
+ forProvider:
+ region: us-east-2
+ patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: spec.forProvider.region
+ transforms:
+ - type: map
+ map:
+ us: us-east-2
+ eu: eu-north-1
+```
+
+### Convert transforms
+
+The {{}}convert{{ }} transform type
+changes the input data type to a different data type.
+
+{{< hint "tip" >}}
+Some provider APIs require a field to be a string. Use a
+{{}}convert{{ }} type to
+change any boolean or integer fields to strings.
+{{< /hint >}}
+
+A {{}}convert{{ }}
+transform requires a {{}}toType{{ }},
+defining the output data type.
+
+```yaml {label="convert",copy-lines="none"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.numberField
+ toFieldPath: metadata.label["numberToString"]
+ transforms:
+ - type: convert
+ convert:
+ toType: string
+```
+
+Supported `toType` values:
+{{< table "table table-sm table-hover" >}}
+| `toType` value | Description |
+| -- | -- |
+| `bool` | A boolean value of `true` or `false`. |
+| `float64` | A 64-bit float value. |
+| `int` | A 32-bit integer value. |
+| `int64` | A 64-bit integer value. |
+| `string` | A string value. |
+{{< /table >}}
+
+#### Converting strings to booleans
+When converting from a string to a `bool` Crossplane considers the string values
+`1`, `t`, `T`, `TRUE`, `True` and `true`
+equal to the boolean value `True`.
+
+The strings
+`0`, `f`, `F`, `FALSE`, `False` and `false`
+are equal to the boolean value `False`.
+
+#### Converting numbers to booleans
+Crossplane considers the integer `1` and float `1.0` equal to the boolean
+value `True`.
+Any other integer or float value is `False`.
+
+#### Converting booleans to numbers
+Crossplane converts the boolean value `True` to the integer `1` or float64
+`1.0`.
+
+The value `False` converts to the integer `0` or float64 `0.0`
+
+#### Converting strings to float64
+When converting from a `string` to a
+{{}}float64{{ }} Crossplane supports
+an optional
+{{}}format: quantity{{ }} field.
+
+Using {{}}format: quantity{{ }} translates
+size suffixes like `M` for megabyte or `Mi` for megabit into the correct float64
+value.
+
+{{}}
+Refer to the [Go language docs](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity)
+for a full list of supported suffixes.
+{{ }}
+
+Add {{}}format: quantity{{ }} to the
+{{}}convert{{ }} object to enable quantity
+suffix support.
+
+```yaml {label="format",copy-lines="all"}
+- type: convert
+ convert:
+ toType: float64
+ format: quantity
+```
+
+### Map transforms
+The {{}}map{{ }} transform type
+_maps_ an input value to an output value.
+
+{{< hint "tip" >}}
+The {{}}map{{ }} transform is useful for
+translating generic region names like `US` or `EU` to provider specific region
+names.
+{{< /hint >}}
+
+The {{}}map{{ }} transform compares the value
+from the {{}}fromFieldPath{{ }} to the
+options listed in the {{}}map{{ }}.
+
+If Crossplane finds the value, Crossplane puts
+the mapped value in the {{}}toFieldPath{{ }}.
+
+{{}}
+Crossplane ignores the patch if the value isn't found.
+{{< /hint >}}
+
+{{}}spec.field1{{ }} is the string
+{{}}"field1-text"{{ }} then Crossplane uses
+the string
+{{}}firstField{{ }} for the
+{{}}annotation{{ }}.
+
+If
+{{}}spec.field1{{ }} is the string
+{{}}"field2-text"{{ }} then Crossplane uses
+the string
+{{}}secondField{{ }} for the
+{{}}annotation{{ }}.
+
+```yaml {label="map",copy-lines="none"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: map
+ map:
+ "field1-text": "firstField"
+ "field2-text": "secondField"
+```
+In this example, the value of
+{{}}spec.field1{{ }} is
+{{}}field1-text{{ }}.
+
+```yaml {label="comositeMap",copy-lines="none"}
+$ kubectl describe composite
+Name: my-example-claim-twx7n
+Spec:
+ # Removed for brevity
+ field1: field1-text
+```
+
+The annotation applied to the managed resource is
+{{}}firstField{{ }}.
+
+```yaml {label="mrMap",copy-lines="none"}
+$ kubectl describe bucket
+Name: my-example-claim-twx7n-ndb2f
+Annotations: crossplane.io/composition-resource-name: bucket1
+ myLabel: firstField
+# Removed for brevity.
+```
+
+### Match transform
+The {{}}match{{ }} transform is like the
+`map` transform.
+
+The {{}}match{{ }}
+transform adds support for regular expressions along with exact
+strings and can provide default values if there isn't a match.
+
+A {{}}match{{ }} object requires a
+{{}}patterns{{ }} object.
+
+The {{}}patterns{{ }} is a list of one or
+more patterns to attempt to match the input value against.
+
+```yaml {label="match",copy-lines="1-8"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: match
+ match:
+ patterns:
+ - type: literal
+ # Removed for brevity
+ - type: regexp
+ # Removed for brevity
+```
+
+Match {{}}patterns{{ }} can be either
+{{}}type: literal{{ }} to match an
+exact string or
+{{}}type: regexp{{ }} to match a
+regular expression.
+
+{{}}
+Crossplane stops processing matches after the first pattern match.
+{{< /hint >}}
+
+#### Match an exact string
+Use a {{}}pattern{{ }} with
+{{}}type: literal{{ }} to match an
+exact string.
+
+On a successful match Crossplane provides the
+{{}}result:{{ }} to
+the patch {{}}toFieldPath{{ }}.
+
+```yaml {label="matchLiteral"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: match
+ match:
+ patterns:
+ - type: literal
+ literal: "field1-text"
+ result: "matchedLiteral"
+```
+
+#### Match a regular expression
+Use a {{}}pattern{{ }} with
+{{}}type: regexp{{ }} to match a regular
+expression.
+Define a
+{{}}regexp{{ }} key with the value of the
+regular expression to match.
+
+On a successful match Crossplane provides the
+{{}}result:{{ }} to
+the patch {{}}toFieldPath{{ }}.
+
+```yaml {label="matchRegex"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: match
+ match:
+ patterns:
+ - type: regexp
+ regexp: '^field1.*'
+ result: "foundField1"
+```
+
+#### Using default values
+
+Optionally you can provide a default value to use if there is no matching
+pattern.
+
+The default value can either be the original input value or a defined default
+value.
+
+Use
+{{}}fallbackTo: Value{{ }} to
+provide a default value if a match isn't found.
+
+For example if the string
+{{}}unknownString{{ }} isn't
+matched, Crossplane provides the
+{{}}Value{{ }}
+{{}}StringNotFound{{ }} to the
+{{}}toFieldPath{{ }}
+
+
+```yaml {label="defaultValue"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: match
+ match:
+ patterns:
+ - type: literal
+ literal: "UnknownString"
+ result: "foundField1"
+ fallbackTo: Value
+ fallbackValue: "StringNotFound"
+```
+
+To use the original input as the fallback value use
+{{}}fallbackTo: Input{{ }}.
+
+Crossplane uses the original
+{{}}fromFieldPath{{ }} input for the
+{{}}toFieldPath{{ }} value.
+```yaml {label="defaultInput"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["myAnnotation"]
+ transforms:
+ - type: match
+ match:
+ patterns:
+ - type: literal
+ literal: "UnknownString"
+ result: "foundField1"
+ fallbackTo: Input
+```
+
+### Math transforms
+
+Use the {{}}math{{ }} transform to multiply
+an input or apply a minimum or maximum value.
+
+{{}}
+A {{}}math{{ }} transform only supports
+integer inputs.
+{{< /hint >}}
+
+```yaml {label="math",copy-lines="1-7"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.numberField
+ toFieldPath: metadata.annotations["mathAnnotation"]
+ transforms:
+ - type: math
+ math:
+ ...
+```
+
+
+#### clampMin
+
+
+The {{}}type: clampMin{{ }} uses a defined
+minimum value if an input is larger than the
+{{}}type: clampMin{{ }} value.
+
+For example, this
+{{}}type: clampMin{{ }} requires an
+input to be greater than
+{{}}20{{ }}.
+
+If an input is lower than
+{{}}20{{ }}, Crossplane uses the
+{{}}clampMin{{ }} value for the
+{{}}toFieldPath{{ }}.
+
+```yaml {label="clampMin"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.numberField
+ toFieldPath: metadata.annotations["mathAnnotation"]
+ transforms:
+ - type: math
+ math:
+ type: clampMin
+ clampMin: 20
+```
+
+
+#### clampMax
+
+
+The {{}}type: clampMax{{ }} uses a defined
+minimum value if an input is larger than the
+{{}}type: clampMax{{ }} value.
+
+For example, this
+{{}}type: clampMax{{ }} requires an
+input to be less than
+{{}}5{{ }}.
+
+If an input is higher than
+{{}}5{{ }}, Crossplane uses the
+{{}}clampMax{{ }} value for the
+{{}}toFieldPath{{ }}.
+
+```yaml {label="clampMax"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.numberField
+ toFieldPath: metadata.annotations["mathAnnotation"]
+ transforms:
+ - type: math
+ math:
+ type: clampMax
+ clampMax: 5
+```
+
+
+#### Multiply
+
+
+The {{}}type: multiply{{ }} multiplies
+the input by the {{}}multiply{{ }}
+value.
+
+For example, this
+{{}}type: multiply{{ }} multiplies the
+value from the {{}}fromFieldPath{{ }}
+value by {{}}2{{ }}
+
+
+```yaml {label="multiply"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.numberField
+ toFieldPath: metadata.annotations["mathAnnotation"]
+ transforms:
+ - type: math
+ math:
+ type: multiply
+ multiply: 2
+```
+
+{{}}
+The {{}}multiply{{ }} value only
+supports integers.
+{{< /hint >}}
+
+### String transforms
+
+The {{}}string{{ }} transform applies
+string formatting or manipulation to string inputs.
+
+```yaml {label="string"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["stringAnnotation"]
+ transforms:
+ - type: string
+ string:
+ type: ...
+```
+
+String transforms support the following
+{{}}types{{ }}
+
+* [Convert](#string-convert)
+* [Format](#string-format)
+* [Regexp](#regular-expression-type)
+* [TrimPrefix](#trim-prefix)
+* [TrimSuffix](#trim-suffix)
+
+#### String convert
+
+The {{}}type: convert{{ }}
+converts the input based on one of the following conversion types:
+* `ToUpper` - Change the string to all upper case letters.
+* `ToLower` - Change the string to all lower case letters.
+* `ToBase64` - Create a new base64 string from the input.
+* `FromBase64` - Create a new text string from a base64 input.
+* `ToJson` - Convert the input string to valid JSON.
+* `ToSha1` - Create a SHA-1 hash of the input string.
+* `ToSha256` - Create a SHA-256 hash of the input string.
+* `ToSha512` - Create a SHA-512 hash of the input string.
+
+```yaml {label="stringConvert"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["FIELD1-TEXT"]
+ transforms:
+ - type: string
+ string:
+ type: Convert
+ convert: "ToUpper"
+```
+
+#### String format
+The {{}}type: format{{ }}
+applies [Go string formatting](https://pkg.go.dev/fmt) to the input.
+
+```yaml {label="typeFormat"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.field1
+ toFieldPath: metadata.annotations["stringAnnotation"]
+ transforms:
+ - type: string
+ string:
+ type: Format
+ format:
+ fmt: "the-field-%s"
+```
+
+#### Regular expression type
+The {{}}type: Regexp{{ }} extracts
+the part of the input matching a regular expression.
+
+Optionally use a
+{{}}group{{ }} to match a regular
+expression capture group.
+By default Crossplane matches the entire regular expression.
+
+```yaml {label="typeRegex"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: metadata.annotations["euRegion"]
+ transforms:
+ - type: string
+ string:
+ type: Regexp
+ regexp:
+ match: '^eu-(.*)-'
+ group: 1
+```
+
+#### Trim prefix
+
+The {{}}type: TrimPrefix{{ }} removes
+the matching string and all preceding characters.
+
+```yaml {label="typeRegex"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: metadata.annotations["north-1"]
+ transforms:
+ - type: string
+ string:
+ type: TrimPrefix
+ trim: `eu-
+```
+
+#### Trim suffix
+
+The {{}}type: TrimSuffix{{ }} removes
+the matching string and all proceeding characters.
+
+```yaml {label="typeRegex"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: metadata.annotations["eu"]
+ transforms:
+ - type: string
+ string:
+ type: TrimSuffix
+ trim: `-north-1'
+```
+
+## Patch policies
+
+Crossplane supports two types of patch policies:
+* `fromFieldPath`
+* `mergeOptions`
+
+
+### fromFieldPath policy
+
+
+Using a `fromFieldPath: Required` policy on a patch requires the
+`fromFieldPath` to exist in the composite resource.
+
+{{}}
+If a resource patch isn't working applying the `fromFieldPath: Required` policy
+may produce an error in the composite resource to help troubleshoot.
+{{< /hint >}}
+
+By default, Crossplane applies the policy `fromFieldPath: Optional`. With
+`fromFieldPath: Optional` Crossplane
+ignores a patch if the `fromFieldPath` doesn't exist.
+
+With
+{{}}fromFieldPath: Required{{ }}
+the composite resource produces an error if the
+{{}}fromFieldPath{{ }} doesn't exist.
+
+```yaml {label="required"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: metadata.annotations["eu"]
+ policy:
+ fromFieldPath: Required
+```
+
+### Merge options
+
+By default when applying a patch the destination data is overridden. Use
+{{}}mergeOptions{{ }} to allow patches to
+merge arrays and objects without overwriting them.
+
+With an array input, use
+{{}}appendSlice: true{{ }} to append the
+array data to the end of the existing array.
+
+With an object, use
+{{}}keepMapValues: true{{ }} to leave
+existing object keys in tact. The patch updates any matching keys between the
+input and destination data.
+
+```yaml {label="merge"}
+patches:
+ - type: FromCompositeFieldPath
+ fromFieldPath: spec.desiredRegion
+ toFieldPath: metadata.annotations["eu"]
+ policy:
+ mergeOptions:
+ appendSlice: true
+ keepMapValues: true
+```
diff --git a/content/v1.13/concepts/pods.md b/content/v1.13/concepts/pods.md
new file mode 100644
index 00000000..9ec5e626
--- /dev/null
+++ b/content/v1.13/concepts/pods.md
@@ -0,0 +1,381 @@
+---
+title: Crossplane Pods
+weight: 1
+description: Background on the components installed with Crossplane and their functions.
+---
+
+The base Crossplane installation consists of two pods, the `crossplane` pod and
+the `crossplane-rbac-manager` pod. Both pods install in the `crossplane-system`
+namespace by default.
+
+
+## Crossplane pod
+
+### Init container
+Before starting the core Crossplane container an _init_ container runs. The init
+container installs the core Crossplane
+[Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions)
+(`CRDs`), configures Crossplane webhooks and installs any supplied Providers or
+Configurations.
+
+{{}}
+The Kubernetes documentation contains more information about
+[init containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
+{{< /hint >}}
+
+The settings the init container sets include installing Provider or Configuration
+packages with Crossplane, customizing the namespace Crossplane installs in and
+defining webhook configurations.
+
+The core CRDs installed by the init container include:
+* CompositeResourceDefinitions, Compositions, Configurations and Providers
+* Locks to manage package dependencies
+* ControllerConfigs to apply settings to installed Providers
+* StoreConfigs for connecting external secret stores like
+[HashiCorp Vault](https://www.vaultproject.io/)
+
+{{< hint "note" >}}
+
+The [Install Crossplane]({{< ref "../software/install" >}}) section has more
+information about customizing the Crossplane install.
+{{< /hint >}}
+
+The status `Init` on the Crossplane pod is the init container running.
+
+```shell
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-9f6d5cd7b-r9j8w 0/1 Init:0/1 0 6s
+```
+
+The init container completes and starts the Crossplane core container
+automatically.
+
+```shell
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-9f6d5cd7b-r9j8w 1/1 Running 0 15s
+```
+
+### Core container
+
+The main Crossplane container, called the _core_ container, enforces
+the desired state of Crossplane resources, manages leader elections and process
+webhooks.
+
+{{}}
+The Crossplane pod only reconciles core Crossplane components, including Claims
+and composite resources. Providers are responsible for reconciling their managed
+resources.
+{{< /hint >}}
+
+#### Reconcile loop
+
+The core container operates on a _reconcile loop_, constantly checking the
+status of deployed resources and correcting any "drift." After checking a
+resource Crossplane waits some time and checks again.
+
+Crossplane monitors resources through a Kubernetes
+[_watch_](https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes)
+or through periodic polling. Some resources may be both watched and polled.
+
+Crossplane requests that the API server notifies Crossplane of any changes on
+objects. This notification tool is a _watch_.
+
+Watched objects include Providers, managed resources and
+CompositeResourceDefinitions.
+
+For objects that Kubernetes can't provide a watch for, Crossplane
+periodically poll the resource to find it's state. The default polling rate is
+one minute. Change the polling rate with the `--poll-interval` pod argument.
+
+Reducing the poll-interval value causes Crossplane to poll resources more
+frequently. This increases the load of the Crossplane pod and
+results in more frequent provider API calls.
+
+
+
+Increasing the poll-interval causes Crossplane to poll resources less
+frequently. This increases the maximum time until Crossplane
+discovers changes in the cloud provider that require updating.
+
+
+Managed resources use polling.
+
+{{< hint "note" >}}
+Managed resources watch for Kubernetes events like deletion or changes to
+their `spec`. Managed resources rely on polling to detect changes in the
+external system.
+{{< /hint >}}
+
+Crossplane double-checks all resources to
+confirm they're in the desired state. Crossplane does this every one hour by
+default. Use the `--sync-interval` Crossplane pod argument to change this
+interval.
+
+The `--max-reconcile-rate` rate defines the rate, in times per second,
+Crossplane reconciles resources.
+
+Reducing the `--max-reconcile-rate`, or making it smaller, reduces CPU
+resources Crossplane uses, but increases the amount of time until changed
+resources are fully synced.
+
+Increasing the `--max-reconcile-rate`, or making it larger, increases the
+CPU resources Crossplane uses but allows Crossplane to reconcile all resources
+faster.
+
+{{< hint "important" >}}
+Most Providers use their own `--max-reconcile-rate`. This determines the
+same settings for Providers and their managed resources. Applying the
+`--max-reconcile-rate` to Crossplane only controls the rate for
+core Crossplane resources.
+{{< /hint >}}
+##### Reconcile retry rate
+
+The `--max-reconcile-rate` setting configures the number of times per second
+Crossplane or a provider attempts to correct a resource. The default value is
+10 times per second.
+
+All core Crossplane components share the reconcile rate. Each Provider
+implements their own max reconcile rate setting.
+
+##### Number of reconcilers
+
+The second value `--max-reconcile-rate` defines is the number of
+resources that Crossplane can reconcile at once. If there are more resources than
+the configured `--max-reconcile-rate` the remaining resources must wait until
+Crossplane reconciles a an existing resource.
+
+Read the [Change Pod Settings]({{[}}) section for
+instructions on applying these settings.
+
+
+
+## RBAC manager pod
+
+The Crossplane RBAC manager pod automates required Kubernetes RBAC permissions
+for Crossplane and Crossplane Providers.
+
+{{]}}
+Crossplane installs and enables the RBAC manager by default.
+Disabling the RBAC manager requires manual Kubernetes permissions definitions
+for proper Crossplane operations.
+
+The
+[RBAC manager design document](https://github.com/crossplane/crossplane/blob/master/design/design-doc-rbac-manager.md)
+provides more comprehensive details on the Crossplane RBAC requirements.
+{{< /hint >}}
+
+### Disable the RBAC manager
+
+Disable the RBAC manager after installation by deleting the
+`crossplane-rbac-manager` deployment from the `crossplane-system` namespace.
+
+Disable the RBAC manager before installation by editing the Helm `values.yaml`
+file, setting `rbacManager.deploy` to `false`.
+
+{{< hint "note" >}}
+
+Instructions for changing Crossplane pod settings during installation are in the
+[Crossplane Install]({{[}}) section.
+{{< /hint >}}
+
+
+
+### RBAC init container
+
+
+The RBAC manager requires the `CompositeResourceDefinition` and
+`ProviderRevision` resources to be available before starting.
+
+The RBAC manager init container waits for these resources before starting the
+main RBAC manager container.
+
+### RBAC manager container
+
+The RBAC manager container preforms the following tasks:
+* creating and binding RBAC roles to Provider ServiceAccounts, allowing
+ them to control their managed resources
+* allowing the `crossplane` ServiceAccount to create managed resources
+* creating ClusterRoles to access Crossplane resources in all namespaces
+* creating Roles to access Crossplane resources in specific namespaces
+
+Use the [ClusterRoles]({{][}}) to grant access to all Crossplane resources in the
+cluster.
+Use the [Roles]({{][}}) to only grant access to Crossplane Claims.
+
+#### Crossplane ClusterRoles
+
+The RBAC manager creates four Kubernetes ClusterRoles. These Roles grant
+permissions over cluster wide Crossplane resources.
+
+
+
+
+
+##### crossplane-admin
+
+
+The `crossplane-admin` ClusterRole has the following permissions:
+ * full access to all Crossplane types
+ * full access to all secrets and namespaces (even those unrelated to Crossplane)
+ * read-only access to all cluster RBAC roles, CustomResourceDefinitions and
+ events
+ * ability to bind RBAC roles to other entities.
+
+View the full RBAC policy with
+
+```shell
+kubectl describe clusterrole crossplane:admin
+```
+
+##### crossplane-edit
+
+The `crossplane-edit` ClusterRole has the following permissions:
+
+ * full access to all Crossplane types
+ * full access to all secrets (even those unrelated to Crossplane)
+ * read-only access to all namespaces and events (even those unrelated to Crossplane).
+
+View the full RBAC policy with
+
+```shell
+kubectl describe clusterrole crossplane:edit
+```
+
+##### crossplane-view
+
+The `crossplane-view` ClusterRole has the following permissions:
+
+ * read-only access to all Crossplane types
+ * read-only access to all namespaces and events (even those unrelated to Crossplane).
+
+View the full RBAC policy with
+
+```shell
+kubectl describe clusterrole crossplane:view
+```
+
+##### crossplane-browse
+
+The `crossplane-browse` ClusterRole has the following permissions:
+
+ * read-only access to all Crossplane types
+ * read-only access to all namespaces and events (even those unrelated to Crossplane).
+
+View the full RBAC policy with
+
+```shell
+kubectl describe clusterrole crossplane:browse
+```
+
+#### Crossplane Roles
+By default the RBAC manager creates three Roles in every namespace. These Roles
+grant access to Claims in a specific namespace. The RBAC manager dynamically
+updates the Roles to access the specific API endpoints in a Claim.
+
+{{< hint "note" >}}
+The specific details of the namespace Roles are beyond this guide. For more
+information read the [Composite Resource ClusterRole
+Mechanics](https://github.com/crossplane/crossplane/blob/master/design/design-doc-rbac-manager.md#composite-resource-clusterrole-mechanics)
+section of the RBAC Manager design document.
+{{< /hint >}}
+
+You can disable these namespace specific roles by configuring the RBAC manager
+with `--manage=Basic`.
+
+
+{{< hint "note" >}}
+
+Instructions for changing Crossplane pod settings during installation are in the
+[Crossplane Install]({{][}}) section.
+{{< /hint >}}
+
+## Leader election
+
+By default only a single Crossplane pod runs in a cluster. If more than one
+Crossplane pod runs both pods try to manage Crossplane resources. To prevent
+conflicts Crossplane uses a _leader election_ to have a single pod in control at
+a time. Other Crossplane pods standby until the leader fails.
+
+{{< hint "note" >}}
+It's possible to run more than one Crossplane or RBAC manager pods for
+redundancy.
+
+Kubernetes restarts any failed Crossplane or RBAC manager pods.
+Redundant pods aren't required in most deployments.
+{{< /hint >}}
+
+Both the Crossplane pod and the RBAC manager pods support leader elections.
+
+Enable leader elections with the `--leader-election` pod argument.
+
+{{< hint "warning" >}}
+
+
+
+
+Running multiple Crossplane pods without leader election is unsupported.
+
+
+{{< /hint >}}
+
+
+## Change pod settings
+
+Change Crossplane pod settings either before installing Crossplane by editing
+the Helm `values.yml` file or after installation by editing the `Deployment`.
+
+The full list of configuration options are available in the
+[Crossplane Install]({{][}}) section.
+
+{{< hint "note" >}}
+
+Instructions for changing Crossplane pod settings during installation are in the
+[Crossplane Install]({{][}}) section.
+{{< /hint >}}
+
+### Edit the deployment
+{{< hint "note" >}}
+These settings apply to both the `crossplane` and `rbac-manager` pods and
+`Deployments`.
+{{< /hint >}}
+
+To change the settings of an installed Crossplane pod, edit the `crossplane`
+deployment in the `crossplane-system` namespace with the command
+
+`kubectl edit deployment crossplane --namespace crossplane-system`
+
+{{< hint "warning" >}}
+Updating the Crossplane deployment restarts the Crossplane pod.
+{{< /hint >}}
+
+Add Crossplane pod arguments to the
+{{]}}spec.template.spec.containers[].args{{< /hover >}}
+section of the deployment.
+
+For example, to change the `sync-interval` add
+{{}}--sync-interval=30m{{< /hover >}}.
+
+```yaml {label="args", copy-lines="1"}
+kubectl edit deployment crossplane --namespace crossplane-system
+apiVersion: apps/v1
+kind: Deployment
+spec:
+# Removed for brevity
+ template:
+ spec:
+ containers:
+ - args:
+ - core
+ - start
+ - --sync-interval=30m
+```
+
+### Use environmental variables
+
+The core Crossplane pod checks for configured environmental variables at startup
+to change default settings.
+
+The full list of configurable environmental variables are available in the
+[Crossplane Install]({{[}}) section.
diff --git a/content/v1.13/concepts/providers.md b/content/v1.13/concepts/providers.md
new file mode 100644
index 00000000..967f85d7
--- /dev/null
+++ b/content/v1.13/concepts/providers.md
@@ -0,0 +1,438 @@
+---
+title: Providers
+weight: 5
+description: "Providers connect Crossplane to external APIs"
+---
+
+Providers enable Crossplane to provision infrastructure on an
+external service. Providers create new Kubernetes APIs and map them to external
+APIs.
+
+Providers are responsible for all aspects of connecting to non-Kubernetes
+resources. This includes authentication, making external API calls and
+providing
+[Kubernetes Controller](https://kubernetes.io/docs/concepts/architecture/controller/)
+logic for any external resources.
+
+Examples of providers include:
+* [Provider AWS](https://github.com/upbound/provider-aws)
+* [Provider Azure](https://github.com/upbound/provider-azure)
+* [Provider GCP](https://github.com/upbound/provider-gcp)
+* [Provider Kubernetes](https://github.com/crossplane-contrib/provider-kubernetes)
+
+{{< hint "tip" >}}
+Find more providers in the [Upbound Marketplace](https://marketplace.upbound.io).
+{{< /hint >}}
+
+
+
+Providers define every external resource they can create in Kubernetes as a
+Kubernetes API endpoint. These endpoints are
+[_Managed Resources_]({{][}}).
+
+
+{{< hint "note" >}}
+Instructions on building your own Provider are outside of the scope of this
+document. Read the Crossplane contributing [Provider Development
+Guide](https://github.com/crossplane/crossplane/blob/master/contributing/guide-provider-development.md)
+for more information.
+{{< /hint >}}
+
+## Install a Provider
+
+Installing a provider creates a Provider pod that's responsible for installing
+the Provider's APIs into the Kubernetes cluster. Providers constantly watch the
+state of the desired managed resources and create any external resources that
+are missing.
+
+Install a Provider with a Crossplane
+{{]}}Provider{{ }} object setting the
+{{}}spec.package{{ }} value to the
+location of the provider package.
+
+For example, to install the
+[AWS Community Provider](https://github.com/crossplane-contrib/provider-aws),
+
+```yaml {label="install"}
+apiVersion: pkg.crossplane.io/v1
+kind: Provider
+metadata:
+ name: provider-aws
+spec:
+ package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.39.0
+```
+
+{{< hint "tip" >}}
+Providers are Crossplane Packages. Read more about Packages in the
+[Packages documentation]({{[}}).
+{{< /hint >}}
+
+By default, the Provider pod installs in the same namespace as Crossplane
+(`crossplane-system`).
+
+### Install with Helm
+
+Crossplane supports installing Providers during an initial Crossplane
+installation with the Crossplane Helm chart.
+
+Use the
+{{]}}--set provider.packages{{ }}
+argument with `helm install`.
+
+For example, to install the AWS Community Provider,
+
+```shell {label="helm"}
+helm install crossplane \
+crossplane-stable/crossplane \
+--namespace crossplane-system \
+--create-namespace \
+--set provider.packages={xpkg.upbound.io/crossplane-contrib/provider-aws:v0.39.0}
+```
+
+### Install from a private repository
+
+Installing a Provider from a private package repository requires a
+Kubernetes secret object. The Provider uses the secret with the
+{{}}packagePullSecrets{{ }} option.
+
+```yaml {label="pps"}
+apiVersion: pkg.crossplane.io/v1
+kind: Provider
+metadata:
+ name: private-provider
+spec:
+ package: private-repo.example.org/providers/my-provider
+ packagePullSecrets:
+ - name: my-secret
+```
+
+{{< hint "note" >}}
+The Kubernetes secret object the Provider uses must be in the same namespace as
+the Crossplane pod.
+{{< /hint >}}
+
+## Upgrade a Provider
+
+To upgrade an existing Provider edit the installed Provider Package by either
+applying a new Provider manifest or with `kubectl edit providers`.
+
+Update the version number in the Provider's `spec.package` and apply the change.
+Crossplane installs the new image and creates a new `ProviderRevision`.
+
+## Remove a Provider
+
+Remove a Provider by deleting the Provider object with `kubectl delete
+provider`.
+
+{{< hint "warning" >}}
+Removing a Provider without first removing the Provider's managed resources
+may abandon the resources. The external resources aren't deleted.
+
+If you remove the Provider first, you must manually delete external resources
+through your cloud provider. Managed resources must be manually deleted by
+removing their finalizers.
+
+For more information on deleting abandoned resources read the [Crossplane
+troubleshooting guide]({{[}}).
+{{< /hint >}}
+
+## Verify a Provider
+
+Providers install their own APIs representing the managed resources they support.
+Providers may also create Deployments, Service Accounts or RBAC configuration.
+
+View the status of a Provider with
+
+`kubectl get providers`
+
+During the install a Provider report `INSTALLED` as `True` and `HEALTHY` as
+`Unknown`.
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+crossplane-contrib-provider-aws True Unknown xpkg.upbound.io/crossplane-contrib/provider-aws:v0.39.0 63s
+```
+
+After the Provider install completes and it's ready for use the `HEALTHY` status
+reports `True`.
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+crossplane-contrib-provider-aws True True xpkg.upbound.io/crossplane-contrib/provider-aws:v0.39.0 88s
+```
+
+{{]}}
+Some Providers install hundreds of Kubernetes Custom Resource Definitions (`CRDs`).
+This can create significant strain on undersized API Servers, impacting Provider
+install times.
+
+The Crossplane community has more
+[details on scaling CRDs](https://github.com/crossplane/crossplane/blob/master/design/one-pager-crd-scaling.md).
+{{< /hint >}}
+### Provider conditions
+
+Crossplane uses a standard set of `Conditions` for Providers.
+View the conditions of a provider under their `Status` with
+`kubectl describe provider`.
+
+```yaml
+kubectl describe provider
+Name: my-provider
+API Version: pkg.crossplane.io/v1
+Kind: Provider
+# Removed for brevity
+Status:
+ Conditions:
+ Reason: HealthyPackageRevision
+ Status: True
+ Type: Healthy
+ Reason: ActivePackageRevision
+ Status: True
+ Type: Installed
+# Removed for brevity
+```
+
+#### Types
+Provider `Conditions` support two `Types`:
+* `Type: Installed` - the Provider package installed but isn't ready for use.
+* `Type: Healthy` - The Provider package is ready to use.
+
+#### Reasons
+Each `Reason` relates to a specific `Type` and `Status`. Crossplane uses the
+following `Reasons` for Provider `Conditions`.
+
+
+##### InactivePackageRevision
+`Reason: InactivePackageRevision` indicates the Provider Package is using an
+inactive Provider Package Revision.
+
+
+```yaml
+Type: Installed
+Status: False
+Reason: InactivePackageRevision
+```
+
+
+##### ActivePackageRevision
+
+The Provider Package is the current Package Revision, but Crossplane hasn't
+finished installing the Package Revision yet.
+
+{{< hint "tip" >}}
+Providers stuck in this state are because of a problem with Package Revisions.
+
+Use `kubectl describe providerrevisions` for more details.
+{{< /hint >}}
+
+```yaml
+Type: Installed
+Status: True
+Reason: ActivePackageRevision
+```
+
+
+##### HealthyPackageRevision
+The Provider is fully installed and ready to use.
+
+{{}}
+`Reason: HealthyPackageRevision` is the normal state of a working Provider.
+{{< /hint >}}
+
+
+```yaml
+Type: Healthy
+Status: True
+Reason: HealthyPackageRevision
+```
+
+
+##### UnhealthyPackageRevision
+
+
+There was an error installing the Provider Package Revision, preventing
+Crossplane from installing the Provider Package.
+
+{{}}
+Use `kubectl describe providerrevisions` for more details on why the Package
+Revision failed.
+{{< /hint >}}
+
+```yaml
+Type: Healthy
+Status: False
+Reason: UnhealthyPackageRevision
+```
+
+##### UnknownPackageRevisionHealth
+
+
+
+The status of the Provider Package Revision is `Unknown`. The Provider Package
+Revision may be installing or has an issue.
+
+{{}}
+Use `kubectl describe providerrevisions` for more details on why the Package
+Revision failed.
+{{< /hint >}}
+
+```yaml
+Type: Healthy
+Status: Unknown
+Reason: UnknownPackageRevisionHealth
+```
+
+## Configure a Provider
+
+Providers have two different types of configurations:
+* _Controller configurations_ that change the settings of the Provider pod
+ running inside the Kubernetes cluster. For example, Pod `toleration`.
+* _Provider configurations_ that change settings used when communicating with
+ an external provider. For example, cloud provider authentication.
+
+{{}}
+Apply `ControllerConfig` objects to Providers.
+
+Apply `ProviderConfig` objects to managed resources.
+{{< /hint >}}
+
+### Controller configuration
+{{< hint "important" >}}
+The Crossplane community deprecated the `ControllerConfig` type in v1.11.
+Applying a Controller configuration generates a deprecation warning.
+
+Controller configurations are still supported until there is a replacement type
+in a future Crossplane version.
+{{< /hint >}}
+
+Applying a Crossplane `ControllerConfig` to a Provider changes the settings of
+the Provider's pod. The
+[Crossplane ControllerConfig schema](https://doc.crds.dev/github.com/crossplane/crossplane/pkg.crossplane.io/ControllerConfig/v1alpha1)
+defines the supported set of ControllerConfig settings.
+
+The most common use case for ControllerConfigs are providing `args` to a
+Provider's pod enabling optional services. For example, enabling
+[external secret stores](https://docs.crossplane.io/knowledge-base/integrations/vault-as-secret-store/#enable-external-secret-stores-in-the-provider)
+for a Provider.
+
+Each Provider determines their supported set of `args`.
+
+### Provider configuration
+
+The `ProviderConfig` determines settings the Provider uses communicating to the
+external provider. Each Provider determines available settings of their
+`ProviderConfig`.
+
+
+
+Provider authentication is usually configured with a `ProviderConfig`. For
+example, to use basic key-pair authentication with Provider AWS a
+{{}}ProviderConfig{{ }}
+{{}}spec{{ }}
+defines the
+{{}}credentials{{ }} and that
+the Provider pod should look in the Kubernetes
+{{}}Secrets{{ }} objects and use
+the key named
+{{}}aws-creds{{ }}.
+
+```yaml {label="providerconfig"}
+apiVersion: aws.crossplane.io/v1beta1
+kind: ProviderConfig
+metadata:
+ name: aws-provider
+spec:
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: aws-creds
+ key: creds
+```
+
+{{< hint "important" >}}
+Authentication configuration may be different across Providers.
+
+Read the documentation on a specific Provider for instructions on configuring
+authentication for that Provider.
+{{< /hint >}}
+
+
+
+ProviderConfig objects apply to individual Managed Resources. A single
+Provider can authenticate with multiple users or accounts through
+ProviderConfigs.
+
+
+Each account's credentials tie to a unique ProviderConfig. When creating a
+managed resource, attach the desired ProviderConfig.
+
+For example, two AWS ProviderConfigs, named
+{{}}user-keys{{ }} and
+{{}}admin-keys{{ }}
+use different Kubernetes secrets.
+
+```yaml {label="user"}
+apiVersion: aws.crossplane.io/v1beta1
+kind: ProviderConfig
+metadata:
+ name: user-keys
+spec:
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: my-key
+ key: secret-key
+```
+
+```yaml {label="admin"}
+apiVersion: aws.crossplane.io/v1beta1
+kind: ProviderConfig
+metadata:
+ name: admin-keys
+spec:
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: admin-key
+ key: admin-secret-key
+```
+
+Apply the ProviderConfig when creating a managed resource.
+
+This creates an AWS {{}}Bucket{{< /hover >}}
+resource using the
+{{}}user-keys{{< /hover >}} ProviderConfig.
+
+```yaml {label="user-bucket"}
+apiVersion: s3.aws.upbound.io/v1beta1
+kind: Bucket
+metadata:
+ name: user-bucket
+spec:
+ forProvider:
+ region: us-east-2
+ providerConfigRef:
+ name: user-keys
+```
+
+This creates a second {{}}Bucket{{< /hover >}}
+resource using the
+{{}}admin-keys{{< /hover >}} ProviderConfig.
+
+```yaml {label="admin-bucket"}
+apiVersion: s3.aws.upbound.io/v1beta1
+kind: Bucket
+metadata:
+ name: user-bucket
+spec:
+ forProvider:
+ region: us-east-2
+ providerConfigRef:
+ name: admin-keys
+```
+
diff --git a/content/v1.13/getting-started/_index.md b/content/v1.13/getting-started/_index.md
new file mode 100644
index 00000000..0b0767c7
--- /dev/null
+++ b/content/v1.13/getting-started/_index.md
@@ -0,0 +1,16 @@
+---
+title: Getting Started
+weight: 4
+description: An introduction to Crossplane and Crossplane quickstart guides.
+---
+
+{{ }}
+
+## Hands-On
+Want a hands-on example? Follow a Crossplane Quickstart for your cloud provider.
+* [AWS quickstart]({{[}})
+* [Azure quickstart]({{][}})
+* [GCP quickstart]({{][}})
+
+## Install
+Ready to get started? [Install Crossplane]({{][}}) in a Kubernetes cluster.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/introduction.md b/content/v1.13/getting-started/introduction.md
new file mode 100644
index 00000000..684654e4
--- /dev/null
+++ b/content/v1.13/getting-started/introduction.md
@@ -0,0 +1,488 @@
+---
+title: Crossplane Introduction
+weight: 2
+---
+
+Crossplane connects your Kubernetes cluster to external,
+non-Kubernetes resources, and allows platform teams to build custom Kubernetes
+APIs to consume those resources.
+
+
+Crossplane creates Kubernetes
+[Custom Resource Definitions](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/)
+(`CRDs`) to represent the external resources as native
+[Kubernetes objects](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/).
+As native Kubernetes objects, you can use standard commands like `kubectl create`
+and `kubectl describe`. The full
+[Kubernetes API](https://kubernetes.io/docs/reference/using-api/) is available
+for every Crossplane resource.
+
+
+Crossplane also acts as a
+[Kubernetes Controller](https://kubernetes.io/docs/concepts/architecture/controller/)
+to watch the state of the external resources and provide state enforcement. If
+something modifies or deletes a resource outside of Kubernetes, Crossplane reverses
+the change or recreates the deleted resource.
+
+{{] }}
+With Crossplane installed in a Kubernetes cluster, users only communicate with
+Kubernetes. Crossplane manages the communication to external resources like AWS,
+Azure or Google Cloud.
+
+Crossplane also allows the creation of custom Kubernetes APIs. Platform teams can
+combine external resources and simplify or customize the APIs presented to the
+platform consumers.
+
+## Crossplane components overview
+This table provides a summary of Crossplane components and their roles.
+
+{{< table "table table-hover table-sm">}}
+| Component | Abbreviation | Scope | Summary |
+| --- | --- | --- | ---- |
+| [Provider]({{[}}) | | cluster | Creates new Kubernetes Custom Resource Definitions for an external service. |
+| [ProviderConfig]({{][}}) | `PC` | cluster | Applies settings for a _Provider_. |
+| [Managed Resource]({{][}}) | `MR` | cluster | A Provider resource created and managed by Crossplane inside the Kubernetes cluster. |
+| [Composition]({{][}}) | | cluster | A template for creating multiple _managed resources_ at once. |
+| [Composite Resources]({{][}}) | `XR` | cluster | Uses a _Composition_ template to create multiple _managed resources_ as a single Kubernetes object. |
+| [CompositeResourceDefinitions]({{][}}) | `XRD` | cluster | Defines the API schema for _Composite Resources_ and _Claims_ |
+| [Claims]({{][}}) | `XC` | namespace | Like a _Composite Resource_, but namespace scoped. |
+{{< /table >}}
+
+## The Crossplane Pod
+When installed in a Kubernetes cluster Crossplane creates an initial set of
+Custom Resource Definitions (`CRDs`) of the core Crossplane components.
+
+{{< expand "View the initial Crossplane CRDs" >}}
+After installing Crossplane use `kubectl get crds` to view the Crossplane
+installed CRDs.
+
+```shell
+kubectl get crds
+NAME
+compositeresourcedefinitions.apiextensions.crossplane.io
+compositionrevisions.apiextensions.crossplane.io
+compositions.apiextensions.crossplane.io
+configurationrevisions.pkg.crossplane.io
+configurations.pkg.crossplane.io
+controllerconfigs.pkg.crossplane.io
+locks.pkg.crossplane.io
+providerrevisions.pkg.crossplane.io
+providers.pkg.crossplane.io
+storeconfigs.secrets.crossplane.io
+```
+{{< /expand >}}
+
+The following sections describe the functions of some of these CRDs.
+
+## Providers
+A Crossplane _Provider_ creates a second set of CRDs that define how Crossplane
+connects to a non-Kubernetes service. Each external service relies on its own
+Provider. For example,
+[AWS](https://marketplace.upbound.io/providers/upbound/provider-aws),
+[Azure](https://marketplace.upbound.io/providers/upbound/provider-azure)
+and [GCP](https://marketplace.upbound.io/providers/upbound/provider-gcp)
+are different providers for each cloud service.
+
+{{< hint "tip" >}}
+Most Providers are for cloud services but Crossplane can use a Provider to
+connect to any service with an API.
+{{< /hint >}}
+
+For example, an AWS Provider defines Kubernetes CRDs for AWS resources like EC2
+compute instances or S3 storage buckets.
+
+The Provider defines the Kubernetes API definition for the external resource.
+For example, the
+[Upbound Provider AWS](https://marketplace.upbound.io/providers/upbound/provider-aws/)
+defines a
+[`bucket`](https://marketplace.upbound.io/providers/upbound/provider-aws/v0.25.0/resources/s3.aws.upbound.io/Bucket/v1beta1)
+resource for creating and managing AWS S3 storage buckets.
+
+Within the `bucket` CRD is a
+[`spec.forProvider.region`](https://marketplace.upbound.io/providers/upbound/provider-aws/v0.25.0/resources/s3.aws.upbound.io/Bucket/v1beta1#doc:spec-forProvider-region)
+value that defines which AWS region to deploy the bucket in.
+
+The Upbound Marketplace contains a large
+[collection of Crossplane Providers](https://marketplace.upbound.io/providers).
+
+More providers are available in the [Crossplane Contrib repository](https://github.com/crossplane-contrib/).
+
+Providers are cluster scoped and available to all cluster namespaces.
+
+View all installed Providers with the command `kubectl get providers`.
+
+## Provider configurations
+Providers have _ProviderConfigs_. _ProviderConfigs_ configure settings
+related to the Provider like authentication or global defaults for the
+Provider.
+
+The API endpoints for ProviderConfigs are unique to each Provider.
+
+_ProviderConfigs_ are cluster scoped and available to all cluster namespaces.
+
+View all installed ProviderConfigs with the command `kubectl get providerconfig`.
+
+## Managed resources
+A Provider's CRDs map to individual _resources_ inside the provider. When
+Crossplane creates and monitors a resource it's a _Managed Resource_.
+
+Using a Provider's CRD creates a unique _Managed Resource_. For example,
+using the Provider AWS's `bucket` CRD, Crossplane creates a `bucket` _Managed Resource_
+inside the Kubernetes cluster that's connected to an AWS S3 storage bucket.
+
+The Crossplane controller provides state enforcement for _Managed Resources_.
+Crossplane enforces the settings and existence of _Managed Resources_. This
+"Controller Pattern" is like how the Kubernetes
+[kube-controller-manager](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/)
+enforces state for pods.
+
+_Managed Resources_ are cluster scoped and available to all cluster namespaces.
+
+Use `kubectl get managed` to view all _managed resources_.
+{{]}}
+The `kubectl get managed` creates a lot of Kubernetes API queries.
+Both the `kubectl` client and kube-apiserver throttle the API queries.
+
+Depending on the size of the API server and number of managed resources, this
+command may take minutes to return or may timeout.
+
+For more information, read
+[Kubernetes issue
+#111880](https://github.com/kubernetes/kubernetes/issues/111880)
+and
+[Crossplane issue #3459](https://github.com/crossplane/crossplane/issues/3459).
+{{< /hint >}}
+
+## Compositions
+
+A _Composition_ is a template for a collection of _managed resource_. _Compositions_
+allow platform teams to define a set of _managed resources_ as a
+single object.
+
+For example, a compute _managed resource_ may require the creation of a storage
+resource and a virtual network as well. A single _Composition_ can define all three
+resources in a single _Composition_ object.
+
+Using _Compositions_ simplifies the deployment of infrastructure made up of
+multiple _managed resources_. _Compositions_ also enforce standards and settings
+across deployments.
+
+Platform teams can define fixed or default settings for each _managed resource_ inside a
+_Composition_ or define fields and settings that users may change.
+
+Using the previous example, the platform team may set a compute resource size
+and virtual network settings. But the platform team allows users to define the
+storage resource size.
+
+Creating a _Composition_ Crossplane doesn't create any managed
+resources. The _Composition_ is only a template for a collection of _managed
+resources_ and their settings. A _Composite Resource_ creates the specific resources.
+
+{{< hint "note" >}}
+The [_Composite Resources_]({{[}})_ section discusses
+_Composite Resources_.
+{{< /hint >}}
+
+_Compositions_ are cluster scoped and available to all cluster namespaces.
+
+Use `kubectl get compositions` to view all _compositions_.
+
+
+ ## Composite Resources
+
+A _Composite Resource_ (`XR`) is a set of provisioned _managed resources_. A
+_Composite Resource_ uses the template defined by a _Composition_ and applies
+any user defined settings.
+
+Multiple unique _Composite Resource_ objects can use the same _Composition_. For
+example, a _Composition_ template can create a compute, storage and networking
+set of _managed resources_. Crossplane uses the same _Composition_ template
+every time a user requests this set of resources.
+
+If a _Composition_ allows a user to define resource settings, users apply them
+in a _Composite Resource_.
+
+
+
+
+{{< hint "tip" >}}
+_Compositions_ are templates for a set of _managed resources_.
+_Composite Resources_ fill out the template and create _managed resources_.
+
+Deleting a _Composite Resource_ deletes all the _managed resources_ it created.
+{{< /hint >}}
+
+_Composite Resources_ are cluster scoped and available to all cluster namespaces.
+
+Use `kubectl get composite` to view all _Composite Resources_.
+
+## Composite Resource Definitions
+_Composite Resource Definitions_ (`XRDs`) create custom Kubernetes APIs used by
+_Claims_ and _Composite Resources_.
+
+{{< hint "note" >}}
+The [_Claims_]({{][}}) section discusses
+_Claims_.
+{{< /hint >}}
+
+Platform teams define the custom APIs.
+These APIs can define specific values
+like storage space in gigabytes, generic settings like `small` or `large`,
+deployment options like `cloud` or `onprem`. Crossplane doesn't limit the API definitions.
+
+The _Composite Resource Definition's_ `kind` is from Crossplane.
+```yaml
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+```
+
+The `spec` of a _Composite Resource Definition_ creates the `apiVersion`,
+`kind` and `spec` of a _Composite Resource_.
+
+{{< hint "tip" >}}
+The _Composite Resource Definition_ defines the parameters for a _Composite
+Resource_.
+{{< /hint >}}
+
+A _Composite Resource Definition_ has four main `spec` parameters:
+* A {{]}}group{{< /hover >}}
+to define the
+{{< hover label="xr2" line="2" >}}apiVersion{{ }}
+in a _Composite Resource_ .
+* The {{< hover label="specGroup" line="7" >}}versions.name{{ }}
+that defines the version used in a _Composite Resource_.
+* A {{< hover label="specGroup" line="5" >}}names.kind{{ }}
+to define the _Composite Resource_
+{{< hover label="xr2" line="3" >}}kind{{ }}.
+* A {{< hover label="specGroup" line="8" >}}versions.schema{{ }} section
+to define the _Composite Resource_ {{}}spec{{ }}.
+
+```yaml {label="specGroup"}
+# Composite Resource Definition (XRD)
+spec:
+ group: test.example.org
+ names:
+ kind: myComputeResource
+ versions:
+ - name: v1alpha1
+ schema:
+ # Removed for brevity
+```
+
+A _Composite Resource_ based on this _Composite Resource Definition_ looks like this:
+
+```yaml {label="xr2"}
+# Composite Resource (XR)
+apiVersion: test.example.org/v1alpha1
+kind: myComputeResource
+metadata:
+ name: myResource
+spec:
+ storage: "large"
+```
+
+A _Composite Resource Definition_ {{< hover label="specGroup" line="8" >}}schema{{ }} defines the _Composite Resource_
+{{}}spec{{ }} parameters.
+
+These parameters are the new, custom APIs, that developers can use.
+
+For example, creating a compute _managed resource_ requires knowledge of a
+cloud provider's compute class names like AWS's `m6in.large` or GCP's
+`e2-standard-2`.
+
+A _Composite Resource Definition_ can limit the choices to `small` or `large`.
+A _Composite Resource_ uses those options and the _Composition_ maps them
+to specific cloud provider settings.
+
+The following _Composite Resource Definition_ defines a {{}}storage{{< /hover >}}
+parameter. The storage is a
+{{}}string{{< /hover >}}
+and the OpenAPI
+{{}}oneOf{{< /hover >}} requires the
+options to be either {{}}small{{< /hover >}}
+or {{}}large{{< /hover >}}.
+
+```yaml {label="specVersions"}
+# Composite Resource Definition (XRD)
+spec:
+ group: test.example.org
+ names:
+ kind: myComputeResource
+ versions:
+ - name: v1alpha1
+ served: true
+ referenceable: true
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ storage:
+ type: string
+ oneOf:
+ - pattern: '^small$'
+ - pattern: '^large$'
+ required:
+ - storage
+```
+
+A _Composite Resource Definition_ can define a wide variety of settings and options.
+
+Creating a _Composite Resource Definition_ enables the creation of _Composite
+Resources_ but can also create a _Claim_.
+
+_Composite Resource Definitions_ with a `spec.claimNames` allow developers to
+create _Claims_.
+
+For example, the
+{{< hover label="xrdClaim" line="6" >}}claimNames.kind{{ }}
+allows the creation of _Claims_ of `kind: computeClaim`.
+```yaml {label="xrdClaim"}
+# Composite Resource Definition (XRD)
+spec:
+ group: test.example.org
+ names:
+ kind: myComputeResource
+ claimNames:
+ kind: computeClaim
+ # Removed for brevity
+```
+
+## Claims
+_Claims_ are the primary way developers interact with Crossplane.
+
+_Claims_ access the custom APIs defined by the platform team in a _Composite
+Resource Definition_.
+
+_Claims_ look like _Composite Resources_, but they're namespace scoped,
+while _Composite Resources_ are cluster scoped.
+
+{{< hint "note" >}}
+**Why does namespace scope matter?**
+Having namespace scoped _Claims_ allows multiple teams, using unique namespaces,
+to create the same types of resources, independent of each other. The compute
+resources of team A are unique to the compute resources of team B.
+
+Directly creating _Composite Resources_ requires cluster-wide permissions,
+shared with all teams.
+_Claims_ create the same set of resources, but on a namespace level.
+{{< /hint >}}
+
+The previous _Composite Resource Definition_ allows the creation of _Claims_
+of the kind
+{{}}computeClaim{{ }}.
+
+Claims use the same
+{{< hover label="xrdClaim2" line="3" >}}apiVersion{{< /hover >}}
+defined in _Composite Resource Definition_ and also used by
+_Composite Resources_.
+```yaml {label="xrdClaim2"}
+# Composite Resource Definition (XRD)
+spec:
+ group: test.example.org
+ names:
+ kind: myComputeResource
+ claimNames:
+ kind: computeClaim
+ # Removed for brevity
+```
+
+In an example _Claim_ the
+{{}}apiVersion{{< /hover >}}
+matches the {{}}group{{< /hover >}} in the
+_Composite Resource Definition_.
+
+The _Claim_ {{}}kind{{< /hover >}} matches the
+_Composite Resource Definition_
+{{}}claimNames.kind{{< /hover >}}.
+
+```yaml {label="claim"}
+# Claim
+apiVersion: test.example.org/v1alpha1
+kind: computeClaim
+metadata:
+ name: myClaim
+ namespace: devGroup
+spec:
+ size: "large"
+```
+
+A _Claim_ can install in a {{}}namespace{{ }}.
+The _Composite Resource Definition_ defines the
+{{}}spec{{< /hover >}} options the same way it
+does for a _Composite Resource_
+{{}}spec{{< /hover >}}.
+
+{{< hint "tip" >}}
+_Composite Resources_ and _Claims_ are similar.
+Only _Claims_ can be in
+a {{}}namespace{{ }}.
+Also the _Composite Resource's_ {{}}kind{{ }} may be different than the _Claim's_
+{{}}kind{{< /hover >}}.
+The _Composite Resource Definition_ defines the
+{{}}kind{{ }} values.
+{{< /hint >}}
+
+```yaml {label="xr-claim"}
+# Composite Resource (XR)
+apiVersion: test.example.org/v1alpha1
+kind: myComputeResource
+metadata:
+ name: myResource
+spec:
+ storage: "large"
+```
+
+_Claims_ are namespace scoped.
+
+View all available Claims with the command `kubectl get claim`.
+
+## Next steps
+Build your own Crossplane platform using one of the quickstart guides.
+* [Azure Quickstart]({{[}})
+* [AWS Quickstart]({{][}})
+* [GCP Quickstart]({{][}})
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-aws-part-2.md b/content/v1.13/getting-started/provider-aws-part-2.md
new file mode 100644
index 00000000..e604ba6d
--- /dev/null
+++ b/content/v1.13/getting-started/provider-aws-part-2.md
@@ -0,0 +1,930 @@
+---
+title: AWS Quickstart Part 2
+weight: 120
+tocHidden: true
+---
+
+{{< hint "important" >}}
+This guide is part 2 of a series. Follow [**part 1**]({{][}})**
+to install Crossplane and connect your Kubernetes cluster to AWS.
+
+[**Part 3**]({{][}})** covers patching _composite resources_
+and using Crossplane _packages_.
+{{< /hint >}}
+
+
+This section creates a _[Composition](#create-a-composition)_,
+_[Composite Resource Definition](#define-a-composite-resource)_ and a
+_[Claim](#create-a-claim)_
+to create a custom Kubernetes API to create AWS resources.
+
+
+## Prerequisites
+* Complete [quickstart part 1]({{][}}) connecting Kubernetes
+ to AWS.
+* an AWS account with permissions to create an AWS S3 storage bucket and a
+DynamoDB instance
+
+{{]}}
+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 <
+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 <}}
+
+## Create a composition
+[Part 1]({{[}}) created a single _managed resource_.
+A _Composition_ is a template to create multiple _managed resources_ at the same time.
+
+This sample _composition_ creates an DynamoDB instance and associated S3 storage
+bucket.
+
+{{< hint "note" >}}
+This example comes from the AWS recommendation for
+[storing large DynamoDB attributes in S3](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-use-s3-too.html#bp-use-s3-too-large-values).
+{{< /hint >}}
+
+To create a _composition_, first define each individual managed resource.
+
+### Create an S3 bucket object
+Define a `bucket` resource using the configuration from the previous section:
+
+```yaml
+apiVersion: s3.aws.upbound.io/v1beta1
+kind: Bucket
+metadata:
+ name: crossplane-quickstart-bucket
+spec:
+ forProvider:
+ region: "us-east-2"
+ providerConfigRef:
+ name: default
+```
+
+### Create a DynamoDB table resource
+Next, define a DynamoDB `table` resource.
+
+{{< hint "tip" >}}
+The [Upbound Marketplace](https://marketplace.upbound.io/) provides
+[schema documentation](https://marketplace.upbound.io/providers/upbound/provider-aws/v0.27.0/resources/dynamodb.aws.upbound.io/Table/v1beta1) for a `Table` resource.
+{{< /hint >}}
+
+The _AWS Provider_ defines the
+{{]}}apiVersion{{ }}
+and
+{{}}kind{{ }}.
+
+DynamoDB instances require a
+{{}}region{{ }},
+{{}}writeCapacity{{ }}
+and
+{{}}readCapacity{{ }}
+parameters.
+
+The {{}}attribute{{ }} section creates
+the database "Partition key" and "Hash key."
+
+This example creates a single key named
+{{}}S3ID{{ }} of type
+{{}}S{{ }} for "string"
+```yaml {label="dynamoMR"}
+apiVersion: dynamodb.aws.upbound.io/v1beta1
+kind: Table
+metadata:
+ name: crossplane-quickstart-database
+spec:
+ forProvider:
+ region: "us-east-2"
+ writeCapacity: 1
+ readCapacity: 1
+ attribute:
+ - name: S3ID
+ type: S
+ hashKey: S3ID
+```
+
+{{< hint "note" >}}
+DynamoDB specifics are beyond the scope of this guide. Read the
+[DynamoDB Developer Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)
+for more information.
+{{ }}
+
+### Create the composition object
+The _composition_ combines the two resource definitions.
+
+A
+{{}}Composition{{ hover>}} comes from the
+{{}}Crossplane{{ hover>}}
+API resources.
+
+Create any {{}}name{{ hover>}} for this _composition_.
+
+```yaml {label="compName"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: dynamoDBWithS3
+```
+
+Add the resources to the
+{{}}spec.resources{{ hover>}}
+section of the _composition_.
+
+Give each resource a
+{{}}name{{ hover>}}
+and put the resource definition under the
+{{}}base{{ hover>}}
+key.
+
+```yaml {label="specResources"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: dynamoDBWithS3
+spec:
+ resources:
+ - name: s3Bucket
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ metadata:
+ name: crossplane-quickstart-bucket
+ spec:
+ forProvider:
+ region: "us-east-2"
+ providerConfigRef:
+ name: default
+ - name: dynamoDB
+ base:
+ apiVersion: dynamodb.aws.upbound.io/v1beta1
+ kind: Table
+ metadata:
+ name: crossplane-quickstart-database
+ spec:
+ forProvider:
+ region: "us-east-2"
+ writeCapacity: 1
+ readCapacity: 1
+ attribute:
+ - name: S3ID
+ type: S
+ hashKey: S3ID
+```
+
+Put the entire resource definition including the
+{{}}apiVersion{{ hover>}} and resource
+settings under the
+{{}}base{{ hover>}}.
+
+_Compositions_ are only a template for generating resources. A _composite
+resource_ actually creates the resources.
+
+A _composition_ defines what _composite resources_ can use this
+template.
+
+_Compositions_ do this with the
+{{}}spec.compositeTypeRef{{ hover>}}
+definition.
+
+```yaml {label="compRef"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: dynamodb-with-bucket
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: database
+ resources:
+ # Removed for Brevity
+```
+
+A _composite resource_ is actually a custom Kubernetes API type you define. The
+platform team controls the kind, API endpoint and version.
+
+
+
+With this {{}}spec.compositeTypeRef{{ hover>}}
+Crossplane only allows _composite resources_ from the API group
+{{}}custom-api.example.org{{ hover>}}
+that are of
+{{}}kind: database{{ hover>}}
+to use this template to create resources.
+
+
+### Apply the composition
+Apply the full _Composition_ to your Kubernetes cluster.
+
+```yaml
+cat <}}
+_Composite resource definitions_ are also called `XRDs` for short.
+{{< /hint >}}
+
+Just like a _composition_ the
+{{}}composite resource definition{{ }}
+is part of the
+{{}}Crossplane{{ }}
+API group.
+
+The _XRD_ {{}}name{{ }} is the new
+API endpoint.
+
+```yaml {label="xrdName"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: databases.custom-api.example.org
+```
+
+The _XRD's_
+{{}}spec{{ }} defines the new custom
+API.
+
+### Define the API endpoint and kind
+First, define the new API
+{{}}group{{ }}.
+Next, create the API {{}}kind{{ }} and
+{{}}plural{{ }}.
+
+```yaml {label="xrdGroup"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: databases.custom-api.example.org
+spec:
+ group: custom-api.example.org
+ names:
+ kind: database
+ plural: databases
+```
+
+{{}}
+The _XRD_ {{}}group{{ }} matches the _composition_ {{}}apiVersion{{ }} and the
+_XRD_ {{}}kind{{ }} matches the _composition_
+{{}}kind{{ }} under the {{}}compositeTypeRef{{ }}.
+
+```yaml {label="noteComp"}
+kind: Composition
+# Removed for brevity
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: database
+```
+{{< /hint >}}
+
+### Set the API version
+In Kubernetes, all API endpoints have a version to tell the stability of the API
+and track revisions.
+
+Apply a version to the _XRD_ with a
+{{}}versions.name{{ }}.
+This matches the {{}}apiVersion{{ }} used in the _composition's_
+{{}}compositeTypeRef{{ }}.
+
+_XRDs_ require both
+{{}}versions.served{{ }}
+and
+{{}}versions.referenceable{{ }}.
+
+```yaml {label="xrdVersion"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: custom-api-definition
+spec:
+ group: custom-api.example.org
+ names:
+ kind: database
+ plural: databases
+ versions:
+ - name: v1alpha1
+ served: true
+ referenceable: true
+```
+
+{{}}
+For more information on defining versions in Kubernetes read the
+[API versioning](https://kubernetes.io/docs/reference/using-api/#api-versioning) section of the Kubernetes documentation.
+{{< /hint >}}
+
+### Create the API schema
+With an API endpoint named, now define the API schema, or what's allowed
+inside the `spec` of the new Kubernetes object.
+
+{{< hint "note" >}}
+_XRDs_ follow the Kubernetes
+[_custom resource definition_ rules for schemas](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
+{{ }}
+
+Place the API
+{{< hover label="xrdSchema" line="8" >}}schema{{ }}
+under the
+{{< hover label="xrdSchema" line="7" >}}version.name{{ }}
+
+The _XRD_ type defines the next lines. They're always the same.
+
+
+
+{{< hover label="xrdSchema" line="9" >}}openAPIV3Schema{{ }} specifies
+how the schema gets validated.
+
+
+Next, the entire API is an
+{{< hover label="xrdSchema" line="10" >}}object{{ }}
+with a
+{{< hover label="xrdSchema" line="11" >}}property{{ }} of
+{{< hover label="xrdSchema" line="12" >}}spec{{ }}.
+
+The
+{{< hover label="xrdSchema" line="12" >}}spec{{ }} is also an
+{{< hover label="xrdSchema" line="13" >}}object{{ }} with
+{{< hover label="xrdSchema" line="14" >}}properties{{ }}.
+
+```yaml {label="xrdSchema"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+ # Removed for brevity
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+```
+
+{{< hint "tip" >}}
+An _XRD_ is a Kubernetes _custom resource definition_.
+For more information on the values allowed in the _XRD_ view the _XRD_ object with
+`kubectl describe crd compositeresourcedefinitions`
+{{< /hint >}}
+
+Now, define the custom API. Your custom API continues under the last
+{{}}properties{{ }} definition in the
+previous example.
+
+This custom API has only one setting:
+
+* {{}}region{{ }} - where to deploy
+the resources, a choice of "EU" or "US"
+
+
+Users can't change any other settings of the S3 bucket or DynamoDB instance.
+
+The{{}}region{{ }}
+is a {{}}string{{ }}
+and can match the regular expression that's
+{{}}oneOf{{ }}
+{{}}EU{{ }}
+or
+{{}}US{{ }}.
+
+This API requires the setting
+{{}}region{{ }}.
+
+
+```yaml {label="customAPI"}
+# Removed for brevity
+# schema.openAPIV3Schema.type.properties.spec
+properties:
+ region:
+ type: string
+ oneOf:
+ - pattern: '^EU$'
+ - pattern: '^US$'
+required:
+ - region
+```
+
+### Enable claims to the API
+Allow a _claim_ to use this _XRD_ by defining the _claim_ API endpoint under the _XRD_
+{{}}spec{{< /hover >}}.
+
+```yaml {label="XRDclaim"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ claimNames:
+ kind: customDatabase
+ plural: customDatabases
+```
+
+{{}}
+The [Claims](#create-a-claim) section later in this guide discusses _claims_.
+{{< /hint >}}
+
+### Apply the composite resource definition
+Apply the complete _XRD_ to your Kubernetes cluster.
+
+
+```yaml
+cat <}}group{{ }}
+becomes the _composite resource_
+{{}}apiVersion{{ }}.
+
+The _XRD_ {{}}kind{{ }}
+is the _composite resource_
+{{}}kind{{ }}
+
+The _XRD_ API {{}}spec{{ }} defines the
+_composite resource_ {{}}spec{{ }}.
+
+The _XRD_ {{}}properties{{ }} section
+defines the options for the _composite resource_
+{{}}spec{{ }}.
+
+The one option is {{}}region{{ }} and it
+can be either {{}}EU{{ }} or
+{{}}US{{ }}.
+
+This _composite resource_ uses
+{{}}region: US{{ }}.
+
+### Apply the composite resource
+
+Apply the composite resource to the Kubernetes cluster.
+
+```yaml {label="xr"}
+cat <}}
+There may a delay in deleting the _managed resources_. Crossplane is making API
+calls to AWS and waits for AWS to confirm they deleted the resources before
+updating the state in Kubernetes.
+{{ }}
+
+Now only one bucket and table exist.
+
+```shell {copy-lines="1"}
+kubectl get bucket
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-8b6tx True True my-composite-resource-8b6tx 7m34s
+```
+
+```shell {copy-lines="1"}
+kubectl get table
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-m6vk6 True True my-composite-resource-m6vk6 7m37s
+```
+
+Delete the second _composite resource_ to remove the last `bucket` and `table`
+_managed resources_.
+
+```shell
+kubectl delete composite my-composite-resource
+```
+
+_Composite resources_ are great for creating multiple related resources against
+a template, but all _composite resources_ exist at the Kubernetes "cluster
+level." There's no isolation between _composite resources_. Crossplane uses
+_claims_ to create resources with namespace isolation.
+
+## Create a claim
+
+_Claims_, just like _composite resources_ use the custom API defined in the
+_XRD_. Unlike a _composite resource_, Crossplane can create _claims_ in a
+namespace.
+
+### Create a new Kubernetes namespace
+Create a new namespace with `kubectl create namespace`.
+
+```shell
+kubectl create namespace test
+```
+
+A _claim_ uses the same {{}}group{{ }}
+a _composite resource_ uses but a different
+{{}}kind{{ }}.
+
+```yaml {label="XRDclaim2"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ group: custom-api.example.org
+ claimNames:
+ kind: custom-database
+ plural: custom-databases
+```
+
+Like the _composite resource_, create a new object with the
+{{}}custom-api.example.org{{ }} API
+endpoint.
+
+The _XRD_
+{{}}ClaimNames.kind{{ }} defines the
+{{}}kind{{ }}.
+
+The {{}}spec{{ }} uses the same
+API options as the _composite resource_.
+
+### Apply the claim
+Apply the _claim_ to your Kubernetes cluster.
+
+```yaml {label="claim"}
+cat <}}) of this guide covers _composition
+patches_ and making all this configuration portable in Crossplane _packages_.
+
+## Next steps
+* [**Continue to part 3**]({{< ref "provider-aws-part-3">}}) to create a learn
+ about _patching_ resources and creating Crossplane _packages_.
+* 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.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-aws-part-3.md b/content/v1.13/getting-started/provider-aws-part-3.md
new file mode 100644
index 00000000..47f14649
--- /dev/null
+++ b/content/v1.13/getting-started/provider-aws-part-3.md
@@ -0,0 +1,652 @@
+---
+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 <
+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 _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: s3Bucket
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ metadata:
+ name: crossplane-quickstart-bucket
+ spec:
+ forProvider:
+ region: "us-east-2"
+ - name: dynamoDB
+ base:
+ apiVersion: dynamodb.aws.upbound.io/v1beta1
+ kind: Table
+ metadata:
+ name: crossplane-quickstart-database
+ 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: database
+# 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: s3Bucket
+ 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 claim 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: databases.custom-api.example.org
+spec:
+ group: custom-api.example.org
+ names:
+ kind: database
+ plural: databases
+ 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: custom-database
+ plural: custom-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: dynamo-with-bucket
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: database
+ resources:
+ - name: s3Bucket
+ base:
+ apiVersion: s3.aws.upbound.io/v1beta1
+ kind: Bucket
+ metadata:
+ name: crossplane-quickstart-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
+ metadata:
+ name: crossplane-quickstart-database
+ 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
+curl "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh"
+./install.sh
+sudo mv kubectl-crossplane /usr/bin
+```
+
+Verify the Crossplane command-line installed with `kubectl crossplane --help`
+
+```shell
+kubectl crossplane --help
+Usage: kubectl 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 `kubectl crossplane` command to create an `.xpkg` file containing the
+custom APIs and Crossplane configuration.
+
+```shell
+kubectl 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]({{[}})
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-aws.md b/content/v1.13/getting-started/provider-aws.md
new file mode 100644
index 00000000..e5e47a41
--- /dev/null
+++ b/content/v1.13/getting-started/provider-aws.md
@@ -0,0 +1,1212 @@
+---
+title: AWS Quickstart
+weight: 100
+---
+
+Connect Crossplane to AWS to create and manage cloud resources from Kubernetes with the [Upbound AWS Provider](https://marketplace.upbound.io/providers/upbound/provider-aws).
+
+This guide is in three parts:
+* Part 1 walks through installing Crossplane, configuring the provider to
+authenticate to AWS and creating a _Managed Resource_ in AWS directly from your
+Kubernetes cluster. This shows Crossplane can communicate with AWS.
+* [Part 2]({{< ref "provider-aws-part-2" >}}) creates a
+_Composite Resource Definition_ (XRD), _Composite Resource_ (XR) and a _Claim_
+(XRC) to show how to create and use custom APIs.
+* [Part 3]({{< ref "provider-aws-part-3" >}}) demonstrates how to patch
+_Compositions_ with values used in a _Claim_ and how to build a Crossplane
+_Package_.
+
+## Prerequisites
+This quickstart requires:
+* a Kubernetes cluster with at least 6 GB of RAM
+* permissions to create pods and secrets in the Kubernetes cluster
+* [Helm](https://helm.sh/) version v3.2.0 or later
+* an AWS account with permissions to create an S3 storage bucket
+* AWS [access keys](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-creds)
+
+## Install Crossplane
+
+Crossplane installs into an existing Kubernetes cluster.
+
+{{< hint type="tip" >}}
+If you don't have a Kubernetes cluster create one locally with [Kind](https://kind.sigs.k8s.io/).
+{{< /hint >}}
+
+
+### Install the Crossplane Helm chart
+
+Helm enables Crossplane to install all its Kubernetes components through a _Helm Chart_.
+
+Enable the Crossplane Helm Chart repository:
+
+```shell
+helm repo add \
+crossplane-stable https://charts.crossplane.io/stable
+helm repo update
+```
+
+Run the Helm dry-run to see all the Crossplane components Helm installs.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+```
+{{]}}
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+install.go:193: [debug] Original chart version: ""
+install.go:210: [debug] CHART PATH: /home/vagrant/.cache/helm/repository/crossplane-1.10.1.tgz
+
+NAME: crossplane
+LAST DEPLOYED: Thu Jan 19 15:52:08 2023
+NAMESPACE: crossplane-system
+STATUS: pending-install
+REVISION: 1
+TEST SUITE: None
+USER-SUPPLIED VALUES:
+{}
+
+COMPUTED VALUES:
+affinity: {}
+args: {}
+configuration:
+ packages: []
+customAnnotations: {}
+customLabels: {}
+deploymentStrategy: RollingUpdate
+extraEnvVarsCrossplane: {}
+extraEnvVarsRBACManager: {}
+image:
+ pullPolicy: IfNotPresent
+ repository: crossplane/crossplane
+ tag: v1.10.1
+imagePullSecrets: {}
+leaderElection: true
+metrics:
+ enabled: false
+nodeSelector: {}
+packageCache:
+ medium: ""
+ pvc: ""
+ sizeLimit: 5Mi
+podSecurityContextCrossplane: {}
+podSecurityContextRBACManager: {}
+priorityClassName: ""
+provider:
+ packages: []
+rbacManager:
+ affinity: {}
+ args: {}
+ deploy: true
+ leaderElection: true
+ managementPolicy: All
+ nodeSelector: {}
+ replicas: 1
+ skipAggregatedClusterRoles: false
+ tolerations: {}
+registryCaBundleConfig: {}
+replicas: 1
+resourcesCrossplane:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+resourcesRBACManager:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+securityContextCrossplane:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+securityContextRBACManager:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+serviceAccount:
+ customAnnotations: {}
+tolerations: {}
+webhooks:
+ enabled: false
+
+HOOKS:
+MANIFEST:
+---
+# Source: crossplane/templates/rbac-manager-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:system:aggregate-to-crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ crossplane.io/scope: "system"
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ - services
+ verbs:
+ - "*"
+- apiGroups:
+ - apiextensions.crossplane.io
+ - pkg.crossplane.io
+ - secrets.crossplane.io
+ resources:
+ - "*"
+ verbs:
+ - "*"
+- apiGroups:
+ - extensions
+ - apps
+ resources:
+ - deployments
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - delete
+ - watch
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+- apiGroups:
+ - admissionregistration.k8s.io
+ resources:
+ - validatingwebhookconfigurations
+ - mutatingwebhookconfigurations
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-allowed-provider-permissions.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:allowed-provider-permissions
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"
+---
+# Source: crossplane/templates/rbac-manager-clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - serviceaccounts
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources:
+ - compositeresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - pkg.crossplane.io
+ resources:
+ - providerrevisions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ - roles
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ # The RBAC manager may grant access it does not have.
+ - escalate
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - bind
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterrolebindings
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-edit
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-view
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-browse
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane administrators have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane administrators must create provider credential secrets, and may
+# need to read or otherwise interact with connection secrets. They may also need
+# to create or annotate namespaces.
+- apiGroups: [""]
+ resources: [secrets, namespaces]
+ verbs: ["*"]
+# Crossplane administrators have access to view the roles that they may be able
+# to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterroles, roles]
+ verbs: [get, list, watch]
+# Crossplane administrators have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterrolebindings, rolebindings]
+ verbs: ["*"]
+# Crossplane administrators have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+# Crossplane administrators have access to view CRDs in order to debug XRDs.
+- apiGroups: [apiextensions.k8s.io]
+ resources: [customresourcedefinitions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane editors must create provider credential secrets, and may need to
+# read or otherwise interact with connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane editors may see which namespaces exist, but not edit them.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane editors have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-view
+ labels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane viewers may see which namespaces exist.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane viewers have read-only access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-browse
+ labels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane browsers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane browsers have read-only access to compositions and XRDs. This
+# allows them to discover and select an appropriate composition when creating a
+# resource claim.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+# The below ClusterRoles are aggregated to the namespaced RBAC roles created by
+# the Crossplane RBAC manager when it is running in --manage=All mode.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-admin: "true"
+ rbac.crossplane.io/base-of-ns-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace admins have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace admins may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane namespace admins have access to view the roles that they may be
+# able to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [roles]
+ verbs: [get, list, watch]
+# Crossplane namespace admins have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [rolebindings]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-edit: "true"
+ rbac.crossplane.io/base-of-ns-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace editors may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-view
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-view: "true"
+ rbac.crossplane.io/base-of-ns-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane
+subjects:
+- kind: ServiceAccount
+ name: crossplane
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-rbac-manager
+subjects:
+- kind: ServiceAccount
+ name: rbac-manager
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+ kind: Group
+ name: crossplane:masters
+---
+# Source: crossplane/templates/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: crossplane
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: POD_SERVICE_ACCOUNT
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.serviceAccountName
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - start
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: LEADER_ELECTION
+ value: "true"
+ volumeMounts:
+ - mountPath: /cache
+ name: package-cache
+ volumes:
+ - name: package-cache
+ emptyDir:
+ medium:
+ sizeLimit: 5Mi
+---
+# Source: crossplane/templates/rbac-manager-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: rbac-manager
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - start
+ - --manage=All
+ - --provider-clusterrole=crossplane:allowed-provider-permissions
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: LEADER_ELECTION
+ value: "true"
+
+NOTES:
+Release: crossplane
+
+Chart Name: crossplane
+Chart Description: Crossplane is an open source Kubernetes add-on that enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume.
+Chart Version: 1.10.1
+Chart Application Version: 1.10.1
+
+Kube Version: v1.24.9
+```
+{{< /expand >}}
+
+Install the Crossplane components using `helm install`.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--namespace crossplane-system \
+--create-namespace
+```
+
+Verify Crossplane installed with `kubectl get pods`.
+
+```shell {copy-lines="1"}
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-d4cd8d784-ldcgb 1/1 Running 0 54s
+crossplane-rbac-manager-84769b574-6mw6f 1/1 Running 0 54s
+```
+
+Installing Crossplane creates new Kubernetes API end-points. Look at the new API end-points with `kubectl api-resources | grep crossplane`.
+
+```shell {label="grep",copy-lines="1"}
+kubectl api-resources | grep crossplane
+compositeresourcedefinitions xrd,xrds apiextensions.crossplane.io/v1 false CompositeResourceDefinition
+compositionrevisions apiextensions.crossplane.io/v1alpha1 false CompositionRevision
+compositions apiextensions.crossplane.io/v1 false Composition
+configurationrevisions pkg.crossplane.io/v1 false ConfigurationRevision
+configurations pkg.crossplane.io/v1 false Configuration
+controllerconfigs pkg.crossplane.io/v1alpha1 false ControllerConfig
+locks pkg.crossplane.io/v1beta1 false Lock
+providerrevisions pkg.crossplane.io/v1 false ProviderRevision
+providers pkg.crossplane.io/v1 false Provider
+storeconfigs secrets.crossplane.io/v1alpha1 false StoreConfig
+```
+
+## Install the AWS provider
+
+Install the provider into the Kubernetes cluster with a Kubernetes configuration file.
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}Provider{{}} Custom Resource Definition tells Kubernetes how to
+connect to the provider.
+
+Verify the provider installed with `kubectl get providers`.
+
+{{< hint type="note" >}}
+It may take up to five minutes for the provider to list `HEALTHY` as `True`.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+upbound-provider-aws True True xpkg.upbound.io/upbound/provider-aws:v0.27.0 12m
+```
+
+A provider installs their own Kubernetes _Custom Resource Definitions_ (CRDs). These CRDs allow you to create AWS resources directly inside Kubernetes.
+
+You can view the new CRDs with `kubectl get crds`. Every CRD maps to a unique AWS service Crossplane can provision and manage.
+
+
+{{< hint type="tip" >}}
+See details about all the supported CRDs in the [Upbound Marketplace](https://marketplace.upbound.io/providers/upbound/provider-family-aws/).
+{{< /hint >}}
+
+## Create a Kubernetes secret for AWS
+The provider requires credentials to create and manage AWS resources. Providers use a Kubernetes _Secret_ to connect the credentials to the provider.
+
+First generate a Kubernetes _Secret_ from your AWS key-pair and then configure the Provider to use it.
+
+{{< hint type="note" >}}
+Other authentication methods exist and are beyond the scope of this guide. The [Provider documentation](https://marketplace.upbound.io/providers/upbound/provider-aws/latest/docs/configuration) contains information on alternative authentication methods.
+{{< /hint >}}
+
+### Generate an AWS key-pair file
+For basic user authentication, use an AWS Access keys key-pair file.
+
+{{< hint type="tip" >}}
+The [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-creds) provides information on how to generate AWS Access keys.
+{{< /hint >}}
+
+Create a text file containing the AWS account `aws_access_key_id` and `aws_secret_access_key`.
+
+```ini {copy-lines="all"}
+[default]
+aws_access_key_id =
+aws_secret_access_key =
+```
+
+Save this text file as `aws-credentials.txt`.
+
+{{< hint type="note" >}}
+The [Configuration](https://marketplace.upbound.io/providers/upbound/provider-aws/latest/docs/configuration) section of the Provider documentation describes other authentication methods.
+{{< /hint >}}
+
+### Create a Kubernetes secret with the AWS credentials
+A Kubernetes generic secret has a name and contents. Use {{< hover label="kube-create-secret" line="1">}}kubectl create secret{{< /hover >}} to generate the secret object named {{< hover label="kube-create-secret" line="2">}}aws-secret{{< /hover >}} in the {{< hover label="kube-create-secret" line="3">}}crossplane-system{{ hover >}} namespace.
+Use the {{< hover label="kube-create-secret" line="4">}}--from-file={{}} argument to set the value to the contents of the {{< hover label="kube-create-secret" line="4">}}aws-credentials.txt{{< /hover >}} file.
+
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic aws-secret \
+-n crossplane-system \
+--from-file=creds=./aws-credentials.txt
+```
+
+View the secret with `kubectl describe secret`
+
+{{< hint type="note" >}}
+The size may be larger if there are extra blank spaces in your text file.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl describe secret aws-secret -n crossplane-system
+Name: aws-secret
+Namespace: crossplane-system
+Labels:
+Annotations:
+
+Type: Opaque
+
+Data
+====
+creds: 114 bytes
+```
+
+## Create a ProviderConfig
+A `ProviderConfig` customizes the settings of the AWS Provider.
+
+Apply the {{< hover label="providerconfig" line="2">}}ProviderConfig{{ hover >}} with the command:
+```yaml {label="providerconfig",copy-lines="all"}
+cat <}}secretRef{{ hover>}}.
+
+The {{< hover label="providerconfig" line="11">}}spec.credentials.secretRef.name{{< /hover >}} value is the name of the Kubernetes secret containing the AWS credentials in the {{< hover label="providerconfig" line="10">}}spec.credentials.secretRef.namespace{{< /hover >}}.
+
+
+## Create a managed resource
+A _managed resource_ is anything Crossplane creates and manages outside of the Kubernetes cluster. This creates an AWS S3 bucket with Crossplane. The S3 bucket is a _managed resource_.
+
+{{< hint type="note" >}}
+AWS S3 bucket names must be globally unique. To generate a unique name the example uses a random hash.
+Any unique name is acceptable.
+{{< /hint >}}
+
+```yaml {label="xr"}
+bucket=$(echo "crossplane-bucket-"$(head -n 4096 /dev/urandom | openssl sha1 | tail -c 10))
+cat <}}apiVersion{{< /hover >}} and {{< hover label="xr" line="4">}}kind{{}} are from the provider's CRDs.
+
+
+The {{< hover label="xr" line="6">}}metadata.name{{< /hover >}} value is the name of the created S3 bucket in AWS.
+This example uses the generated name `crossplane-bucket-` in the {{< hover label="xr" line="6">}}`$bucket`{{}} variable.
+
+The {{< hover label="xr" line="9">}}spec.forProvider.region{{< /hover >}} tells AWS which AWS region to use when deploying resources. The region can be any [AWS Regional endpoint](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints) code.
+
+Use `kubectl get buckets` to verify Crossplane created the bucket.
+
+{{< hint type="tip" >}}
+Crossplane created the bucket when the values `READY` and `SYNCED` are `True`.
+This may take up to 5 minutes.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get buckets
+NAME READY SYNCED EXTERNAL-NAME AGE
+crossplane-bucket-45eed4ae0 True True crossplane-bucket-45eed4ae0 61s
+```
+
+## Delete the managed resource
+Before shutting down your Kubernetes cluster, delete the S3 bucket just created.
+
+Use `kubectl delete bucket ` to remove the bucket.
+
+```shell {copy-lines="1"}
+kubectl delete bucket $bucket
+bucket.s3.aws.upbound.io "crossplane-bucket-45eed4ae0" deleted
+```
+
+## Next steps
+* [**Continue to part 2**]({{< ref "provider-aws-part-2">}})** to create a Crossplane _Composite Resource_ and _Claim_.
+* 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.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-azure-part-2.md b/content/v1.13/getting-started/provider-azure-part-2.md
new file mode 100644
index 00000000..07dd8412
--- /dev/null
+++ b/content/v1.13/getting-started/provider-azure-part-2.md
@@ -0,0 +1,1060 @@
+---
+title: Azure Quickstart Part 2
+weight: 120
+tocHidden: true
+---
+
+{{< hint "important" >}}
+This guide is part 2 of a series. Follow [**part 1**]({{[}})
+to install Crossplane and connect your Kubernetes cluster to Azure.
+
+[**Part 3**]({{][}})** covers patching _composite resources_
+and using Crossplane _Packages_.
+{{< /hint >}}
+
+This section creates a _[Composition](#create-a-composition)_,
+_[CompositeResourceDefinition](#define-a-composite-resource)_ and a
+_[Claim](#create-a-claim)_
+to create a custom Kubernetes API to create Azure resources. This custom API
+is a _composite resource_ (XR) API.
+
+## Prerequisites
+* Complete [quickstart part 1]({{][}}) connecting
+ Kubernetes to Azure.
+* an Azure account with permissions to create an Azure Virtual Machine and
+ Virtual Networking
+
+{{]}}
+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 Azure
+ Provider
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}
+```console
+az ad sp create-for-rbac \
+--sdk-auth \
+--role Owner \
+--scopes /subscriptions/$$$$
+```
+{{ editCode >}}
+
+4. Create a Kubernetes secret from the Azure JSON file.
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic azure-secret \
+-n crossplane-system \
+--from-file=creds=./azure-credentials.json
+```
+
+5. Create a _ProviderConfig_
+```yaml {label="providerconfig",copy-lines="all"}
+cat <}}
+
+## Create a composition
+[Part 1]({{[}}) created a single _managed resource_.
+A _Composition_ is a template to create one or more _managed resource_ at the
+same time.
+
+This sample _composition_ creates an Linux Virtual Machine and the required
+networking components.
+
+Compositions have multiple components:
+* The individual managed resources.
+* The Composition kind and version.
+* A Composite type reference.
+
+The following steps describe each of these components before
+[applying the final Composition](#apply-the-composition).
+
+Follow the steps to understand their details or skip straight to
+[applying the Composition](#apply-the-composition).
+
+
+### Define a virtual network
+Define a `virtualnetwork` resource using the configuration from the previous
+section:
+
+{{< hint "note" >}}
+Don't apply this configuration. This YAML is part of a larger
+definition.
+{{< /hint >}}
+
+```yaml {copy-lines="none"}
+apiVersion: network.azure.upbound.io/v1beta1
+kind: VirtualNetwork
+metadata:
+ name: crossplane-quickstart-network
+spec:
+ forProvider:
+ addressSpace:
+ - 10.0.0.0/16
+ location: "Central US"
+ resourceGroupName: ]
+```
+
+### Define a subnet resource
+Next, define a `Subnet` resource.
+
+{{< hint "note" >}}
+Don't apply this configuration. This YAML is part of a larger
+definition.
+{{< /hint >}}
+
+```yaml {label="subnet",copy-lines="none"}
+apiVersion: network.azure.upbound.io/v1beta1
+kind: Subnet
+metadata:
+ name: crossplane-quickstart-subnet
+spec:
+ forProvider:
+ addressPrefixes:
+ - 10.0.1.0/24
+ resourceGroupName:
+```
+
+### Define a network interface
+Define a network interface to attach to the virtual machine.
+
+{{< hint "note" >}}
+Don't apply this configuration. This YAML is part of a larger
+definition.
+{{< /hint >}}
+
+```yaml {label="nic",copy-lines="none"}
+apiVersion: network.azure.upbound.io/v1beta1
+kind: NetworkInterface
+metadata:
+ name: crossplane-quickstart-nic
+spec:
+ forProvider:
+ ipConfiguration:
+ - name: crossplane-quickstart-configuration
+ privateIpAddressAllocation: Dynamic
+ location: "Central US"
+ resourceGroupName:
+```
+
+### Define a virtual machine
+Define the `LinuxVirtualMachine` with its settings.
+
+{{< hint "note" >}}
+Don't apply this configuration. This YAML is part of a larger
+definition.
+{{< /hint >}}
+
+```yaml {label="vm",copy-lines="none"}
+apiVersion: compute.azure.upbound.io/v1beta1
+kind: LinuxVirtualMachine
+metadata:
+ name: crossplane-quickstart-vm
+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
+ size: Standard_B1ms
+ sourceImageReference:
+ - offer: debian-11
+ publisher: Debian
+ sku: 11-backports-gen2
+ version: latest
+ resourceGroupName:
+```
+
+### Create the composition object
+The _Composition_ combines all the managed resources into a single object.
+
+A
+{{}}Composition{{ hover>}} comes from the
+{{}}Crossplane{{ hover>}}
+API resources.
+
+Create any {{}}name{{ hover>}} for this _Composition_.
+
+```yaml {label="compName",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: crossplane-quickstart-vm-with-network
+```
+
+Add all the defined resources to the
+{{}}spec.resources{{ hover>}}
+section of the _Composition_.
+
+Give each resource a
+{{}}name{{ hover>}}
+and put the resource definition under the
+{{}}base{{ hover>}}
+key.
+
+Add your {{}}resourceGroupName{{< /hover >}}
+for each resource in the Composition.
+
+{{}}
+The contents of the
+{{}}base{{ hover>}} key
+doesn't include the `metadata` field from the managed resources.
+{{< /hint >}}
+
+```yaml {label="specResources",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: crossplane-quickstart-vm-with-network
+spec:
+ resources:
+ - name: quickstart-subnet
+ base:
+ apiVersion: network.azure.upbound.io/v1beta1
+ kind: Subnet
+ spec:
+ forProvider:
+ addressPrefixes:
+ - 10.0.1.0/24
+ virtualNetworkNameSelector:
+ matchControllerRef: true
+ resourceGroupName:
+# Removed for brevity
+```
+
+{{}}
+Crossplane provides the
+{{}}matchControllerRef{{ }} value
+to automatically link resources created by the same _Composition_.
+{{ }}
+
+_Compositions_ are a template for generating resources. A _composite
+resource_ actually creates the resources.
+
+A _Composition_ defines what _composite resources_ can use this
+template.
+
+_Compositions_ do this with the
+{{}}spec.compositeTypeRef{{ hover>}}
+definition.
+
+{{< hint "tip" >}}
+Crossplane recommends prefacing the `kind` with an `X` to show it's a Composition.
+{{< /hint >}}
+
+```yaml {label="compRef",copy-lines="none"}
+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:
+ # Removed for Brevity
+```
+
+A _composite resource_ is actually a custom Kubernetes API type you define. The
+platform team controls the kind, API endpoint and version.
+
+
+
+With this {{}}spec.compositeTypeRef{{ hover>}}
+Crossplane only allows _composite resources_ from the API group
+{{}}custom-api.example.org{{ hover>}}
+that are of
+{{}}kind: XVirtualMachine{{ hover>}}
+to use this template to create resources.
+
+
+### Apply the composition
+Apply the full _Composition_ to your Kubernetes cluster.
+
+{{}}
+Add your {{}}resourceGroupName{{ }} to
+each resource.
+{{< /hint >}}
+
+{{< editCode >}}
+```yaml {label="fullComp"}
+cat <$$
+ 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: $$$$
+ - name: quickstart-subnet
+ base:
+ apiVersion: network.azure.upbound.io/v1beta1
+ kind: Subnet
+ spec:
+ forProvider:
+ addressPrefixes:
+ - 10.0.1.0/24
+ virtualNetworkNameSelector:
+ matchControllerRef: true
+ resourceGroupName: $$$$
+ - name: quickstart-network
+ base:
+ apiVersion: network.azure.upbound.io/v1beta1
+ kind: VirtualNetwork
+ spec:
+ forProvider:
+ addressSpace:
+ - 10.0.0.0/16
+ location: "Central US"
+ resourceGroupName: $$$$
+EOF
+```
+{{< /editCode >}}
+
+Confirm the _Composition_ exists with `kubectl get composition`
+
+```shell {copy-lines="1"}
+kubectl get composition
+NAME XR-KIND XR-APIVERSION AGE
+crossplane-quickstart-vm-with-network XVirtualMachine custom-api.example.org/v1alpha1 5s
+```
+
+Again, the _Composition_ is only a template. At this point, Crossplane hasn't
+created any resources inside of Azure.
+
+## Define a composite resource
+
+The _Composition_ that was just created limited which _composite resources_ can
+use that template.
+
+A _composite resource_ is a custom API defined by the platform teams.
+A _CompositeResourceDefinition_ defines the schema for a _composite resource_.
+
+
+A _CompositeResourceDefinition_ installs the custom API type into Kubernetes
+and defines what `spec` keys and values are valid when calling this new custom API.
+
+Before creating a _composite resource_ Crossplane requires a _CompositeResourceDefinition_.
+
+{{< hint "tip" >}}
+_CompositeResourceDefinitions_ are also called `XRDs` for short.
+{{< /hint >}}
+
+Just like a _Composition_ the
+{{}}CompositeResourceDefinition{{ }}
+is part of the
+{{}}Crossplane{{ }}
+API group.
+
+The _XRD_ {{}}name{{ }} is the new
+API endpoint.
+
+{{< hint "tip" >}}
+Crossplane recommends using a plural name for the _XRD_
+{{}}name{{ }}.
+{{< /hint >}}
+
+```yaml {label="xrdName",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xvirtualmachines.custom-api.example.org
+```
+
+The _XRD's_
+{{}}spec{{ }} defines the new custom
+API.
+
+### Define the API endpoint and kind
+First, define the new API
+{{}}group{{ }}.
+Next, create the API {{}}kind{{ }} and
+{{}}plural{{ }}.
+
+```yaml {label="xrdGroup",copy-lines="none"}
+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
+```
+
+{{}}
+The _XRD_ {{}}group{{ }} matches the _composition_ {{}}apiVersion{{ }} and the
+_XRD_ {{}}kind{{ }} matches the _composition_
+{{}}compositeTypeRef.kind{{ }}.
+
+```yaml {label="noteComp",copy-lines="none"}
+kind: Composition
+# Removed for brevity
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: XVirtualMachine
+```
+{{< /hint >}}
+
+### Set the API version
+In Kubernetes, all API endpoints have a version to show the stability of the API
+and track revisions.
+
+Apply a version to the _XRD_ with a
+{{}}versions.name{{ }}.
+This matches the
+{{}}compositeTypeRef.apiVersion{{ }}
+
+_XRDs_ require both
+{{}}versions.served{{ }}
+and
+{{}}versions.referenceable{{ }}.
+
+```yaml {label="xrdVersion",copy-lines="none"}
+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
+```
+
+{{}}
+For more information on defining versions in Kubernetes read the
+[API versioning](https://kubernetes.io/docs/reference/using-api/#api-versioning) section of the Kubernetes documentation.
+{{< /hint >}}
+
+### Create the API schema
+With an API endpoint named, now define the API schema, or what's allowed
+inside the `spec` of the new Kubernetes object.
+
+{{< hint "note" >}}
+_XRDs_ follow the Kubernetes
+[_Custom Resource Definition_ rules for schemas](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
+{{ }}
+
+Place the API
+{{< hover label="xrdSchema" line="8" >}}schema{{ }}
+under the
+{{< hover label="xrdSchema" line="7" >}}version.name{{ }}
+
+The _XRD_ type defines the next lines. They're always the same.
+
+
+
+{{< hover label="xrdSchema" line="9" >}}openAPIV3Schema{{ }} specifies
+how the schema gets validated.
+
+
+Next, the entire API is an
+{{< hover label="xrdSchema" line="10" >}}object{{ }}
+with a
+{{< hover label="xrdSchema" line="11" >}}property{{ }} of
+{{< hover label="xrdSchema" line="12" >}}spec{{ }}.
+
+The
+{{< hover label="xrdSchema" line="12" >}}spec{{ }} is also an
+{{< hover label="xrdSchema" line="13" >}}object{{ }} with
+{{< hover label="xrdSchema" line="14" >}}properties{{ }}.
+
+```yaml {label="xrdSchema",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+ # Removed for brevity
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+```
+
+{{< hint "tip" >}}
+For more information on the values allowed in a _CompositeResourceDefinition_ view its schema with
+`kubectl explain xrd`
+{{< /hint >}}
+
+Now, define the custom API. Your custom API continues under the last
+{{}}properties{{ }} definition in the
+previous example.
+
+This custom API has only one setting:
+
+* {{}}region{{ }} - where to deploy
+the resources, a choice of "EU" or "US"
+
+Users can't change any other settings of the VM or its network.
+
+The{{}}region{{ }}
+is a {{}}string{{ }}
+and can match the regular expression that's
+{{}}oneOf{{ }}
+{{}}EU{{ }}
+or
+{{}}US{{ }}.
+
+This API requires the setting
+{{}}region{{ }}.
+
+
+```yaml {label="customAPI",copy-lines="none"}
+# Removed for brevity
+# schema.openAPIV3Schema.type.properties.spec
+properties:
+ region:
+ type: string
+ oneOf:
+ - pattern: '^EU$'
+ - pattern: '^US$'
+required:
+ - region
+```
+
+### Enable claims to the API
+Tell this _XRD_ to offer a _claim_ by defining the _claim_ API endpoint under
+the _XRD_ {{}}spec{{< /hover >}}.
+
+{{< hint "tip" >}}
+Crossplane recommends a _Claim_ {{}}kind{{ hover>}} match the _Composite Resource_ (XR)
+{{}}kind{{ hover>}},
+without the preceding `X`.
+{{< /hint >}}
+
+
+```yaml {label="XRDclaim",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ names:
+ kind: XVirtualMachine
+ plural: xvirtualmachines
+ claimNames:
+ kind: VirtualMachine
+ plural: virtualmachines
+```
+
+{{}}
+The [Claims](#create-a-claim) section later in this guide discusses _claims_.
+{{< /hint >}}
+
+### Apply the CompositeResourceDefinition
+Apply the complete _XRD_ to your Kubernetes cluster.
+
+
+```yaml
+cat <}}group{{ }}
+becomes the _composite resource_
+{{}}apiVersion{{ }}.
+
+The _XRD_ {{}}kind{{ }}
+is the _composite resource_
+{{}}kind{{ }}
+
+The _XRD_ API {{}}spec{{ }} defines the
+_composite resource_ {{}}spec{{ }}.
+
+The _XRD_ {{}}properties{{ }} section
+defines the options for the _composite resource_
+{{}}spec{{ }}.
+
+The one option is {{}}region{{ }} and it
+can be either {{}}EU{{ }} or
+{{}}US{{ }}.
+
+This _composite resource_ uses
+{{}}region: US{{ }}.
+
+### Apply the composite resource
+
+Apply the composite resource to the Kubernetes cluster.
+
+```yaml {label="xr"}
+cat <}}
+It may take up to 10 minutes for Azure to create the Virtual Machine resources.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get xvirtualmachine
+NAME SYNCED READY COMPOSITION AGE
+my-composite-resource True True crossplane-quickstart-vm-with-network 5m2s
+```
+
+{{}}
+Use `kubectl get ` to view a specific `kind` of _composite resource_.
+View all _composite resources_ with `kubectl get composite`.
+{{< /hint >}}
+
+
+Both `SYNCED` and `READY` are `True` when Crossplane created the Azure
+resources.
+
+Now look at the `linuxvirtualmachine` and `networkinterface`
+_managed resources_ with
+`kubectl get linuxvirtualmachine` and `kubectl get networkinterface`.
+
+```shell {copy-lines="1"}
+kubectl get linuxvirtualmachine
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-w564c True True my-composite-resource-w564c 8m33s
+```
+
+```shell {copy-lines="1"}
+kubectl get networkinterface
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-72ft8 True True my-composite-resource-72ft8 8m54s
+```
+
+The _composite resource_ automatically generated the _managed resources_.
+
+Using `kubectl describe` on a _managed resource_ shows the `Owner References` is
+the _composite resource_.
+
+```yaml {copy-lines="1"}
+ kubectl describe linuxvirtualmachine | grep "Owner References" -A5
+ Owner References:
+ API Version: custom-api.example.org/v1alpha1
+ Block Owner Deletion: true
+ Controller: true
+ Kind: XVirtualMachine
+ Name: my-composite-resource
+```
+
+Each _composite resource_ creates and owns a unique set of _managed resources_.
+If you create a second _composite resource_ Crossplane creates a new
+`LinuxVirtualMachine` and new networking resources.
+
+```yaml {label="xr"}
+cat <}}
+Delete a specific _composite resource_ with `kubectl delete ` or
+`kubectl delete composite`.
+{{< /hint >}}
+
+Delete the second composition
+```shell
+kubectl delete xvirtualmachine my-second-composite-resource
+```
+
+{{}}
+It may take up to five minutes before Crossplane finishes deleting resources.
+{{ }}
+
+Now only one virtual machine and network interface exist.
+
+```shell {copy-lines="1"}
+kubectl get linuxvirtualmachines
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-w564c True True my-composite-resource-w564c 28m
+```
+
+```shell {copy-lines="1"}
+kubectl get networkinterface
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-72ft8 True True my-composite-resource-72ft8 29m
+```
+
+Delete the other _composite resource_ to remove the last `linuxvirtualmachines`
+and `networkinterface` _managed resources_.
+
+```shell
+kubectl delete xvirtualmachine my-composite-resource
+```
+
+_Composite resources_ are great for creating one or more related resources against
+a template, but all _composite resources_ exist at the Kubernetes "cluster
+level." There's no isolation between _composite resources_. Crossplane uses
+_Claims_ to create resources with namespace isolation.
+
+## Create a claim
+
+_Claims_, just like _composite resources_ use the custom API defined in the
+_XRD_. Unlike a _composite resource_, Crossplane can create _Claims_ in a
+namespace.
+
+### Create a new Kubernetes namespace
+Create a new namespace with `kubectl create namespace`.
+
+```shell
+kubectl create namespace test
+```
+
+Look at the _XRD_ to see the parameters for the _Claim_.
+A _Claim_ uses the same {{}}group{{ }}
+a _composite resource_ uses but a different
+{{}}kind{{ }}.
+
+```yaml {label="XRDclaim2",copy-lines="none"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ group: custom-api.example.org
+ claimNames:
+ kind: VirtualMachine
+ plural: virtualmachines
+```
+
+Like the _composite resource_, create a new object with the
+{{}}custom-api.example.org{{ }} API
+endpoint.
+
+The _XRD_
+{{}}claimNames.kind{{ }} defines the
+{{}}kind{{ }}.
+
+The {{}}spec{{ }} uses the same
+API options as the _composite resource_.
+
+### Apply the claim
+Apply the _claim_ to your Kubernetes cluster.
+
+```yaml {label="claim"}
+cat <}}
+View claims with `kubectl get ` or use `kubectl get claim` to view all
+_Claims_.
+{{ }}
+
+```shell {copy-lines="1"}
+kubectl get virtualmachine -n test
+NAME SYNCED READY CONNECTION-SECRET AGE
+claimed-virtualmachine True True 3m40s
+```
+
+When Crossplane creates a _Claim_, a unique _composite resource_ is also
+created. View the new _composite resource_ with `kubectl get xvirtualmachine`.
+
+```shell {copy-lines="1"}
+kubectl get xvirtualmachine
+NAME SYNCED READY COMPOSITION AGE
+claimed-virtualmachine-cw6cv True True crossplane-quickstart-vm-with-network 3m57s
+```
+
+The _composite resource_ exists at the "cluster scope" while the _Claim_ exists
+at the "namespace scope."
+
+Create a second namespace and a second claim.
+
+```yaml
+kubectl create namespace test2
+cat <}}) of this guide covers _composition
+patches_ and making all this configuration portable in Crossplane _Packages_.
+
+## Next steps
+* [**Continue to part 3**]({{< ref "provider-azure-part-3">}}) to learn
+ about _patching_ resources and creating Crossplane _Packages_.
+* Explore Azure resources that Crossplane can configure in the
+ [Provider CRD reference](https://marketplace.upbound.io/providers/upbound/provider-family-azure/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with Crossplane users and contributors.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-azure-part-3.md b/content/v1.13/getting-started/provider-azure-part-3.md
new file mode 100644
index 00000000..899ff872
--- /dev/null
+++ b/content/v1.13/getting-started/provider-azure-part-3.md
@@ -0,0 +1,810 @@
+---
+title: Azure 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 Azure.
+
+Follow [**part 2**]({{][}}) to create a _composition_,
+_custom resource definition_ and a _claim_.
+{{< /hint >}}
+
+[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]({{][}}) 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
+```
+
+1. When the Crossplane pods finish installing and are ready, apply the Azure
+ Provider
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}
+```console
+az ad sp create-for-rbac \
+--sdk-auth \
+--role Owner \
+--scopes /subscriptions/$$$$
+```
+{{ editCode >}}
+
+4. Create a Kubernetes secret from the Azure JSON file.
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic azure-secret \
+-n crossplane-system \
+--from-file=creds=./azure-credentials.json
+```
+
+5. Create a _ProviderConfig_
+```yaml {label="providerconfig",copy-lines="all"}
+cat <}}
+Apply your
+{{}}resourceGroupName{{ }} to each resource.
+{{< /hint >}}
+
+{{< editCode >}}
+```yaml {label="Composition"}
+cat <$$
+ 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: $$$$
+ - name: quickstart-subnet
+ base:
+ apiVersion: network.azure.upbound.io/v1beta1
+ kind: Subnet
+ spec:
+ forProvider:
+ addressPrefixes:
+ - 10.0.1.0/24
+ virtualNetworkNameSelector:
+ matchControllerRef: true
+ resourceGroupName: $$$$
+ - name: quickstart-network
+ base:
+ apiVersion: network.azure.upbound.io/v1beta1
+ kind: VirtualNetwork
+ spec:
+ forProvider:
+ addressSpace:
+ - 10.0.0.0/16
+ location: "Central US"
+ resourceGroupName: $$$$
+EOF
+```
+{{< /editCode >}}
+
+7. Create a _CompositeResourceDefinition_
+```yaml
+cat <}}
+
+## 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{{ }}.
+
+
+```yaml {label="compResources",copy-lines="none"}
+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{{ }}.
+
+
+```yaml {label="xrdSnip",copy-lines="none"}
+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."
+
+
+
+```yaml {label="patch",copy-lines="none"}
+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 >}}
+```yaml
+cat <$$
+ 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: $$$$
+ 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: $$$$
+ 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: $$$$
+ 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."
+
+```yaml {label="claim"}
+cat <}}
+It may take up to 10 minutes for the Claim to be `READY`.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+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`.
+
+```shell {copy-lines="1"}
+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_.
+
+{{}}
+The _managed resources_ take up to 5 minutes to delete.
+{{< /hint >}}
+
+```shell
+kubectl delete virtualmachine claimed-eu-virtualmachine -n test
+```
+
+## Create a Crossplane configuration package
+
+Crossplane _configuration packages_ allow users to combine their
+_Custom Resource Definition_ and _Composition_ files into a single 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 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.
+
+{{}}
+Crossplane automatically installs dependencies. Dependencies can include other
+configuration packages.
+{{< /hint >}}
+
+Create a new directory and save the `crossplane.yaml` file.
+
+```yaml {label="xpyaml"}
+mkdir crossplane-azure-quickstart
+cat < crossplane-azure-quickstart/crossplane.yaml
+apiVersion: meta.pkg.crossplane.io/v1
+kind: Configuration
+metadata:
+ name: crossplane-azure-quickstart
+spec:
+ crossplane:
+ version: ">=v1.12.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.
+
+```yaml
+cat < 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 >}}
+```yaml
+cat < 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: $$$$
+ 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: $$$$
+ 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: $$$$
+ 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: $$$$
+ 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.
+
+```shell
+wget "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh"
+chmod +x install.sh
+./install.sh
+```
+
+Follow the directions and move the `kubectl-crossplane` binary to the correct
+directory.
+
+Verify the Crossplane command-line installed with `kubectl crossplane --help`
+
+```shell {copy-lines="1"}
+kubectl crossplane --help
+Usage: kubectl 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 `kubectl crossplane` command to create an `.xpkg` file containing the
+custom APIs and Crossplane configuration.
+
+```shell
+kubectl crossplane build configuration -f crossplane-azure-quickstart/ --name="crossplane-azure-quickstart"
+```
+
+Now an `.xpkg` OCI image is inside the `crossplane-azure-quickstart` directory.
+
+```shell {copy-lines="1"}
+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](https://marketplace.upbound.io/providers/upbound/provider-family-azure/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with Crossplane users and contributors.
+* Read more about [Crossplane concepts]({{[}})
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-azure.md b/content/v1.13/getting-started/provider-azure.md
new file mode 100644
index 00000000..0811738a
--- /dev/null
+++ b/content/v1.13/getting-started/provider-azure.md
@@ -0,0 +1,1250 @@
+---
+title: Azure Quickstart
+weight: 110
+---
+
+Connect Crossplane to Azure to create and manage cloud resources from Kubernetes
+with the
+[Upbound Azure Provider](https://marketplace.upbound.io/providers/upbound/provider-azure).
+
+This guide is in three parts:
+* Part 1 walks through installing Crossplane, configuring the provider to
+authenticate to Azure and creating a _Managed Resource_ in Azure directly from
+your Kubernetes cluster. This shows Crossplane can communicate with Azure.
+* [Part 2]({{< ref "provider-azure-part-2" >}}) creates a
+_Composite Resource Definition_ (XRD), _Composite Resource_ (XR) and a _Claim_
+(XRC) to show how to create and use custom APIs.
+* [Part 3]({{< ref "provider-azure-part-3" >}}) demonstrates how to patch
+_Compositions_ with values used in a _Claim_ and how to build a Crossplane
+_Package_.
+
+## Prerequisites
+This quickstart requires:
+* a Kubernetes cluster with at least 6 GB of RAM
+* permissions to create pods and secrets in the Kubernetes cluster
+* [Helm](https://helm.sh/) version v3.2.0 or later
+* an Azure account with permissions to create an
+ [Azure Virtual Machine](https://learn.microsoft.com/en-us/azure/virtual-machines/)
+ and
+ [Virtual Network](https://learn.microsoft.com/en-us/azure/virtual-network/)
+* an Azure account with permissions to create an Azure [service principal](https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals#service-principal-object) and an [Azure resource group](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal)
+
+## Install Crossplane
+
+Crossplane installs into an existing Kubernetes cluster.
+
+{{< hint type="tip" >}}
+If you don't have a Kubernetes cluster create one locally with
+[Kind](https://kind.sigs.k8s.io/).
+{{< /hint >}}
+
+
+### Install the Crossplane Helm chart
+
+Helm enables Crossplane to install all its Kubernetes components through a
+_Helm Chart_.
+
+Enable the Crossplane Helm Chart repository:
+
+```shell
+helm repo add \
+crossplane-stable https://charts.crossplane.io/stable && helm repo update
+```
+
+Run the Helm dry-run to see all the Crossplane components Helm installs.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+```
+{{]}}
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+install.go:193: [debug] Original chart version: ""
+install.go:210: [debug] CHART PATH: /home/vagrant/.cache/helm/repository/crossplane-1.10.1.tgz
+
+NAME: crossplane
+LAST DEPLOYED: Thu Jan 19 15:52:08 2023
+NAMESPACE: crossplane-system
+STATUS: pending-install
+REVISION: 1
+TEST SUITE: None
+USER-SUPPLIED VALUES:
+{}
+
+COMPUTED VALUES:
+affinity: {}
+args: {}
+configuration:
+ packages: []
+customAnnotations: {}
+customLabels: {}
+deploymentStrategy: RollingUpdate
+extraEnvVarsCrossplane: {}
+extraEnvVarsRBACManager: {}
+image:
+ pullPolicy: IfNotPresent
+ repository: crossplane/crossplane
+ tag: v1.10.1
+imagePullSecrets: {}
+leaderElection: true
+metrics:
+ enabled: false
+nodeSelector: {}
+packageCache:
+ medium: ""
+ pvc: ""
+ sizeLimit: 5Mi
+podSecurityContextCrossplane: {}
+podSecurityContextRBACManager: {}
+priorityClassName: ""
+provider:
+ packages: []
+rbacManager:
+ affinity: {}
+ args: {}
+ deploy: true
+ leaderElection: true
+ managementPolicy: All
+ nodeSelector: {}
+ replicas: 1
+ skipAggregatedClusterRoles: false
+ tolerations: {}
+registryCaBundleConfig: {}
+replicas: 1
+resourcesCrossplane:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+resourcesRBACManager:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+securityContextCrossplane:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+securityContextRBACManager:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+serviceAccount:
+ customAnnotations: {}
+tolerations: {}
+webhooks:
+ enabled: false
+
+HOOKS:
+MANIFEST:
+---
+# Source: crossplane/templates/rbac-manager-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:system:aggregate-to-crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ crossplane.io/scope: "system"
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ - services
+ verbs:
+ - "*"
+- apiGroups:
+ - apiextensions.crossplane.io
+ - pkg.crossplane.io
+ - secrets.crossplane.io
+ resources:
+ - "*"
+ verbs:
+ - "*"
+- apiGroups:
+ - extensions
+ - apps
+ resources:
+ - deployments
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - delete
+ - watch
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+- apiGroups:
+ - admissionregistration.k8s.io
+ resources:
+ - validatingwebhookconfigurations
+ - mutatingwebhookconfigurations
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-allowed-provider-permissions.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:allowed-provider-permissions
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"
+---
+# Source: crossplane/templates/rbac-manager-clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - serviceaccounts
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources:
+ - compositeresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - pkg.crossplane.io
+ resources:
+ - providerrevisions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ - roles
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ # The RBAC manager may grant access it does not have.
+ - escalate
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - bind
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterrolebindings
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-edit
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-view
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-browse
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane administrators have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane administrators must create provider credential secrets, and may
+# need to read or otherwise interact with connection secrets. They may also need
+# to create or annotate namespaces.
+- apiGroups: [""]
+ resources: [secrets, namespaces]
+ verbs: ["*"]
+# Crossplane administrators have access to view the roles that they may be able
+# to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterroles, roles]
+ verbs: [get, list, watch]
+# Crossplane administrators have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterrolebindings, rolebindings]
+ verbs: ["*"]
+# Crossplane administrators have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+# Crossplane administrators have access to view CRDs in order to debug XRDs.
+- apiGroups: [apiextensions.k8s.io]
+ resources: [customresourcedefinitions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane editors must create provider credential secrets, and may need to
+# read or otherwise interact with connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane editors may see which namespaces exist, but not edit them.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane editors have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-view
+ labels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane viewers may see which namespaces exist.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane viewers have read-only access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-browse
+ labels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane browsers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane browsers have read-only access to compositions and XRDs. This
+# allows them to discover and select an appropriate composition when creating a
+# resource claim.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+# The below ClusterRoles are aggregated to the namespaced RBAC roles created by
+# the Crossplane RBAC manager when it is running in --manage=All mode.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-admin: "true"
+ rbac.crossplane.io/base-of-ns-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace admins have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace admins may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane namespace admins have access to view the roles that they may be
+# able to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [roles]
+ verbs: [get, list, watch]
+# Crossplane namespace admins have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [rolebindings]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-edit: "true"
+ rbac.crossplane.io/base-of-ns-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace editors may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-view
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-view: "true"
+ rbac.crossplane.io/base-of-ns-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane
+subjects:
+- kind: ServiceAccount
+ name: crossplane
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-rbac-manager
+subjects:
+- kind: ServiceAccount
+ name: rbac-manager
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+ kind: Group
+ name: crossplane:masters
+---
+# Source: crossplane/templates/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: crossplane
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: POD_SERVICE_ACCOUNT
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.serviceAccountName
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - start
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: LEADER_ELECTION
+ value: "true"
+ volumeMounts:
+ - mountPath: /cache
+ name: package-cache
+ volumes:
+ - name: package-cache
+ emptyDir:
+ medium:
+ sizeLimit: 5Mi
+---
+# Source: crossplane/templates/rbac-manager-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: rbac-manager
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - start
+ - --manage=All
+ - --provider-clusterrole=crossplane:allowed-provider-permissions
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: LEADER_ELECTION
+ value: "true"
+
+NOTES:
+Release: crossplane
+
+Chart Name: crossplane
+Chart Description: Crossplane is an open source Kubernetes add-on that enables platform teams to assemble infrastructure from multiple vendors, and expose higher level self-service APIs for application teams to consume.
+Chart Version: 1.10.1
+Chart Application Version: 1.10.1
+
+Kube Version: v1.24.9
+```
+{{< /expand >}}
+
+Install the Crossplane components using `helm install`.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--namespace crossplane-system \
+--create-namespace
+```
+
+Verify Crossplane installed with `kubectl get pods`.
+
+```shell {copy-lines="1"}
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-d4cd8d784-ldcgb 1/1 Running 0 54s
+crossplane-rbac-manager-84769b574-6mw6f 1/1 Running 0 54s
+```
+
+Installing Crossplane creates new Kubernetes API end-points. Look at the new API
+end-points with `kubectl api-resources | grep crossplane`.
+
+```shell {label="grep",copy-lines="1"}
+kubectl api-resources | grep crossplane
+compositeresourcedefinitions xrd,xrds apiextensions.crossplane.io/v1 false CompositeResourceDefinition
+compositionrevisions apiextensions.crossplane.io/v1alpha1 false CompositionRevision
+compositions apiextensions.crossplane.io/v1 false Composition
+configurationrevisions pkg.crossplane.io/v1 false ConfigurationRevision
+configurations pkg.crossplane.io/v1 false Configuration
+controllerconfigs pkg.crossplane.io/v1alpha1 false ControllerConfig
+locks pkg.crossplane.io/v1beta1 false Lock
+providerrevisions pkg.crossplane.io/v1 false ProviderRevision
+providers pkg.crossplane.io/v1 false Provider
+storeconfigs secrets.crossplane.io/v1alpha1 false StoreConfig
+```
+
+## Install the Azure provider
+
+Install the provider into the Kubernetes cluster with a Kubernetes configuration
+file.
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}Provider{{ }}
+Custom Resource Definitions tells Kubernetes how to
+connect to the provider.
+
+Verify the provider installed with `kubectl get providers`.
+
+{{< hint type="note" >}}
+It may take up to five minutes for the provider to list `HEALTHY` as `True`.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+upbound-provider-azure True True xpkg.upbound.io/upbound/provider-azure:v0.32.0 22m
+```
+
+A provider installs their own Kubernetes _Custom Resource Definitions_ (CRDs).
+These CRDs allow you to create Azure resources directly inside Kubernetes.
+
+You can view the new CRDs with `kubectl get crds`. Every CRD maps to a unique
+Azure service Crossplane can provision and manage.
+
+
+{{< hint type="tip" >}}
+See details about all the supported CRDs in the
+[Upbound Marketplace](https://marketplace.upbound.io/providers/upbound/provider-family-azure/).
+{{< /hint >}}
+
+## Create a Kubernetes secret for Azure
+The provider requires credentials to create and manage Azure resources.
+Providers use a Kubernetes _Secret_ to connect the credentials to the provider.
+
+This guide generates an Azure service principal JSON file and saves it as a
+Kubernetes _Secret_.
+
+{{< hint type="note" >}}
+Other authentication methods exist and are beyond the scope of this guide. The
+[Provider documentation](https://github.com/upbound/provider-azure/blob/main/AUTHENTICATION.md)
+contains information on alternative authentication methods.
+{{< /hint >}}
+
+### Install the Azure command-line
+Generating an [authentication file](https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization#use-file-based-authentication) requires the Azure command-line.
+Follow the documentation from Microsoft to [Download and install the Azure command-line](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli).
+
+Log in to the Azure command-line.
+
+```command
+az login
+```
+### Create an Azure service principal
+Follow the Azure documentation to [find your Subscription ID](https://docs.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id) from the Azure Portal.
+
+Using the Azure command-line and provide your Subscription ID create a service principal and authentication file.
+
+{{< editCode >}}
+```console {copy-lines="all"}
+az ad sp create-for-rbac \
+--sdk-auth \
+--role Owner \
+--scopes /subscriptions/$$$$
+```
+{{< /editCode >}}
+
+Save your Azure JSON output as `azure-credentials.json`.
+
+{{< hint type="note" >}}
+The Azure Provider
+[Authentication documentation](https://github.com/upbound/provider-azure/blob/main/AUTHENTICATION.md)
+describes other authentication methods.
+{{< /hint >}}
+
+### Create a Kubernetes secret with the Azure credentials
+A Kubernetes generic secret has a name and contents. Use {{< hover label="kube-create-secret" line="1">}}kubectl create secret{{< /hover >}} to generate the secret object named {{< hover label="kube-create-secret" line="2">}}azure-secret{{< /hover >}} in the {{< hover label="kube-create-secret" line="3">}}crossplane-system{{ hover >}} namespace.
+
+
+
+Use the {{< hover label="kube-create-secret" line="4">}}--from-file={{ }} argument to set the value to the contents of the {{< hover label="kube-create-secret" line="4">}}azure-credentials.json{{< /hover >}} file.
+
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic azure-secret \
+-n crossplane-system \
+--from-file=creds=./azure-credentials.json
+```
+
+View the secret with `kubectl describe secret`
+
+{{< hint type="note" >}}
+The size may be larger if there are extra blank spaces in your text file.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl describe secret azure-secret -n crossplane-system
+Name: azure-secret
+Namespace: crossplane-system
+Labels:
+Annotations:
+
+Type: Opaque
+
+Data
+====
+creds: 629 bytes
+```
+
+## Create a ProviderConfig
+A `ProviderConfig` customizes the settings of the Azure Provider.
+
+Apply the {{< hover label="providerconfig" line="5">}}ProviderConfig{{ hover >}} with the command:
+```yaml {label="providerconfig",copy-lines="all"}
+cat <}}secretRef{{ hover>}}.
+
+The {{< hover label="providerconfig" line="11">}}spec.credentials.secretRef.name{{< /hover >}} value is the name of the Kubernetes secret containing the Azure credentials in the {{< hover label="providerconfig" line="10">}}spec.credentials.secretRef.namespace{{< /hover >}}.
+
+
+## Create a managed resource
+A _managed resource_ is anything Crossplane creates and manages outside of the
+Kubernetes cluster. This example creates an Azure Virtual Network with
+Crossplane. The Virtual Network is a _managed resource_.
+
+{{< hint type="note" >}}
+Add your Azure Resource Group name. Follow the Azure documentation to
+[create a resource group](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal)
+if you don't have one.
+{{< /hint >}}
+
+{{< editCode >}}
+```yaml {label="xr"}
+cat <}}
+
+The {{< hover label="xr" line="2">}}apiVersion{{< /hover >}} and
+{{< hover label="xr" line="3">}}kind{{ }} are from the provider's CRDs.
+
+The {{< hover label="xr" line="10">}}spec.forProvider.location{{< /hover >}}
+tells Azure which location to use when deploying the resource.
+
+Use `kubectl get virtualnetwork.network` to verify Crossplane created the
+Azure Virtual Network.
+
+{{< hint type="tip" >}}
+Crossplane created the virtual network when the values `READY` and `SYNCED` are `True`.
+This may take up to 5 minutes.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get virtualnetwork.network
+NAME READY SYNCED EXTERNAL-NAME AGE
+crossplane-quickstart-network True True crossplane-quickstart-network 10m
+```
+
+## Delete the managed resource
+Before shutting down your Kubernetes cluster, delete the virtual network just
+created.
+
+Use `kubectl delete virtualnetwork.network` to delete the virtual network.
+
+
+```shell {copy-lines="1"}
+kubectl delete virtualnetwork.network crossplane-quickstart-network
+virtualnetwork.network.azure.upbound.io "crossplane-quickstart-network" deleted
+```
+
+## Next steps
+* [**Continue to part 2**]({{< ref "provider-azure-part-2">}}) to create a
+ Crossplane _Composite Resource_ and _Claim_.
+* Explore Azure resources that Crossplane can configure in the
+ [Provider CRD reference](https://marketplace.upbound.io/providers/upbound/provider-family-azure/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with
+ Crossplane users and contributors.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-gcp-part-2.md b/content/v1.13/getting-started/provider-gcp-part-2.md
new file mode 100644
index 00000000..23f2bb0f
--- /dev/null
+++ b/content/v1.13/getting-started/provider-gcp-part-2.md
@@ -0,0 +1,967 @@
+---
+title: GCP Quickstart Part 2
+weight: 120
+tocHidden: true
+---
+
+{{< hint "important" >}}
+This guide is part 2 of a series. Follow [**part 1**]({{[}})
+to install Crossplane and connect your Kubernetes cluster to GCP.
+
+[**Part 3**]({{][}})** covers patching
+_composite resources_ and using Crossplane _packages_.
+{{< /hint >}}
+
+This section creates a _[Composition](#create-a-composition)_,
+_[Composite Resource Definition](#define-a-composite-resource)_ and a
+_[Claim](#create-a-claim)_
+to create a custom Kubernetes API to create GCP resources. This custom API is a
+_Composite Resource_ (XR) API.
+
+## Prerequisites
+* Complete [quickstart part 1]({{][}}) connecting Kubernetes
+ to GCP.
+* a GCP account with permissions to create a GCP
+ [storage bucket](https://cloud.google.com/storage) and a
+ [Pub/Sub topic](https://cloud.google.com/pubsub).
+
+{{]}}
+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 GCP Provider.
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}
+The
+[GCP documentation](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)
+provides information on how to generate a service account JSON file.
+{{< /hint >}}
+
+4. Create a Kubernetes secret from the GCP JSON file
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic gcp-secret \
+-n crossplane-system \
+--from-file=creds=./gcp-credentials.json
+```
+
+5. 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 >}}
+```yaml {label="providerconfig",copy-lines="all"}
+cat <$@
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: gcp-secret
+ key: creds
+EOF
+```
+{{< /editCode >}}
+
+{{ }}
+
+## Create a composition
+[Part 1]({{[}}) created a single _managed resource_.
+A _Composition_ is a template to create one or more _managed resources_ at the
+same time.
+
+This sample _composition_ creates a Pub/Sub instance and associated GCP storage
+bucket.
+
+{{< hint "note" >}}
+This example comes from part of the GCP
+[Stream messages from Pub/Sub by using Dataflow](https://cloud.google.com/pubsub/docs/stream-messages-dataflow)
+guide.
+{{< /hint >}}
+
+To create a _composition_, first define each individual managed resource.
+
+### Create a storage bucket object
+Define a `bucket` resource using the configuration from the previous section:
+
+{{< hint "note" >}}
+Don't apply this configuration. This YAML is part of a larger
+definition.
+{{< /hint >}}
+
+```yaml
+apiVersion: storage.gcp.upbound.io/v1beta1
+kind: Bucket
+metadata:
+ name: crossplane-quickstart-bucket
+spec:
+ forProvider:
+ location: US
+ providerConfigRef:
+ name: default
+```
+
+### Create a Pub/Sub topic resource
+Next, define a Pub/Sub `topic` resource.
+
+{{< hint "tip" >}}
+The [Upbound Marketplace](https://marketplace.upbound.io/) provides
+[schema documentation](https://marketplace.upbound.io/providers/upbound/provider-gcp/v0.28.0/resources/pubsub.gcp.upbound.io/Topic/v1beta1)
+for a `topic` resource.
+{{< /hint >}}
+
+The _GCP Provider_ defines the
+{{]}}apiVersion{{ }}
+and
+{{}}kind{{ }}.
+
+A Pub/Sub topic doesn't have requirements but using
+{{}}messageStoragePolicy.allowedPersistenceRegions{{< /hover >}}
+can keep messages stored in the same location as the storage bucket.
+
+```yaml {label="topicMR"}
+apiVersion: pubsub.gcp.upbound.io/v1beta1
+kind: Topic
+metadata:
+ name: crossplane-quickstart-topic
+spec:
+ forProvider:
+ messageStoragePolicy:
+ - allowedPersistenceRegions:
+ - "us-central1"
+```
+
+{{< hint "note" >}}
+Pub/Sub topic specifics are beyond the scope of this guide. Read the GCP
+[Pub/Sub API reference](https://cloud.google.com/compute/docs/apis)
+for more information.
+{{ }}
+
+### Create the composition object
+The _composition_ combines the two resource definitions.
+
+A
+{{}}Composition{{ hover>}} comes from the
+{{}}Crossplane{{ hover>}}
+API resources.
+
+Create any {{}}name{{ hover>}} for this _composition_.
+
+```yaml {label="compName"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: topic-with-bucket
+```
+
+Add the resources to the
+{{}}spec.resources{{ hover>}}
+section of the _composition_.
+
+Give each resource a
+{{}}name{{ hover>}}
+and put the resource definition under the
+{{}}base{{ hover>}}
+key.
+
+{{< hint "note" >}}
+Don't include resource `metadata` under the
+{{}}base{{ hover>}} key.
+{{< /hint >}}
+
+```yaml {label="specResources"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: topic-with-bucket
+spec:
+ 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"
+```
+
+_Compositions_ are a template for generating resources. A
+_composite resource_ actually creates the resources.
+
+A _composition_ defines which _composite resources_ can use this
+template.
+
+_Compositions_ do this with the
+{{}}spec.compositeTypeRef{{ hover>}}
+definition.
+
+{{< hint "tip" >}}
+Crossplane recommends prefacing the `kind` with an `X` to show it's a
+Composition.
+{{< /hint >}}
+
+```yaml {label="compRef"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: Composition
+metadata:
+ name: topic-with-bucket
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: XTopicBucket
+ resources:
+ # Removed for Brevity
+```
+
+A _composite resource_ is actually a custom Kubernetes API type you define. The
+platform team controls the kind, API endpoint and version.
+
+
+
+With this {{}}spec.compositeTypeRef{{ hover>}}
+Crossplane allows _composite resources_ from the API group
+{{}}custom-api.example.org{{ hover>}}
+that are of
+{{}}kind: XTopicBucket{{ hover>}}
+to use this template to create resources. No other API group or kind can use
+this template.
+
+
+### Apply the composition
+Apply the full _Composition_ to your Kubernetes cluster.
+
+```yaml {copy-lines="all"}
+cat <}}
+_Composite resource definitions_ are also called `XRDs` for short.
+{{< /hint >}}
+
+Just like a _composition_ the
+{{}}composite resource definition{{ }}
+is part of the
+{{}}Crossplane{{ }}
+API group.
+
+The _XRD_ {{}}name{{ }} is the new
+API endpoint.
+
+{{< hint "tip" >}}
+Crossplane recommends using a plural name for the _XRD_
+{{}}name{{ }}.
+{{< /hint >}}
+
+```yaml {label="xrdName"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+metadata:
+ name: xtopicbuckets.custom-api.example.org
+```
+
+The _XRD's_
+{{}}spec{{ }} defines the new custom
+API.
+
+### Define the API endpoint and kind
+First, define the new API
+{{}}group{{ }}.
+Next, create the API {{}}kind{{ }} and
+{{}}plural{{ }}.
+
+```yaml {label="xrdGroup"}
+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
+```
+
+{{}}
+The _XRD_ {{}}group{{ }} matches the _composition_ {{}}apiVersion{{ }} and the
+_XRD_ {{}}kind{{ }} matches the _composition_
+{{}}compositeTypeRef.kind{{ }}.
+
+```yaml {label="noteComp"}
+kind: Composition
+# Removed for brevity
+spec:
+ compositeTypeRef:
+ apiVersion: custom-api.example.org/v1alpha1
+ kind: XTopicBucket
+```
+{{< /hint >}}
+
+### Set the API version
+In Kubernetes, all API endpoints have a version to show the stability of the API
+and track revisions.
+
+Apply a version to the _XRD_ with a
+{{}}versions.name{{ }}.
+This matches the
+{{}}compositeTypeRef.apiVersion{{ }}
+
+_XRDs_ require both
+{{}}versions.served{{ }}
+and
+{{}}versions.referenceable{{ }}.
+
+```yaml {label="xrdVersion"}
+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
+```
+
+{{}}
+For more information on defining versions in Kubernetes read the
+[API versioning](https://kubernetes.io/docs/reference/using-api/#api-versioning)
+section of the Kubernetes documentation.
+{{< /hint >}}
+
+### Create the API schema
+With an API endpoint named, now define the API schema, or what's allowed
+inside the `spec` of the new Kubernetes object.
+
+{{< hint "note" >}}
+_XRDs_ follow the Kubernetes
+[_custom resource definition_ rules for schemas](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
+{{ }}
+
+Place the API
+{{< hover label="xrdSchema" line="8" >}}schema{{ }}
+under the
+{{< hover label="xrdSchema" line="7" >}}version.name{{ }}
+
+The _XRD_ type defines the next lines. They're always the same.
+
+
+
+{{< hover label="xrdSchema" line="9" >}}openAPIV3Schema{{ }} specifies
+how the schema gets validated.
+
+
+Next, the entire API is an
+{{< hover label="xrdSchema" line="10" >}}object{{ }}
+with a
+{{< hover label="xrdSchema" line="11" >}}property{{ }} of
+{{< hover label="xrdSchema" line="12" >}}spec{{ }}.
+
+The
+{{< hover label="xrdSchema" line="12" >}}spec{{ }} is also an
+{{< hover label="xrdSchema" line="13" >}}object{{ }} with
+{{< hover label="xrdSchema" line="14" >}}properties{{ }}.
+
+```yaml {label="xrdSchema"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+ # Removed for brevity
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+```
+
+{{< hint "tip" >}}
+For more information on the values allowed in a _composite resource definition_ view its schema with
+`kubectl explain xrd`
+{{< /hint >}}
+
+Now, define the custom API. Your custom API continues under the last
+{{}}properties{{ }} definition in the
+previous example.
+
+This custom API has one setting:
+
+* {{}}location{{ }} - where to deploy
+the resources, a choice of "EU" or "US."
+
+
+Users can't change any other settings of the storage bucket or Pub/Sub topic.
+
+The{{}}location{{ }}
+is a {{}}string{{ }}
+and matches the regular expression that's
+{{}}oneOf{{ }}
+{{}}EU{{ }}
+or
+{{}}US{{ }}.
+
+This API requires the setting
+{{}}location{{ }}.
+
+
+```yaml {label="customAPI"}
+# Removed for brevity
+# schema.openAPIV3Schema.type.properties.spec
+properties:
+ location:
+ type: string
+ oneOf:
+ - pattern: '^EU$'
+ - pattern: '^US$'
+required:
+ - location
+```
+
+### Enable claims to the API
+Tell this _XRD_ to offer a _claim_ by defining the _claim_ API endpoint under
+the _XRD_ {{}}spec{{< /hover >}}.
+
+{{< hint "tip" >}}
+Crossplane recommends a _Claim_
+{{}}kind{{ }} match the
+_Composite Resource Definition_ (XRD)
+{{}}kind{{ hover>}},
+without the preceding `X`.
+{{< /hint >}}
+
+
+```yaml {label="XRDclaim"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ names:
+ kind: XTopicBucket
+ plural: xtopicbuckets
+ claimNames:
+ kind: TopicBucket
+ plural: topicbuckets
+```
+
+{{}}
+The [Claims](#create-a-claim) section later in this guide discusses _claims_.
+{{< /hint >}}
+
+### Apply the composite resource definition
+Apply the complete _XRD_ to your Kubernetes cluster.
+
+
+```yaml {copy-lines="all"}
+cat <}}group{{ }}
+becomes the _composite resource_
+{{}}apiVersion{{ }}.
+
+The _XRD_ {{}}kind{{ }}
+is the _composite resource_
+{{}}kind{{ }}
+
+The _XRD_ API {{}}spec{{ }} defines the
+_composite resource_ {{}}spec{{ }}.
+
+The _XRD_ {{}}properties{{ }} section
+defines the options for the _composite resource_
+{{}}spec{{ }}.
+
+The one option is {{}}location{{ }}
+and it can be either {{}}EU{{ }} or
+{{}}US{{ }}.
+
+This _composite resource_ uses
+{{}}location: US{{ }}.
+
+### Apply the composite resource
+
+Apply the composite resource to the Kubernetes cluster.
+
+```yaml {label="xr", copy-lines="all"}
+cat <}}
+Use `kubectl get ` to view a specific `kind` of _composite resource_.
+View all _composite resources_ with `kubectl get composite`.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get XTopicBucket
+NAME SYNCED READY COMPOSITION AGE
+my-composite-resource True True topic-with-bucket 2m3s
+```
+
+Both `SYNCED` and `READY` are `True` when Crossplane created the GCP resources.
+
+Now look at the GCP storage `bucket` and Pub/Sub `topic` _managed resources_
+with `kubectl get bucket` and `kubectl get topic`.
+
+```shell {copy-lines="1"}
+kubectl get bucket
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-m6lbx True True my-composite-resource-m6lbx 4m34s
+```
+
+```shell {copy-lines="1"}
+kubectl get topics
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-88vzp True True my-composite-resource-88vzp 4m48s
+```
+
+The _composite resource_ automatically generated both _managed resources_.
+
+Using `kubectl describe` on a _managed resource_ shows the `Owner References` is
+the _composite resource_.
+
+```yaml {copy-lines="1"}
+kubectl describe bucket | grep "Owner References" -A5
+ Owner References:
+ API Version: custom-api.example.org/v1alpha1
+ Block Owner Deletion: true
+ Controller: true
+ Kind: XTopicBucket
+ Name: my-composite-resource
+```
+
+Each _composite resource_ creates and owns a unique set of _managed resources_.
+If you create a second _composite resource_ Crossplane creates a new storage
+`bucket` and Pub/Sub `topic`.
+
+```yaml {label="xr", copy-lines="all"}
+cat <}}
+Delete a specific _composite resource_ with
+`kubectl delete ` or
+`kubectl delete composite `.
+{{< /hint >}}
+
+Delete the second composition
+```shell
+kubectl delete XTopicBucket my-second-composite-resource
+```
+
+{{}}
+There may a delay in deleting the _managed resources_. Crossplane is making API
+calls to GCP and waits for GCP to confirm they deleted the resources before
+updating the state in Kubernetes.
+{{ }}
+
+Now a single bucket and topic exist.
+
+```shell {copy-lines="1"}
+kubectl get bucket
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-m6lbx True True my-composite-resource-m6lbx 11m
+```
+
+```shell {copy-lines="1"}
+kubectl get topic
+NAME READY SYNCED EXTERNAL-NAME AGE
+my-composite-resource-88vzp True True my-composite-resource-88vzp 11m
+```
+
+Delete the other _composite resource_ to remove the last `bucket` and `table`
+_managed resources_.
+
+```shell
+kubectl delete xtopicbucket my-composite-resource
+```
+
+_Composite resources_ are great for creating one or more related resources against
+a template, but all _composite resources_ exist at the Kubernetes "cluster
+level." There's no isolation between _composite resources_. Crossplane uses
+_claims_ to create resources with namespace isolation.
+
+## Create a claim
+
+_Claims_, just like _composite resources_ use the custom API defined in the
+_XRD_. Unlike a _composite resource_, Crossplane can create _claims_ in a
+namespace.
+
+### Create a new Kubernetes namespace
+Create a new namespace with `kubectl create namespace`.
+
+```shell
+kubectl create namespace test
+```
+
+Look at the _XRD_ to see the parameters for the _claim_.
+A _claim_ uses the same {{}}group{{ }}
+a _composite resource_ uses but a different
+{{}}kind{{ }}.
+
+```yaml {label="XRDclaim2"}
+apiVersion: apiextensions.crossplane.io/v1
+kind: CompositeResourceDefinition
+# Removed for brevity
+spec:
+# Removed for brevity
+ group: custom-api.example.org
+ claimNames:
+ kind: TopicBucket
+ plural: topicbuckets
+```
+
+Like the _composite resource_, create a new object with the
+{{}}custom-api.example.org{{ }} API
+endpoint.
+
+The _XRD_
+{{}}claimNames.kind{{ }} defines the
+{{}}kind{{ }}.
+
+The {{}}spec{{ }} uses the same
+API options as the _composite resource_.
+
+### Apply the claim
+Apply the _claim_ to your Kubernetes cluster.
+
+```yaml {label="claim", copy-lines="all"}
+cat <}}
+View claims with `kubectl get ` or use `kubectl get claim` to view all
+_claims_.
+{{ }}
+
+```shell {copy-lines="1"}
+kubectl get TopicBucket -n test
+NAME SYNCED READY CONNECTION-SECRET AGE
+claimed-topic-with-bucket True True 4m37s
+```
+
+When Crossplane creates a _claim_, a unique _composite resource_ is also
+created. View the new _composite resource_ with `kubectl get xtopicbucket`.
+
+```shell {copy-lines="1"}
+kubectl get xtopicbucket
+NAME SYNCED READY COMPOSITION AGE
+claimed-topic-with-bucket-7k2lj True True topic-with-bucket 4m58s
+```
+
+The _composite resource_ exists at the "cluster scope" while the _claim_ exists
+at the "namespace scope."
+
+Create a second namespace and a second claim.
+
+```shell {copy-lines="all"}
+kubectl create namespace test2
+cat <}}) of this guide covers
+_composition patches_ and making all this configuration portable in Crossplane
+_packages_.
+
+## Next steps
+* [**Continue to part 3**]({{< ref "provider-gcp-part-3">}})** to create a learn
+ about _patching_ resources and creating Crossplane _packages_.
+* Explore GCP resources that Crossplane can configure in the
+ [Provider CRD reference](https://marketplace.upbound.io/providers/upbound/provider-family-gcp/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with Crossplane users and contributors.
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-gcp-part-3.md b/content/v1.13/getting-started/provider-gcp-part-3.md
new file mode 100644
index 00000000..35ab7203
--- /dev/null
+++ b/content/v1.13/getting-started/provider-gcp-part-3.md
@@ -0,0 +1,659 @@
+---
+title: GCP 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 GCP.
+
+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 GCP Provider.
+
+```yaml {label="provider",copy-lines="all"}
+cat <}}
+The
+[GCP documentation](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)
+provides information on how to generate a service account JSON file.
+{{< /hint >}}
+
+4. Create a Kubernetes secret from the GCP JSON file
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic gcp-secret \
+-n crossplane-system \
+--from-file=creds=./gcp-credentials.json
+```
+
+5. 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 >}}
+```yaml {label="providerconfig",copy-lines="all"}
+cat <$@
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: gcp-secret
+ key: creds
+EOF
+```
+{{< /editCode >}}
+
+
+6. Create a _composition_
+```yaml {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
+{{}}topic{{ }}.
+
+```yaml {label="compResources"}
+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{{ }}.
+
+
+```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:
+ 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."
+
+
+
+```yaml {label="patch"}
+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_.
+
+```yaml
+cat <}}location{{}} to "EU."
+
+```yaml {label="claim"}
+cat <}}europe-central2{{< /hover >}}.
+
+```shell {copy-lines="1",label="topicLocation"}
+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{{ }}.
+
+```shell {copy-lines="1",label="bucketLocation"}
+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_.
+
+{{}}
+The _managed resources_ take up to 5 minutes to delete.
+{{< /hint >}}
+
+```shell
+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](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.
+
+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 command-line tool](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-gcp{{ }}
+version {{}}0.28.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-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.
+
+```yaml {copy-lines="all"}
+mkdir crossplane-gcp-quickstart
+cat < crossplane-gcp-quickstart/crossplane.yaml
+apiVersion: meta.pkg.crossplane.io/v1
+kind: Configuration
+metadata:
+ name: crossplane-gcp-quickstart
+spec:
+ crossplane:
+ version: ">=v1.12.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.
+
+```yaml {copy-lines="all"}
+cat < 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`.
+
+```yaml
+cat < 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.
+
+```shell
+wget "https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh"
+chmod +x install.sh
+./install.sh
+sudo mv kubectl-crossplane /usr/bin
+```
+
+Verify the Crossplane command-line installed with `kubectl crossplane --help`
+
+```shell
+kubectl crossplane --help
+Usage: kubectl 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 `kubectl crossplane` command to create an `.xpkg` file containing the
+custom APIs and Crossplane configuration.
+
+```shell
+kubectl crossplane build configuration -f crossplane-gcp-quickstart/ --name="crossplane-gcp-quickstart"
+```
+
+Now an `.xpkg` OCI image is inside the `crossplane-gcp-quickstart` directory.
+
+```shell
+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](https://marketplace.upbound.io/providers/upbound/provider-family-gcp/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with Crossplane users and contributors.
+* Read more about [Crossplane concepts]({{[}})
\ No newline at end of file
diff --git a/content/v1.13/getting-started/provider-gcp.md b/content/v1.13/getting-started/provider-gcp.md
new file mode 100644
index 00000000..cf1bb19e
--- /dev/null
+++ b/content/v1.13/getting-started/provider-gcp.md
@@ -0,0 +1,1255 @@
+---
+title: GCP Quickstart
+weight: 140
+---
+
+Connect Crossplane to GCP to create and manage cloud resources from Kubernetes
+with the
+[Upbound GCP Provider](https://marketplace.upbound.io/providers/upbound/provider-gcp).
+
+This guide is in three parts:
+* Part 1 walks through installing Crossplane, configuring the provider to
+authenticate to GCP and creating a _Managed Resource_ in GCP directly from your
+Kubernetes cluster. This shows Crossplane can communicate with GCP.
+* [Part 2]({{< ref "provider-gcp-part-2" >}}) creates a
+_Composite Resource Definition_ (XRD), _Composite Resource_ (XR) and a _Claim_
+(XRC) to show how to create and use custom APIs.
+* [Part 3]({{< ref "provider-gcp-part-3" >}}) demonstrates how to patch
+_Compositions_ with values used in a _Claim_ and how to build a Crossplane
+_Package_.
+## Prerequisites
+This quickstart requires:
+* a Kubernetes cluster with at least 6 GB of RAM
+* permissions to create pods and secrets in the Kubernetes cluster
+* [Helm](https://helm.sh/) version v3.2.0 or later
+* a GCP account with permissions to create a storage bucket
+* GCP [account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)
+* GCP [Project ID](https://support.google.com/googleapi/answer/7014113?hl=en)
+
+## Install Crossplane
+
+Crossplane installs into an existing Kubernetes cluster.
+
+{{< hint type="tip" >}}
+If you don't have a Kubernetes cluster create one locally with
+[Kind](https://kind.sigs.k8s.io/).
+{{< /hint >}}
+
+### Install the Crossplane Helm chart
+
+Helm enables Crossplane to install all its Kubernetes components through a
+_Helm Chart_.
+
+Enable the Crossplane Helm Chart repository:
+
+```shell
+helm repo add \
+crossplane-stable https://charts.crossplane.io/stable && helm repo update
+```
+
+Run the Helm dry-run to see all the Crossplane components Helm installs.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+```
+{{]}}
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--dry-run --debug \
+--namespace crossplane-system \
+--create-namespace
+install.go:193: [debug] Original chart version: ""
+install.go:210: [debug] CHART PATH: /home/vagrant/.cache/helm/repository/crossplane-1.10.1.tgz
+
+NAME: crossplane
+LAST DEPLOYED: Thu Jan 19 15:52:08 2023
+NAMESPACE: crossplane-system
+STATUS: pending-install
+REVISION: 1
+TEST SUITE: None
+USER-SUPPLIED VALUES:
+{}
+
+COMPUTED VALUES:
+affinity: {}
+args: {}
+configuration:
+ packages: []
+customAnnotations: {}
+customLabels: {}
+deploymentStrategy: RollingUpdate
+extraEnvVarsCrossplane: {}
+extraEnvVarsRBACManager: {}
+image:
+ pullPolicy: IfNotPresent
+ repository: crossplane/crossplane
+ tag: v1.10.1
+imagePullSecrets: {}
+leaderElection: true
+metrics:
+ enabled: false
+nodeSelector: {}
+packageCache:
+ medium: ""
+ pvc: ""
+ sizeLimit: 5Mi
+podSecurityContextCrossplane: {}
+podSecurityContextRBACManager: {}
+priorityClassName: ""
+provider:
+ packages: []
+rbacManager:
+ affinity: {}
+ args: {}
+ deploy: true
+ leaderElection: true
+ managementPolicy: All
+ nodeSelector: {}
+ replicas: 1
+ skipAggregatedClusterRoles: false
+ tolerations: {}
+registryCaBundleConfig: {}
+replicas: 1
+resourcesCrossplane:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+resourcesRBACManager:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+securityContextCrossplane:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+securityContextRBACManager:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+serviceAccount:
+ customAnnotations: {}
+tolerations: {}
+webhooks:
+ enabled: false
+
+HOOKS:
+MANIFEST:
+---
+# Source: crossplane/templates/rbac-manager-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+---
+# Source: crossplane/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:system:aggregate-to-crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ crossplane.io/scope: "system"
+ rbac.crossplane.io/aggregate-to-crossplane: "true"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ - services
+ verbs:
+ - "*"
+- apiGroups:
+ - apiextensions.crossplane.io
+ - pkg.crossplane.io
+ - secrets.crossplane.io
+ resources:
+ - "*"
+ verbs:
+ - "*"
+- apiGroups:
+ - extensions
+ - apps
+ resources:
+ - deployments
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - delete
+ - watch
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+- apiGroups:
+ - admissionregistration.k8s.io
+ resources:
+ - validatingwebhookconfigurations
+ - mutatingwebhookconfigurations
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-allowed-provider-permissions.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:allowed-provider-permissions
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-allowed-provider-permissions: "true"
+---
+# Source: crossplane/templates/rbac-manager-clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
+ - patch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - serviceaccounts
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources:
+ - compositeresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - pkg.crossplane.io
+ resources:
+ - providerrevisions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ - roles
+ verbs:
+ - get
+ - list
+ - watch
+ - create
+ - update
+ - patch
+ # The RBAC manager may grant access it does not have.
+ - escalate
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - bind
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterrolebindings
+ verbs:
+ - "*"
+- apiGroups:
+ - ""
+ - coordination.k8s.io
+ resources:
+ - configmaps
+ - leases
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - patch
+ - watch
+ - delete
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-edit
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-view
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane-browse
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+aggregationRule:
+ clusterRoleSelectors:
+ - matchLabels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane administrators have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane administrators must create provider credential secrets, and may
+# need to read or otherwise interact with connection secrets. They may also need
+# to create or annotate namespaces.
+- apiGroups: [""]
+ resources: [secrets, namespaces]
+ verbs: ["*"]
+# Crossplane administrators have access to view the roles that they may be able
+# to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterroles, roles]
+ verbs: [get, list, watch]
+# Crossplane administrators have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [clusterrolebindings, rolebindings]
+ verbs: ["*"]
+# Crossplane administrators have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+# Crossplane administrators have access to view CRDs in order to debug XRDs.
+- apiGroups: [apiextensions.k8s.io]
+ resources: [customresourcedefinitions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane editors must create provider credential secrets, and may need to
+# read or otherwise interact with connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane editors may see which namespaces exist, but not edit them.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane editors have full access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: ["*"]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-view
+ labels:
+ rbac.crossplane.io/aggregate-to-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane viewers may see which namespaces exist.
+- apiGroups: [""]
+ resources: [namespaces]
+ verbs: [get, list, watch]
+# Crossplane viewers have read-only access to built in Crossplane types.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+- apiGroups:
+ - pkg.crossplane.io
+ resources: [providers, configurations, providerrevisions, configurationrevisions]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-browse
+ labels:
+ rbac.crossplane.io/aggregate-to-browse: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane browsers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane browsers have read-only access to compositions and XRDs. This
+# allows them to discover and select an appropriate composition when creating a
+# resource claim.
+- apiGroups:
+ - apiextensions.crossplane.io
+ resources: ["*"]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+# The below ClusterRoles are aggregated to the namespaced RBAC roles created by
+# the Crossplane RBAC manager when it is running in --manage=All mode.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-admin
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-admin: "true"
+ rbac.crossplane.io/base-of-ns-admin: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace admins have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace admins may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+# Crossplane namespace admins have access to view the roles that they may be
+# able to grant to other subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [roles]
+ verbs: [get, list, watch]
+# Crossplane namespace admins have access to grant the access they have to other
+# subjects.
+- apiGroups: [rbac.authorization.k8s.io]
+ resources: [rolebindings]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-edit
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-edit: "true"
+ rbac.crossplane.io/base-of-ns-edit: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace editors have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+# Crossplane namespace editors may need to read or otherwise interact with
+# resource claim connection secrets.
+- apiGroups: [""]
+ resources: [secrets]
+ verbs: ["*"]
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: crossplane:aggregate-to-ns-view
+ labels:
+ rbac.crossplane.io/aggregate-to-ns-view: "true"
+ rbac.crossplane.io/base-of-ns-view: "true"
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+rules:
+# Crossplane namespace viewers have access to view events.
+- apiGroups: [""]
+ resources: [events]
+ verbs: [get, list, watch]
+---
+# Source: crossplane/templates/clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane
+subjects:
+- kind: ServiceAccount
+ name: crossplane
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-rbac-manager
+subjects:
+- kind: ServiceAccount
+ name: rbac-manager
+ namespace: crossplane-system
+---
+# Source: crossplane/templates/rbac-manager-managed-clusterroles.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: crossplane-admin
+ labels:
+ app: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: crossplane-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+ kind: Group
+ name: crossplane:masters
+---
+# Source: crossplane/templates/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: crossplane
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: POD_SERVICE_ACCOUNT
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.serviceAccountName
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - core
+ - start
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: LEADER_ELECTION
+ value: "true"
+ volumeMounts:
+ - mountPath: /cache
+ name: package-cache
+ volumes:
+ - name: package-cache
+ emptyDir:
+ medium:
+ sizeLimit: 5Mi
+---
+# Source: crossplane/templates/rbac-manager-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: crossplane-rbac-manager
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: crossplane-rbac-manager
+ release: crossplane
+ helm.sh/chart: crossplane-1.10.1
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/component: cloud-infrastructure-controller
+ app.kubernetes.io/part-of: crossplane
+ app.kubernetes.io/name: crossplane
+ app.kubernetes.io/instance: crossplane
+ app.kubernetes.io/version: "1.10.1"
+ spec:
+ securityContext:
+ {}
+ serviceAccountName: rbac-manager
+ initContainers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - init
+ imagePullPolicy: IfNotPresent
+ name: crossplane-init
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ containers:
+ - image: crossplane/crossplane:v1.10.1
+ args:
+ - rbac
+ - start
+ - --manage=All
+ - --provider-clusterrole=crossplane:allowed-provider-permissions
+ imagePullPolicy: IfNotPresent
+ name: crossplane
+ resources:
+ limits:
+ cpu: 100m
+ memory: 512Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ readOnlyRootFilesystem: true
+ runAsGroup: 65532
+ runAsUser: 65532
+ env:
+ - name: LEADER_ELECTION
+ value: "true"
+
+NOTES:
+Release: crossplane
+
+Chart Name: crossplane
+Chart Description: Crossplane is an open source Kubernetes add-on that enables
+platform teams to assemble infrastructure from multiple vendors, and expose
+higher level self-service APIs for application teams to consume.
+Chart Version: 1.10.1
+Chart Application Version: 1.10.1
+
+Kube Version: v1.24.9
+```
+{{< /expand >}}
+
+Install the Crossplane components using `helm install`.
+
+```shell
+helm install crossplane \
+crossplane-stable/crossplane \
+--namespace crossplane-system \
+--create-namespace
+```
+
+Verify Crossplane installed with `kubectl get pods`.
+
+```shell {copy-lines="1"}
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-644f4d5958-97m5v 1/1 Running 0 16s
+crossplane-rbac-manager-7f8ccd95f8-nkq78 1/1 Running 0 16s
+```
+
+Installing Crossplane creates new Kubernetes API end-points. Look at the new
+API end-points with `kubectl api-resources | grep crossplane`.
+
+```shell {label="grep",copy-lines="1"}
+kubectl api-resources | grep crossplane
+compositeresourcedefinitions xrd,xrds apiextensions.crossplane.io/v1 false CompositeResourceDefinition
+compositionrevisions apiextensions.crossplane.io/v1alpha1 false CompositionRevision
+compositions apiextensions.crossplane.io/v1 false Composition
+configurationrevisions pkg.crossplane.io/v1 false ConfigurationRevision
+configurations pkg.crossplane.io/v1 false Configuration
+controllerconfigs pkg.crossplane.io/v1alpha1 false ControllerConfig
+locks pkg.crossplane.io/v1beta1 false Lock
+providerrevisions pkg.crossplane.io/v1 false ProviderRevision
+providers pkg.crossplane.io/v1 false Provider
+storeconfigs secrets.crossplane.io/v1alpha1 false StoreConfig
+```
+
+## Install the GCP provider
+
+Install the provider into the Kubernetes cluster with a Kubernetes configuration
+file.
+
+```shell {label="provider",copy-lines="all"}
+cat <}}kind: Provider{{< /hover >}} uses the
+Crossplane `Provider` _Custom Resource Definition_ to connect your Kubernetes
+cluster to your cloud provider.
+
+Verify the provider installed with `kubectl get providers`.
+
+{{< hint type="note" >}}
+It may take up to five minutes for the provider to list `HEALTHY` as `True`.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+upbound-provider-gcp True True xpkg.upbound.io/upbound/provider-gcp:v0.28.0 107s
+```
+
+A provider installs their own Kubernetes _Custom Resource Definitions_ (CRDs).
+These CRDs allow you to create GCP resources directly inside Kubernetes.
+
+You can view the new CRDs with `kubectl get crds`. Every CRD maps to a unique
+GCP service Crossplane can provision and manage.
+
+
+{{< hint type="tip" >}}
+See details about all the supported CRDs in the
+[Upbound Marketplace](https://marketplace.upbound.io/providers/upbound/provider-family-gcp/).
+{{< /hint >}}
+
+## Create a Kubernetes secret for GCP
+The provider requires credentials to create and manage GCP resources. Providers
+use a Kubernetes _Secret_ to connect the credentials to the provider.
+
+First generate a Kubernetes _Secret_ from a Google Cloud service account JSON
+file and then configure the Provider to use it.
+
+{{< hint type="note" >}}
+Other authentication methods exist and are beyond the scope of this guide. The
+[Provider documentation](https://marketplace.upbound.io/providers/upbound/provider-gcp/latest/docs/configuration) contains information on alternative authentication methods.
+{{< /hint >}}
+
+### Generate a GCP service account JSON file
+For basic user authentication, use a Google Cloud service account JSON file.
+
+{{< hint type="tip" >}}
+The
+[GCP documentation](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)
+provides information on how to generate a service account JSON file.
+{{< /hint >}}
+
+Save this JSON file as `gcp-credentials.json`
+
+{{< hint type="note" >}}
+The [Configuration](https://marketplace.upbound.io/providers/upbound/provider-gcp/latest/docs/configuration) section of the Provider documentation describes other
+authentication methods.
+{{< /hint >}}
+
+### Create a Kubernetes secret with the GCP credentials
+A Kubernetes generic secret has a name and contents. Use
+{{< hover label="kube-create-secret" line="1">}}kubectl create secret{{< /hover >}}
+to generate the secret object named
+{{< hover label="kube-create-secret" line="2">}}gcp-secret{{< /hover >}} in the
+{{< hover label="kube-create-secret" line="3">}}crossplane-system{{ hover >}}
+namespace.
+Use the {{< hover label="kube-create-secret" line="4">}}--from-file={{}}
+argument to set the value to the contents of the
+{{< hover label="kube-create-secret" line="4">}}gcp-credentials.json{{< /hover >}}
+file.
+
+
+```shell {label="kube-create-secret",copy-lines="all"}
+kubectl create secret \
+generic gcp-secret \
+-n crossplane-system \
+--from-file=creds=./gcp-credentials.json
+```
+
+View the secret with `kubectl describe secret`
+
+{{< hint type="note" >}}
+The size may be larger if there are extra blank spaces in your JSON file.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl describe secret gcp-secret -n crossplane-system
+Name: gcp-secret
+Namespace: crossplane-system
+Labels:
+Annotations:
+
+Type: Opaque
+
+Data
+====
+creds: 2330 bytes
+```
+
+## Create a ProviderConfig
+A `ProviderConfig` customizes the settings of the GCP Provider.
+
+Apply the
+{{< hover label="providerconfig" line="2">}}ProviderConfig{{ hover >}}.
+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 >}}
+```yaml {label="providerconfig",copy-lines="all"}
+cat <$@
+ credentials:
+ source: Secret
+ secretRef:
+ namespace: crossplane-system
+ name: gcp-secret
+ key: creds
+EOF
+```
+{{< /editCode >}}
+
+This attaches the GCP credentials, saved as a Kubernetes secret, as a
+{{< hover label="providerconfig" line="10">}}secretRef{{ hover>}}.
+
+The {{< hover label="providerconfig" line="12">}}spec.credentials.secretRef.name{{< /hover >}} value is the name of the Kubernetes secret containing the GCP credentials in the
+{{< hover label="providerconfig" line="11">}}spec.credentials.secretRef.namespace{{< /hover >}}.
+
+## Create a managed resource
+A _managed resource_ is anything Crossplane creates and manages outside of the
+Kubernetes cluster. This creates a GCP storage bucket with Crossplane.
+The storage bucket is a _managed resource_.
+
+{{< hint type="note" >}}
+To generate a unique name use
+{{}}generateName{{ }} instead of `name`.
+{{< /hint >}}
+
+```yaml {label="xr",copy-lines="all"}
+cat <}}apiVersion{{< /hover >}} and
+{{< hover label="xr" line="3">}}kind{{}} are from the provider's CRDs.
+
+The {{< hover label="xr" line="10">}}spec.forProvider.location{{< /hover >}}
+tells GCP which GCP region to use when deploying resources. For a
+{{}}bucket{{ }} the
+region can be any
+[GCP multi-region location](https://cloud.google.com/storage/docs/locations#location-mr)
+
+Use `kubectl get bucket` to verify Crossplane created the bucket.
+
+{{< hint type="tip" >}}
+Crossplane created the bucket when the values `READY` and `SYNCED` are `True`.
+This may take up to 5 minutes.
+{{< /hint >}}
+
+```shell {copy-lines="1"}
+kubectl get bucket
+NAME READY SYNCED EXTERNAL-NAME AGE
+crossplane-bucket-8b7gw True True crossplane-bucket-8b7gw 2m2s
+```
+
+## Delete the managed resource
+Before shutting down your Kubernetes cluster, delete the GCP bucket just
+created.
+
+Use `kubectl delete bucket` to remove the bucket.
+
+{{}}
+Use the `--selector` flag to delete by label instead of by name.
+{{ }}
+
+```shell {copy-lines="1"}
+kubectl delete bucket --selector docs.crossplane.io/example=provider-gcp
+bucket.storage.gcp.upbound.io "crossplane-bucket-8b7gw" deleted
+```
+
+## Next steps
+* [**Continue to part 2**]({{< ref "provider-gcp-part-2">}}) to create a
+Crossplane _Composite Resource_ and _Claim_.
+* Explore GCP resources that can Crossplane can configure in the
+[Provider CRD reference](https://marketplace.upbound.io/providers/upbound/provider-family-gcp/).
+* Join the [Crossplane Slack](https://slack.crossplane.io/) and connect with
+Crossplane users and contributors.
\ No newline at end of file
diff --git a/content/v1.13/software/_index.md b/content/v1.13/software/_index.md
new file mode 100644
index 00000000..d527097f
--- /dev/null
+++ b/content/v1.13/software/_index.md
@@ -0,0 +1,11 @@
+---
+title: Install, Uninstall and Upgrade
+weight: 300
+description: Manage Crossplane installations
+---
+
+## [Install Crossplane](./install/)
+How to install and customize Crossplane in an existing Kubernetes cluster.
+
+## [Uninstall Crossplane](./uninstall/)
+How to remove Crossplane from a Kubernetes cluster.
\ No newline at end of file
diff --git a/content/v1.13/software/install.md b/content/v1.13/software/install.md
new file mode 100644
index 00000000..248d424c
--- /dev/null
+++ b/content/v1.13/software/install.md
@@ -0,0 +1,342 @@
+---
+title: Install Crossplane
+weight: 100
+---
+
+Crossplane installs into an existing Kubernetes cluster, creating the
+`Crossplane` pod, enabling the installation of Crossplane _Provider_ resources.
+
+{{< hint type="tip" >}}
+If you don't have a Kubernetes cluster create one locally with [Kind](https://kind.sigs.k8s.io/).
+{{< /hint >}}
+
+## Prerequisites
+* An actively [supported Kubernetes version](https://kubernetes.io/releases/patch-releases/#support-period)
+* [Helm](https://helm.sh/docs/intro/install/) version `v3.2.0` or later
+
+## Install Crossplane
+
+Install Crossplane using the Crossplane published _Helm chart_.
+
+### Add the Crossplane Helm repository
+
+Add the Crossplane repository with the `helm repo add` command.
+
+```shell
+helm repo add crossplane-stable https://charts.crossplane.io/stable
+```
+
+Update the
+local Helm chart cache with `helm repo update`.
+```shell
+helm repo update
+```
+
+### Install the Crossplane Helm chart
+
+Install the Crossplane Helm chart with `helm install`.
+
+{{< hint "tip" >}}
+View the changes Crossplane makes to your cluster with the
+`helm install --dry-run --debug` options. Helm shows what configurations it
+applies without making changes to the Kubernetes cluster.
+{{< /hint >}}
+
+Crossplane creates and installs into the `crossplane-system` namespace.
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace crossplane-stable/crossplane
+```
+
+View the installed Crossplane pods with `kubectl get pods -n crossplane-system`.
+
+```shell {copy-lines="1"}
+kubectl get pods -n crossplane-system
+NAME READY STATUS RESTARTS AGE
+crossplane-6d67f8cd9d-g2gjw 1/1 Running 0 26m
+crossplane-rbac-manager-86d9b5cf9f-2vc4s 1/1 Running 0 26m
+```
+
+{{< hint "tip" >}}
+Install a specific version of Crossplane with the `--version ` option. For example, to install version `1.10.0`:
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace crossplane-stable/crossplane \
+--version 1.10.0
+```
+{{< /hint >}}
+
+
+## Installed deployments
+Crossplane creates two Kubernetes _deployments_ in the `crossplane-system`
+namespace to deploy the Crossplane pods.
+
+```shell {copy-lines="1"}
+kubectl get deployments -n crossplane-system
+NAME READY UP-TO-DATE AVAILABLE AGE
+crossplane 1/1 1 1 8m13s
+crossplane-rbac-manager 1/1 1 1 8m13s
+```
+
+### Crossplane deployment
+The Crossplane deployment starts with the `crossplane-init container`. The
+`init` container installs the Crossplane _Custom Resource Definitions_ into the
+Kubernetes cluster.
+
+After the `init` container finishes, the `crossplane` pod manages two Kubernetes
+controllers.
+* The _Package Manager controller_ installs the
+provider and configuration packages.
+* The _Composition controller_ installs and manages the
+Crossplane _Composite Resource Definitions_, _Compositions_ and _Claims_.
+
+### Crossplane-rbac-manager deployment
+The `crossplane-rbac-manager` creates and manages Kubernetes _ClusterRoles_ for
+installed Crossplane _Provider_ and their _Custom Resource Definitions_.
+
+The
+[Crossplane RBAC Manger design document](https://github.com/crossplane/crossplane/blob/master/design/design-doc-rbac-manager.md)
+has more information on the installed _ClusterRoles_.
+
+## Installation options
+
+### Customize the Crossplane Helm chart
+Crossplane supports customizations at install time by configuring the Helm
+chart.
+
+Apply customizations with the command line or with a Helm _values_ file.
+
+
+
+{{}}
+{{< table "table table-hover table-striped table-sm">}}
+| Parameter | Description | Default |
+| --- | --- | --- |
+| `affinity` | Add `affinities` to the Crossplane pod deployment. | `{}` |
+| `args` | Add custom arguments to the Crossplane pod. | `[]` |
+| `configuration.packages` | A list of Configuration packages to install. | `[]` |
+| `customAnnotations` | Add custom `annotations` to the Crossplane pod deployment. | `{}` |
+| `customLabels` | Add custom `labels` to the Crossplane pod deployment. | `{}` |
+| `deploymentStrategy` | The deployment strategy for the Crossplane and RBAC Manager pods. | `"RollingUpdate"` |
+| `extraEnvVarsCrossplane` | Add custom environmental variables to the Crossplane pod deployment. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` |
+| `extraEnvVarsRBACManager` | Add custom environmental variables to the RBAC Manager pod deployment. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` |
+| `extraVolumeMountsCrossplane` | Add custom `volumeMounts` to the Crossplane pod. | `{}` |
+| `extraVolumesCrossplane` | Add custom `volumes` to the Crossplane pod. | `{}` |
+| `hostNetwork` | Enable `hostNetwork` for the Crossplane deployment. Caution: enabling `hostNetwork`` grants the Crossplane Pod access to the host network namespace. | `false` |
+| `image.pullPolicy` | The image pull policy used for Crossplane and RBAC Manager pods. | `"IfNotPresent"` |
+| `image.repository` | Repository for the Crossplane pod image. | `"crossplane/crossplane"` |
+| `image.tag` | The Crossplane image tag. Defaults to the value of `appVersion` in Chart.yaml. | `""` |
+| `imagePullSecrets` | The imagePullSecret names to add to the Crossplane ServiceAccount. | `{}` |
+| `leaderElection` | Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the Crossplane pod. | `true` |
+| `metrics.enabled` | Enable Prometheus path, port and scrape annotations and expose port 8080 for both the Crossplane and RBAC Manager pods. | `false` |
+| `nodeSelector` | Add `nodeSelectors` to the Crossplane pod deployment. | `{}` |
+| `packageCache.configMap` | The name of a ConfigMap to use as the package cache. Disables the default package cache `emptyDir` Volume. | `""` |
+| `packageCache.medium` | Set to `Memory` to hold the package cache in a RAM-backed file system. Useful for Crossplane development. | `""` |
+| `packageCache.pvc` | The name of a PersistentVolumeClaim to use as the package cache. Disables the default package cache `emptyDir` Volume. | `""` |
+| `packageCache.sizeLimit` | The size limit for the package cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. | `"20Mi"` |
+| `podSecurityContextCrossplane` | Add a custom `securityContext` to the Crossplane pod. | `{}` |
+| `podSecurityContextRBACManager` | Add a custom `securityContext` to the RBAC Manager pod. | `{}` |
+| `priorityClassName` | The PriorityClass name to apply to the Crossplane and RBAC Manager pods. | `""` |
+| `provider.packages` | A list of Provider packages to install. | `[]` |
+| `rbacManager.affinity` | Add `affinities` to the RBAC Manager pod deployment. | `{}` |
+| `rbacManager.args` | Add custom arguments to the RBAC Manager pod. | `[]` |
+| `rbacManager.deploy` | Deploy the RBAC Manager pod and its required roles. | `true` |
+| `rbacManager.leaderElection` | Enable [leader election](https://docs.crossplane.io/latest/concepts/pods/#leader-election) for the RBAC Manager pod. | `true` |
+| `rbacManager.managementPolicy` | Defines the Roles and ClusterRoles the RBAC Manager creates and manages. - A policy of `Basic` creates and binds Roles only for the Crossplane ServiceAccount, Provider ServiceAccounts and creates Crossplane ClusterRoles. - A policy of `All` includes all the `Basic` settings and also creates Crossplane Roles in all namespaces. - Read the Crossplane docs for more information on the [RBAC Roles and ClusterRoles](https://docs.crossplane.io/latest/concepts/pods/#crossplane-clusterroles) | `"Basic"` |
+| `rbacManager.nodeSelector` | Add `nodeSelectors` to the RBAC Manager pod deployment. | `{}` |
+| `rbacManager.replicas` | The number of RBAC Manager pod `replicas` to deploy. | `1` |
+| `rbacManager.skipAggregatedClusterRoles` | Don't install aggregated Crossplane ClusterRoles. | `false` |
+| `rbacManager.tolerations` | Add `tolerations` to the RBAC Manager pod deployment. | `[]` |
+| `registryCaBundleConfig.key` | The ConfigMap key containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. | `""` |
+| `registryCaBundleConfig.name` | The ConfigMap name containing a custom CA bundle to enable fetching packages from registries with unknown or untrusted certificates. | `""` |
+| `replicas` | The number of Crossplane pod `replicas` to deploy. | `1` |
+| `resourcesCrossplane.limits.cpu` | CPU resource limits for the Crossplane pod. | `"100m"` |
+| `resourcesCrossplane.limits.memory` | Memory resource limits for the Crossplane pod. | `"512Mi"` |
+| `resourcesCrossplane.requests.cpu` | CPU resource requests for the Crossplane pod. | `"100m"` |
+| `resourcesCrossplane.requests.memory` | Memory resource requests for the Crossplane pod. | `"256Mi"` |
+| `resourcesRBACManager.limits.cpu` | CPU resource limits for the RBAC Manager pod. | `"100m"` |
+| `resourcesRBACManager.limits.memory` | Memory resource limits for the RBAC Manager pod. | `"512Mi"` |
+| `resourcesRBACManager.requests.cpu` | CPU resource requests for the RBAC Manager pod. | `"100m"` |
+| `resourcesRBACManager.requests.memory` | Memory resource requests for the RBAC Manager pod. | `"256Mi"` |
+| `securityContextCrossplane.allowPrivilegeEscalation` | Enable `allowPrivilegeEscalation` for the Crossplane pod. | `false` |
+| `securityContextCrossplane.readOnlyRootFilesystem` | Set the Crossplane pod root file system as read-only. | `true` |
+| `securityContextCrossplane.runAsGroup` | The group ID used by the Crossplane pod. | `65532` |
+| `securityContextCrossplane.runAsUser` | The user ID used by the Crossplane pod. | `65532` |
+| `securityContextRBACManager.allowPrivilegeEscalation` | Enable `allowPrivilegeEscalation` for the RBAC Manager pod. | `false` |
+| `securityContextRBACManager.readOnlyRootFilesystem` | Set the RBAC Manager pod root file system as read-only. | `true` |
+| `securityContextRBACManager.runAsGroup` | The group ID used by the RBAC Manager pod. | `65532` |
+| `securityContextRBACManager.runAsUser` | The user ID used by the RBAC Manager pod. | `65532` |
+| `serviceAccount.customAnnotations` | Add custom `annotations` to the Crossplane ServiceAccount. | `{}` |
+| `tolerations` | Add `tolerations` to the Crossplane pod deployment. | `[]` |
+| `webhooks.enabled` | Enable webhooks for Crossplane and installed Provider packages. | `true` |
+| `xfn.args` | Add custom arguments to the Composite functions runner container. | `[]` |
+| `xfn.cache.configMap` | The name of a ConfigMap to use as the Composite function runner package cache. Disables the default Composite function runner package cache `emptyDir` Volume. | `""` |
+| `xfn.cache.medium` | Set to `Memory` to hold the Composite function runner package cache in a RAM-backed file system. Useful for Crossplane development. | `""` |
+| `xfn.cache.pvc` | The name of a PersistentVolumeClaim to use as the Composite function runner package cache. Disables the default Composite function runner package cache `emptyDir` Volume. | `""` |
+| `xfn.cache.sizeLimit` | The size limit for the Composite function runner package cache. If medium is `Memory` the `sizeLimit` can't exceed Node memory. | `"1Gi"` |
+| `xfn.enabled` | Enable the alpha Composition functions (`xfn`) sidecar container. Also requires Crossplane `args` value `--enable-composition-functions` set. | `false` |
+| `xfn.extraEnvVars` | Add custom environmental variables to the Composite function runner container. Replaces any `.` in a variable name with `_`. For example, `SAMPLE.KEY=value1` becomes `SAMPLE_KEY=value1`. | `{}` |
+| `xfn.image.pullPolicy` | Composite function runner container image pull policy. | `"IfNotPresent"` |
+| `xfn.image.repository` | Composite function runner container image. | `"crossplane/xfn"` |
+| `xfn.image.tag` | Composite function runner container image tag. Defaults to the value of `appVersion` in Chart.yaml. | `""` |
+| `xfn.resources.limits.cpu` | CPU resource limits for the Composite function runner container. | `"2000m"` |
+| `xfn.resources.limits.memory` | Memory resource limits for the Composite function runner container. | `"2Gi"` |
+| `xfn.resources.requests.cpu` | CPU resource requests for the Composite function runner container. | `"1000m"` |
+| `xfn.resources.requests.memory` | Memory resource requests for the Composite function runner container. | `"1Gi"` |
+| `xfn.securityContext.allowPrivilegeEscalation` | Enable `allowPrivilegeEscalation` for the Composite function runner container. | `false` |
+| `xfn.securityContext.capabilities.add` | Set Linux capabilities for the Composite function runner container. The default values allow the container to create an unprivileged user namespace for running Composite function containers. | `["SETUID","SETGID"]` |
+| `xfn.securityContext.readOnlyRootFilesystem` | Set the Composite function runner container root file system as read-only. | `true` |
+| `xfn.securityContext.runAsGroup` | The group ID used by the Composite function runner container. | `65532` |
+| `xfn.securityContext.runAsUser` | The user ID used by the Composite function runner container. | `65532` |
+| `xfn.securityContext.seccompProfile.type` | Apply a `seccompProfile` to the Composite function runner container. The default value allows the Composite function runner container permissions to use the `unshare` syscall. | `"Unconfined"` |
+{{< /table >}}
+{{< /expand >}}
+
+
+#### Command line customization
+
+Apply custom settings at the command line with
+`helm install crossplane --set =`.
+
+For example, to change the image pull policy:
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace \
+crossplane-stable/crossplane \
+--set image.pullPolicy=Always
+```
+
+Helm supports comma-seperated arguments.
+
+For example, to change the image pull policy and number of replicas:
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace \
+crossplane-stable/crossplane \
+--set image.pullPolicy=Always,replicas=2
+```
+
+#### Helm values file
+
+Apply custom settings in a Helm _values_ file with
+`helm install crossplane -f `.
+
+A YAML file defines the customized settings.
+
+For example, to change the image pull policy and number of replicas:
+
+Create a YAML with the customized settings.
+
+```yaml
+replicas: 2
+
+image:
+ pullPolicy: Always
+```
+
+Apply the file with `helm install`:
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace \
+crossplane-stable/crossplane \
+-f settings.yaml
+```
+
+#### Feature flags
+
+Crossplane introduces new features behind feature flags. By default
+alpha features are off. Crossplane enables beta features by default. To enable a
+feature flag, set the `args` value in the Helm chart. Available feature flags
+can be directly found by running `crossplane core start --help`, or by looking
+at the table below.
+
+{{< expand "Feature flags" >}}
+{{< table caption="Feature flags" >}}
+| Status | Flag | Description |
+| --- | --- | --- |
+| Beta | `--enable-composition-revisions` |Enable support for CompositionRevisions |
+| Alpha | `--enable-composition-functions` | Enable support for Composition Functions. |
+| Alpha | `--enable-composition-webhook-schema-validation` | Enable Composition validation using schemas. |
+| Alpha | `--enable-environment-configs` | Enable support for EnvironmentConfigs. |
+| Alpha | `--enable-external-secret-stores` | Enable support for External Secret Stores. |
+{{< /table >}}
+{{< /expand >}}
+
+Set these flags either in the `values.yaml` file or at install time using the
+`--set` flag, for example: `--set
+args=["--enable-composition-functions","--enable-composition-webhook-schema-validation"]`.
+
+### Install pre-release Crossplane versions
+Install a pre-release versions of Crossplane from the `master` Crossplane Helm channel.
+
+Versions in the `master` channel are under active development and may be unstable.
+
+{{< hint "warning" >}}
+Don't use Crossplane `master` releases in production. Only use `stable` channel.
+Only use `master` for testing and development.
+{{< /hint >}}
+
+
+#### Add the Crossplane master Helm repository
+
+Add the Crossplane repository with the `helm repo add` command.
+
+```shell
+helm repo add crossplane-master https://charts.crossplane.io/master/
+```
+
+Update the
+local Helm chart cache with `helm repo update`.
+```shell
+helm repo update
+```
+
+#### Install the Crossplane master Helm chart
+
+Install the Crossplane `master` Helm chart with `helm install`.
+
+{{< hint "tip" >}}
+View the changes Crossplane makes to your cluster with the
+`helm install --dry-run --debug` options. Helm shows what configurations it
+applies without making changes to the Kubernetes cluster.
+{{< /hint >}}
+
+Crossplane creates and installs into the `crossplane-system` namespace.
+
+```shell
+helm install crossplane \
+--namespace crossplane-system \
+--create-namespace crossplane-master/crossplane \
+--devel
+```
+
+## Crossplane distributions
+Third-party vendors may maintain their own Crossplane distributions. Vendor
+supported distribution may have features or tooling that isn't in the
+Community Crossplane distribution.
+
+The CNCF certified third-party distributions as
+"[conformant](https://github.com/cncf/crossplane-conformance)" with the
+Community Crossplane distribution.
+
+### Vendors
+Below are vendors providing conformant Crossplane distributions.
+
+#### Upbound
+Upbound, the founders of Crossplane, maintains a free and open source
+distribution of Crossplane called
+[Universal Crossplane](https://www.upbound.io/products/universal-crossplane)
+(`UXP`).
+
+Find information on UXP in the
+[Upbound UXP documentation](https://docs.upbound.io/uxp/install/).
diff --git a/content/v1.13/software/uninstall.md b/content/v1.13/software/uninstall.md
new file mode 100644
index 00000000..e3c76a1b
--- /dev/null
+++ b/content/v1.13/software/uninstall.md
@@ -0,0 +1,183 @@
+---
+title: Uninstall Crossplane
+weight: 300
+---
+
+{{}}
+Resources created by Crossplane aren't deleted if Crossplane isn't uninstalled
+in order.
+
+This can leave cloud resources running, requiring manual deletion.
+{{< /hint >}}
+
+## Ordered Crossplane uninstall
+Most Crossplane resources have dependencies on other Crossplane resources.
+
+For example, a _managed resource_ is dependent on the _provider_.
+
+Failure to delete Crossplane resources in order may prevent Crossplane from
+deleting provisioned external resources.
+
+Removing Crossplane resources should happen in the following order:
+1. Remove all _composite resource definitions_
+2. Remove all remaining _managed resources_
+3. Remove all _providers_
+
+Deleting the Crossplane pod removes remaining Crossplane components like _claims_.
+
+{{}}
+Collect an inventory of all external resources with `kubectl get managed`.
+
+Depending on the size of the Kubernetes API server and number of resources, this
+command may take minutes to return.
+
+{{}}
+
+```shell {copy-lines="1"}
+kubectl get managed
+NAME READY SYNCED EXTERNAL-NAME AGE
+securitygroup.ec2.aws.upbound.io/my-db-7mc7h-j84h8 True True sg-0da6e9c29113596b6 3m1s
+securitygroup.ec2.aws.upbound.io/my-db-8bhr2-9wsx9 True True sg-02695166f010ec05b 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+route.ec2.aws.upbound.io/my-db-7mc7h-vw985 True True r-rtb-05822b8df433e4e2b1080289494 3m1s
+route.ec2.aws.upbound.io/my-db-8bhr2-7m2wq False True 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+securitygrouprule.ec2.aws.upbound.io/my-db-7mc7h-mkd9s True True sgrule-778063708 3m1s
+securitygrouprule.ec2.aws.upbound.io/my-db-8bhr2-lzr89 False True 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+routetable.ec2.aws.upbound.io/my-db-7mc7h-mnqvm True True rtb-05822b8df433e4e2b 3m1s
+routetable.ec2.aws.upbound.io/my-db-8bhr2-dfhj6 True True rtb-02e875abd25658254 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+subnet.ec2.aws.upbound.io/my-db-7mc7h-7m49d True True subnet-0c1ab32c5ec129dd1 3m2s
+subnet.ec2.aws.upbound.io/my-db-7mc7h-9t64t True True subnet-07075c17c7a72f79e 3m2s
+subnet.ec2.aws.upbound.io/my-db-7mc7h-rs8t8 True True subnet-08e88e826a42e55b4 3m2s
+subnet.ec2.aws.upbound.io/my-db-8bhr2-9sjpx True True subnet-05d21c7b52f7ac8ca 2m26s
+subnet.ec2.aws.upbound.io/my-db-8bhr2-dvrxf True True subnet-0432310376b5d09de 2m26s
+subnet.ec2.aws.upbound.io/my-db-8bhr2-t7dpr True True subnet-0080fdcb6e9b70632 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+vpc.ec2.aws.upbound.io/my-db-7mc7h-ktbbh True True vpc-08d7dd84e0c12f33e 3m3s
+vpc.ec2.aws.upbound.io/my-db-8bhr2-mrh2x True True vpc-06994bf323fc1daea 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+internetgateway.ec2.aws.upbound.io/my-db-7mc7h-s2x4v True True igw-0189c4da07a3142dc 3m1s
+internetgateway.ec2.aws.upbound.io/my-db-8bhr2-q7dzl True True igw-01bf2a1dbbebf6a27 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+routetableassociation.ec2.aws.upbound.io/my-db-7mc7h-28qb4 True True rtbassoc-0718d680b5a0e68fe 3m1s
+routetableassociation.ec2.aws.upbound.io/my-db-7mc7h-9hdlr True True rtbassoc-0faaedb88c6e1518c 3m1s
+routetableassociation.ec2.aws.upbound.io/my-db-7mc7h-txhmz True True rtbassoc-0e5010724ca027864 3m1s
+routetableassociation.ec2.aws.upbound.io/my-db-8bhr2-bvgkt False True 2m26s
+routetableassociation.ec2.aws.upbound.io/my-db-8bhr2-d9gbg False True 2m26s
+routetableassociation.ec2.aws.upbound.io/my-db-8bhr2-k6k8m False True 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+instance.rds.aws.upbound.io/my-db-7mc7h-5d6w4 False True my-db-7mc7h-5d6w4 3m1s
+instance.rds.aws.upbound.io/my-db-8bhr2-tx9kf False True my-db-8bhr2-tx9kf 2m26s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+subnetgroup.rds.aws.upbound.io/my-db-7mc7h-8c8n9 True True my-db-7mc7h-8c8n9 3m2s
+subnetgroup.rds.aws.upbound.io/my-db-8bhr2-mc5ps True True my-db-8bhr2-mc5ps 2m27s
+
+NAME READY SYNCED EXTERNAL-NAME AGE
+bucket.s3.aws.upbound.io/crossplane-bucket-867737b10 True True
+crossplane-bucket-867737b10 5m26s
+```
+
+{{ }}
+{{< /hint >}}
+
+### Remove composite resource definitions
+Removing installed _composite resource definitions_ removes any
+_composite resources_ defined by the _composite resource definition_ and the
+_managed resourced_ they created.
+
+View the installed _composite resource definitions_ with `kubectl get xrd`.
+
+```shell {copy-lines="1"}
+kubectl get xrd
+NAME ESTABLISHED OFFERED AGE
+compositepostgresqlinstances.database.example.org True True 40s
+```
+
+Delete the _composite resource definitions_ with `kubectl delete xrd`.
+
+```shell
+kubectl delete xrd compositepostgresqlinstances.database.example.org
+```
+
+### Remove managed resources
+
+Manually delete any _managed resources_ manually created.
+
+Use `kubectl get managed` to view remaining _managed resources_.
+
+```shell {copy-lines="1"}
+kubectl get managed
+NAME READY SYNCED EXTERNAL-NAME AGE
+bucket.s3.aws.upbound.io/crossplane-bucket-867737b10 True True crossplane-bucket-867737b10 8h
+```
+
+Use `kubectl delete` to remove the resources.
+
+```shell
+kubectl delete bucket.s3.aws.upbound.io/crossplane-bucket-867737b10
+```
+
+### Remove Crossplane providers
+
+List the installed _providers_ with `kubectl get providers`.
+
+```shell {copy-lines="1"}
+kubectl get providers
+NAME INSTALLED HEALTHY PACKAGE AGE
+upbound-provider-aws True True xpkg.upbound.io/upbound/provider-aws:v0.27.0 8h
+```
+
+Remove the installed _providers_ with `kubectl delete provider`.
+
+```shell
+kubectl delete provider upbound-provider-aws
+```
+
+## Uninstall the Crossplane deployment
+
+Uninstall Crossplane using Helm with `helm uninstall`
+
+```shell
+helm uninstall crossplane --namespace crossplane-system
+```
+
+Verify Helm removed the Crossplane pods with `kubectl get pods`
+
+```shell
+kubectl get pods -n crossplane-system
+No resources found in crossplane-system namespace.
+```
+
+## Delete the Crossplane namespace
+
+When Helm installs Crossplane it creates the `crossplane-system` namespace. Helm
+doesn't uninstall this namespace with `helm uninstall`.
+
+Manually delete the Crossplane namespace with `kubectl delete namespace`.
+
+```shell
+kubectl delete namespace crossplane-system
+```
+
+Verify Kubernetes removed the namespace with `kubectl get namespaces`
+
+```shell
+kubectl get namespace
+NAME STATUS AGE
+default Active 2m45s
+kube-flannel Active 2m42s
+kube-node-lease Active 2m47s
+kube-public Active 2m47s
+kube-system Active 2m47s
+```
\ No newline at end of file
diff --git a/content/v1.13/software/upgrade.md b/content/v1.13/software/upgrade.md
new file mode 100644
index 00000000..345d817a
--- /dev/null
+++ b/content/v1.13/software/upgrade.md
@@ -0,0 +1,7 @@
+---
+title: Upgrade Crossplane
+weight: 200
+draft: true
+---
+
+Install, Uninstall, Upgrade