docs/content/master/getting-started/create-configuration.md

674 lines
20 KiB
Markdown

---
title: Create a Configuration
weight: 4
---
In the [previous section] we were able to create a PostgreSQL database because
we had installed a configuration package that defined the `PostgreSQLInstance`
type and a `Composition` of managed resources that mapped to it. Crossplane
allows you to define your own composite resources (XRs) and compositions, then
package them up to be easily distributed as OCI images. This allows you to
construct a reproducible platform that exposes infrastructure APIs at your
desired level of abstraction, and can be installed into any Crossplane cluster.
## Create a Configuration Directory
We are going to build the same configuration package that we previously
installed. It will consist of three files:
* `crossplane.yaml` - Metadata about the configuration.
* `definition.yaml` - The XRD.
* `composition.yaml` - The Composition.
Crossplane can create a configuration from any directory with a valid
`crossplane.yaml` metadata file at its root, and one or more XRDs or
Compositions. The directory structure does not matter, as long as the
`crossplane.yaml` file is at the root. Note that a configuration need not
contain one XRD and one composition - it could include only an XRD, only a
composition, several compositions, or any combination thereof.
Before we go any further, we must create a directory in which to build our
configuration:
```console
mkdir crossplane-config
cd crossplane-config
```
We'll create the aforementioned three files in this directory, then build them
into a package.
> Note that `definition.yaml` and `composition.yaml` could be created directly
> in the Crossplane cluster without packaging them into a configuration. This
> can be useful for testing compositions before pushing them to a registry.
## Create CompositeResourceDefinition
First we'll create a `CompositeResourceDefinition` (XRD) to define the schema of
our `XPostgreSQLInstance` and its `PostgreSQLInstance` resource claim.
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresqlinstances.database.example.org
spec:
group: database.example.org
names:
kind: XPostgreSQLInstance
plural: xpostgresqlinstances
claimNames:
kind: PostgreSQLInstance
plural: postgresqlinstances
connectionSecretKeys:
- username
- password
- endpoint
- port
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
storageGB:
type: integer
required:
- storageGB
required:
- parameters
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/definition.yaml
```
> You might notice that the XRD we created specifies both "names" and "claim
> names". This is because the composite resource it defines offers a composite
> resource claim (XRC).
## Create Compositions
Now we'll specify which managed resources our `XPostgreSQLInstance` XR
and its claim could be composed of, and how they should be configured. We do
this by defining a `Composition` that can satisfy the XR we defined above. In
this case, our `Composition` will specify how to provision a public PostgreSQL
instance on the chosen provider.
{{< tabs >}}
{{< tab "AWS (Default VPC)" >}}
> Note that this Composition will create an RDS instance using your default VPC,
> which may or may not allow connections from the internet depending on how it
> is configured. Select the AWS (New VPC) Composition if you wish to create an
> RDS instance that will allow traffic from the internet.
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xpostgresqlinstances.aws.database.example.org
labels:
provider: aws
guide: quickstart
vpc: default
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: rdsinstance
base:
apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
spec:
forProvider:
region: us-east-1
dbInstanceClass: db.t2.small
masterUsername: masteruser
engine: postgres
engineVersion: "12"
skipFinalSnapshotBeforeDeletion: true
publiclyAccessible: true
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
- fromFieldPath: "metadata.uid"
toFieldPath: "spec.writeConnectionSecretToRef.name"
transforms:
- type: string
string:
fmt: "%s-postgresql"
- fromFieldPath: "spec.parameters.storageGB"
toFieldPath: "spec.forProvider.allocatedStorage"
connectionDetails:
- fromConnectionSecretKey: username
- fromConnectionSecretKey: password
- fromConnectionSecretKey: endpoint
- fromConnectionSecretKey: port
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/aws/composition.yaml
```
{{< /tab >}}
{{< tab "AWS (New VPC)" >}}
> Note: this `Composition` for AWS also includes several networking managed
> resources that are required to provision a publicly available PostgreSQL
> instance. Composition enables scenarios such as this, as well as far more
> complex ones. See the [composition] documentation for more information.
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: vpcpostgresqlinstances.aws.database.example.org
labels:
provider: aws
guide: quickstart
vpc: new
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: vpc
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: VPC
spec:
forProvider:
region: us-east-1
cidrBlock: 192.168.0.0/16
enableDnsSupport: true
enableDnsHostNames: true
- name: subnet-a
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: Subnet
metadata:
labels:
zone: us-east-1a
spec:
forProvider:
region: us-east-1
cidrBlock: 192.168.64.0/18
vpcIdSelector:
matchControllerRef: true
availabilityZone: us-east-1a
- name: subnet-b
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: Subnet
metadata:
labels:
zone: us-east-1b
spec:
forProvider:
region: us-east-1
cidrBlock: 192.168.128.0/18
vpcIdSelector:
matchControllerRef: true
availabilityZone: us-east-1b
- name: subnet-c
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: Subnet
metadata:
labels:
zone: us-east-1c
spec:
forProvider:
region: us-east-1
cidrBlock: 192.168.192.0/18
vpcIdSelector:
matchControllerRef: true
availabilityZone: us-east-1c
- name: dbsubnetgroup
base:
apiVersion: database.aws.crossplane.io/v1beta1
kind: DBSubnetGroup
spec:
forProvider:
region: us-east-1
description: An excellent formation of subnetworks.
subnetIdSelector:
matchControllerRef: true
- name: internetgateway
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: InternetGateway
spec:
forProvider:
region: us-east-1
vpcIdSelector:
matchControllerRef: true
- name: routetable
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: RouteTable
spec:
forProvider:
region: us-east-1
vpcIdSelector:
matchControllerRef: true
routes:
- destinationCidrBlock: 0.0.0.0/0
gatewayIdSelector:
matchControllerRef: true
associations:
- subnetIdSelector:
matchLabels:
zone: us-east-1a
- subnetIdSelector:
matchLabels:
zone: us-east-1b
- subnetIdSelector:
matchLabels:
zone: us-east-1c
- name: securitygroup
base:
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: SecurityGroup
spec:
forProvider:
region: us-east-1
vpcIdSelector:
matchControllerRef: true
groupName: crossplane-getting-started
description: Allow access to PostgreSQL
ingress:
- fromPort: 5432
toPort: 5432
ipProtocol: tcp
ipRanges:
- cidrIp: 0.0.0.0/0
description: Everywhere
- name: rdsinstance
base:
apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
spec:
forProvider:
region: us-east-1
dbSubnetGroupNameSelector:
matchControllerRef: true
vpcSecurityGroupIDSelector:
matchControllerRef: true
dbInstanceClass: db.t2.small
masterUsername: masteruser
engine: postgres
engineVersion: "12"
skipFinalSnapshotBeforeDeletion: true
publiclyAccessible: true
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
- fromFieldPath: "metadata.uid"
toFieldPath: "spec.writeConnectionSecretToRef.name"
transforms:
- type: string
string:
fmt: "%s-postgresql"
- fromFieldPath: "spec.parameters.storageGB"
toFieldPath: "spec.forProvider.allocatedStorage"
connectionDetails:
- fromConnectionSecretKey: username
- fromConnectionSecretKey: password
- fromConnectionSecretKey: endpoint
- fromConnectionSecretKey: port
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/aws-with-vpc/composition.yaml
```
{{< /tab >}}
{{< tab "GCP" >}}
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xpostgresqlinstances.gcp.database.example.org
labels:
provider: gcp
guide: quickstart
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: cloudsqlinstance
base:
apiVersion: database.gcp.crossplane.io/v1beta1
kind: CloudSQLInstance
spec:
forProvider:
databaseVersion: POSTGRES_12
region: us-central1
settings:
tier: db-custom-1-3840
dataDiskType: PD_SSD
ipConfiguration:
ipv4Enabled: true
authorizedNetworks:
- value: "0.0.0.0/0"
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
- fromFieldPath: "metadata.uid"
toFieldPath: "spec.writeConnectionSecretToRef.name"
transforms:
- type: string
string:
fmt: "%s-postgresql"
- fromFieldPath: "spec.parameters.storageGB"
toFieldPath: "spec.forProvider.settings.dataDiskSizeGb"
connectionDetails:
- fromConnectionSecretKey: username
- fromConnectionSecretKey: password
- fromConnectionSecretKey: endpoint
- type: FromValue
name: port
value: "5432"
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/gcp/composition.yaml
```
{{< /tab >}}
{{< tab "Azure" >}}
> Note: the `Composition` for Azure also includes a `ResourceGroup` and
> `PostgreSQLServerFirewallRule` that are required to provision a publicly
> available PostgreSQL instance on Azure. Composition enables scenarios such as
> this, as well as far more complex ones. See the [composition] documentation
> for more information.
```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xpostgresqlinstances.azure.database.example.org
labels:
provider: azure
guide: quickstart
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: database.example.org/v1alpha1
kind: XPostgreSQLInstance
resources:
- name: resourcegroup
base:
apiVersion: azure.crossplane.io/v1alpha3
kind: ResourceGroup
spec:
location: West US 2
- name: postgresqlserver
base:
apiVersion: database.azure.crossplane.io/v1beta1
kind: PostgreSQLServer
spec:
forProvider:
administratorLogin: myadmin
resourceGroupNameSelector:
matchControllerRef: true
location: West US 2
sslEnforcement: Disabled
version: "9.6"
sku:
tier: GeneralPurpose
capacity: 2
family: Gen5
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
- fromFieldPath: "metadata.uid"
toFieldPath: "spec.writeConnectionSecretToRef.name"
transforms:
- type: string
string:
fmt: "%s-postgresql"
- fromFieldPath: "spec.parameters.storageGB"
toFieldPath: "spec.forProvider.storageProfile.storageMB"
transforms:
- type: math
math:
multiply: 1024
connectionDetails:
- fromConnectionSecretKey: username
- fromConnectionSecretKey: password
- fromConnectionSecretKey: endpoint
- type: FromValue
name: port
value: "5432"
- name: firewallrule
base:
apiVersion: database.azure.crossplane.io/v1alpha3
kind: PostgreSQLServerFirewallRule
spec:
forProvider:
serverNameSelector:
matchControllerRef: true
resourceGroupNameSelector:
matchControllerRef: true
properties:
startIpAddress: 0.0.0.0
endIpAddress: 255.255.255.254
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/azure/composition.yaml
```
{{< /tab >}}
{{< /tabs >}}
## Build and Push The Configuration
Finally, we'll author our metadata file then build and push our configuration
so that Crossplane users may install it.
> Note that Crossplane pushes packages to an OCI registry - currently [Docker
> Hub] by default. You may need to run `docker login` before you are able to
> push a package.
{{< tabs >}}
{{< tab "AWS (Default VPC)" >}}
```yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: getting-started-with-aws
annotations:
guide: quickstart
provider: aws
vpc: default
spec:
crossplane:
version: ">=v1.4.0-0"
dependsOn:
- provider: xpkg.upbound.io/crossplane-contrib/provider-aws
version: ">=v0.18.2"
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/aws/crossplane.yaml
kubectl crossplane build configuration
```
You should see a file in your working directory with a `.xpkg` extension. The
Crossplane CLI will automatically tag and push it to the registry of your
choosing in the next step if it is the only `.xpkg` in the directory. Otherwise
you may specify a specific package by using the `-f` flag.
```console
# Set this to the Docker Hub username or OCI registry you wish to use.
REG=my-package-repo
kubectl crossplane push configuration ${REG}/getting-started-with-aws:v1.10.1
```
> Note that the Crossplane CLI will not follow symbolic links for files in the
> root package directory.
{{< /tab >}}
{{< tab "AWS (New VPC)" >}}
```yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: getting-started-with-aws-with-vpc
annotations:
guide: quickstart
provider: aws
vpc: new
spec:
crossplane:
version: ">=v1.4.0-0"
dependsOn:
- provider: xpkg.upbound.io/crossplane-contrib/provider-aws
version: ">=v0.18.2"
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/aws-with-vpc/crossplane.yaml
kubectl crossplane build configuration
```
You should see a file in your working directory with a `.xpkg` extension. The
Crossplane CLI will automatically tag and push it to the registry of your
choosing in the next step if it is the only `.xpkg` in the directory. Otherwise
you may specify a specific package by using the `-f` flag.
```console
# Set this to the Docker Hub username or OCI registry you wish to use.
REG=my-package-repo
kubectl crossplane push configuration ${REG}/getting-started-with-aws-with-vpc:v1.10.1
```
> Note that the Crossplane CLI will not follow symbolic links for files in the
> root package directory.
{{< /tab >}}
{{< tab "GCP" >}}
```yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: getting-started-with-gcp
annotations:
guide: quickstart
provider: gcp
spec:
crossplane:
version: ">=v1.4.0-0"
dependsOn:
- provider: xpkg.upbound.io/crossplane-contrib/provider-gcp
version: ">=v0.13.0"
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/gcp/crossplane.yaml
kubectl crossplane build configuration
```
You should see a file in your working directory with a `.xpkg` extension. The
Crossplane CLI will automatically tag and push it to the registry of your
choosing in the next step if it is the only `.xpkg` in the directory. Otherwise
you may specify a specific package by using the `-f` flag.
```console
# Set this to the Docker Hub username or OCI registry you wish to use.
REG=my-package-repo
kubectl crossplane push configuration ${REG}/getting-started-with-gcp:v1.10.1
```
> Note that the Crossplane CLI will not follow symbolic links for files in the
> root package directory.
{{< /tab >}}
{{< tab "Azure" >}}
```yaml
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
metadata:
name: getting-started-with-azure
annotations:
guide: quickstart
provider: azure
spec:
crossplane:
version: ">=v1.4.0-0"
dependsOn:
- provider: xpkg.upbound.io/crossplane-contrib/provider-azure
version: ">=v0.13.0"
```
```console
curl -OL https://raw.githubusercontent.com/crossplane/crossplane/master/docs/snippets/package/azure/crossplane.yaml
kubectl crossplane build configuration
```
You should see a file in your working directory with a `.xpkg` extension. The
Crossplane CLI will automatically tag and push it to the registry of your
choosing in the next step if it is the only `.xpkg` in the directory. Otherwise
you may specify a specific package by using the `-f` flag.
```console
# Set this to the Docker Hub username or OCI registry you wish to use.
REG=my-package-repo
kubectl crossplane push configuration ${REG}/getting-started-with-azure:v1.10.1
```
> Note that the Crossplane CLI will not follow symbolic links for files in the
> root package directory.
{{< /tab >}}
{{< /tabs >}}
That's it! You've now built and pushed your package. Take a look at the
Crossplane [packages] documentation for more information about installing and
working with packages, or read about other Crossplane [concepts].
## Clean Up
To clean up, you can simply delete your package directory:
```console
cd ..
rm -rf crossplane-config
```
<!-- Named Links -->
[previous section]: {{<ref "provision-infrastructure" >}}
[composed]: {{<ref "../concepts/composition" >}}
[composition]: {{<ref "../concepts/composition" >}}
[Docker Hub]: https://hub.docker.com/
[packages]: {{<ref "../concepts/packages" >}}
[concepts]: {{<ref "../concepts" >}}