Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ XPKG_REG_ORGS_NO_PROMOTE ?= xpkg.upbound.io/upbound
XPKGS = $(PROJECT_NAME)
-include build/makelib/xpkg.mk

CROSSPLANE_NAMESPACE = upbound-system
CROSSPLANE_ARGS = "--enable-usages"
CROSSPLANE_NAMESPACE = crossplane-system
CROSSPLANE_ARGS = ""
-include build/makelib/local.xpkg.mk
-include build/makelib/controlplane.mk

Expand Down Expand Up @@ -65,7 +65,7 @@ build.init: $(UP)
# - UPTEST_DATASOURCE_PATH (optional), see https://github.com/upbound/uptest#injecting-dynamic-values-and-datasource
uptest: $(UPTEST) $(KUBECTL) $(KUTTL)
@$(INFO) running automated tests
@KUBECTL=$(KUBECTL) KUTTL=$(KUTTL) CROSSPLANE_NAMESPACE=$(CROSSPLANE_NAMESPACE) $(UPTEST) e2e examples/XAccountScaffold/xr.yaml,examples/XCluster/xr.yaml,examples/XCompositeCluster/xr.yaml,examples/XDatabase/xr.yaml,examples/XNetwork/xr.yaml,examples/XNodePool/xr.yaml,examples/XServiceAccount/xr.yaml,examples/XSubnetwork/xr.yaml --data-source="${UPTEST_DATASOURCE_PATH}" --setup-script=test/setup.sh --default-timeout=2400 || $(FAIL)
@KUBECTL=$(KUBECTL) KUTTL=$(KUTTL) CROSSPLANE_NAMESPACE=$(CROSSPLANE_NAMESPACE) $(UPTEST) e2e examples/accountscaffold/xr.yaml,examples/cluster/xr.yaml,examples/compositecluster/xr.yaml,examples/database/xr.yaml,examples/network/xr.yaml,examples/nodepool/xr.yaml,examples/serviceaccount/xr.yaml,examples/subnetwork/xr.yaml --data-source="${UPTEST_DATASOURCE_PATH}" --setup-script=test/setup.sh --default-timeout=2400 || $(FAIL)
@$(OK) running automated tests

# This target requires the following environment variables to be set:
Expand All @@ -84,7 +84,7 @@ render:
if [[ "$$COMPOSITION" == "null" || "$$FUNCTION" == "null" ]]; then \
continue; \
fi; \
crossplane beta render $$file $$COMPOSITION $$FUNCTION -x -r; \
crossplane render $$file $$COMPOSITION $$FUNCTION -x -r; \
done

yamllint:
Expand Down
104 changes: 63 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# configuration-getting-started
An introductory example to Crossplane and Compositions using provider-nop. This will enable provisioning of several different fake resource types.

This repository contains a reference configuration for [Crossplane](https://crossplane.io). This configuration is built with [provider-nop](https://marketplace.upbound.io/providers/crossplane-contrib/provider-nop), a Crossplane provider that simulates the creation of external resources.
An introductory example to Crossplane and Compositions using provider-nop. This will enable provisioning of several different fake resource types.

This repository contains a reference configuration for [Crossplane](https://crossplane.io) **v2**. This configuration is built with [provider-nop](https://marketplace.upbound.io/providers/crossplane-contrib/provider-nop), a Crossplane provider that simulates the creation of external resources. All composite resources are **namespaced** — claims are not used (they don't exist in Crossplane v2).

## Overview

This platform offers APIs for setting up a variety of basic resources that mirror what you'd find in a Cloud Service Provider such as AWS, Azure, or GCP. The resource types include:

* [Cluster](apis/primitives/XCluster/), a resource that loosely represents a Kubernetes cluster.
* [NodePool](apis/primitives/XNodePool/), a resource that loosely represents a Nodepool in a Kubernetes cluster.
* [Database](apis/primitives/XDatabase/), a resource that loosely represents a cloud database.
* [Network](apis/primitives/XNetwork/), a resource that loosely represents a cloud network resource.
* [Subnetwork](apis/primitives/XSubnetwork/), a resource that loosely represents a subnetwork resource within a cloud network.
* [Service Account](apis/primitives/XServiceAccount/), a resource that loosely represents a service account in the cloud.
* [Cluster](apis/primitives/cluster/), a resource that loosely represents a Kubernetes cluster.
* [NodePool](apis/primitives/nodepool/), a resource that loosely represents a Nodepool in a Kubernetes cluster.
* [Database](apis/primitives/database/), a resource that loosely represents a cloud database.
* [Network](apis/primitives/network/), a resource that loosely represents a cloud network resource.
* [Subnetwork](apis/primitives/subnetwork/), a resource that loosely represents a subnetwork resource within a cloud network.
* [ServiceAccount](apis/primitives/serviceaccount/), a resource that loosely represents a service account in the cloud.

This configuration also demonstrates the power of Crossplane to build abstractions called "compositions", which assemble multiple basic resources into a more complex resource. These are demonstrated with:

* [CompositeCluster](apis/composition-basics/XCompositeCluster/), a resource abstraction that composes a cluster, nodepool, network, subnetwork, and service account.
* [AccountScaffold](apis/composition-basics/XAccountScaffold/), a resource abstraction that composes a service account, network, and subnetwork.
* [CompositeCluster](apis/composition-basics/compositecluster/), a resource abstraction that composes a cluster, nodepool, network, subnetwork, and service account.
* [AccountScaffold](apis/composition-basics/accountscaffold/), a resource abstraction that composes a service account, network, and subnetwork.

Learn more about Composite Resources in the [Crossplane
Docs](https://docs.crossplane.io/latest/concepts/compositions/).
Expand All @@ -27,79 +27,101 @@ Docs](https://docs.crossplane.io/latest/concepts/compositions/).

### Prerequisites

Before we can install the reference platform we should install the `up` CLI.
This is a utility that makes following this quickstart guide easier. Everything
described here can also be done in a declarative approach - which we highly
recommend for any production type use-case.
<!-- TODO enhance this guide: Getting ready for Gitops -->
You need a running Crossplane v2 control plane. You can create a managed control plane on [Upbound](https://console.upbound.io), or run upstream Crossplane locally with [kind](https://kind.sigs.k8s.io/).

To install `up` run this install script:
Install the `up` CLI:
```console
curl -sL https://cli.upbound.io | sh
```
See [up docs](https://docs.upbound.io/cli/) for more install options.

We need a running Crossplane control plane to install our instance. Use [Upbound](https://console.upbound.io) to create a managed control plane. You can [create an account](https://accounts.upbound.io/register) and start a free 30 day trial if you haven't signed up for Upbound before.
Alternatively, install the Crossplane CLI:
```console
curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh
```

### Install the Getting Started configuration

Now you can install this reference platform. It's packaged as a [Crossplane
configuration package](https://docs.crossplane.io/latest/concepts/packages/)
so there is a single command to install it:
Install the configuration package:

```console
up ctp configuration install xpkg.upbound.io/upbound/configuration-getting-started:v0.1.0
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: configuration-getting-started
spec:
package: xpkg.upbound.io/upbound/configuration-getting-started:v1.0.0
EOF
```

Validate the install by inspecting the provider and configuration packages:
Wait for the configuration and all dependencies to become healthy:
```console
kubectl get providers,providerrevision
kubectl get configurations,providers,functions
```

kubectl get configurations,configurationrevisions
Verify all XRDs are established:
```console
kubectl get xrd
```

Check the
[marketplace](https://marketplace.upbound.io/configurations/upbound/configuration-getting-started/)
for the latest version of this platform.
You should see 8 XRDs, all with `ESTABLISHED=True` and an empty `OFFERED` column (no claims in v2).

## Using the Getting Started configuration

🎉 Congratulations. You have just installed your first Crossplane-powered platform!

You can now use the managed control plane to request resources which will simulate getting provisioned in an external cloud service. You do this by creating "claims" against the APIs available on yuor control palne. In our example here we simply create the claims directly:
All resources are namespaced in Crossplane v2 — you apply XRs directly to a namespace instead of creating claims.

Create a custom defined cluster:
```console
kubectl apply -f examples/XCluster/claim.yaml
kubectl apply -f examples/cluster/xr.yaml
```

Create a custom defined database:
```console
kubectl apply -f examples/XDatabase/claim.yaml
kubectl apply -f examples/database/xr.yaml
```

You can verify the status by inspecting the claims, composites and managed
resources:
Create a composite cluster (composes 5 nested XRs):
```console
kubectl apply -f examples/compositecluster/xr.yaml
```

You can verify the status by inspecting the composite and managed resources:
```console
kubectl get claim,composite,managed
kubectl get managed,composite -n default
```

To delete the provisioned resources you would simply delete the claims:
To delete the provisioned resources:
```console
kubectl delete -f examples/cluster/xr.yaml
kubectl delete -f examples/database/xr.yaml
kubectl delete -f examples/compositecluster/xr.yaml
```

To uninstall the configuration:
```console
kubectl delete -f examples/XCluster/claim.yaml,examples/XDatabase/claim.yaml
kubectl delete configurations.pkg.crossplane.io configuration-getting-started
```

To uninstall the provider & platform configuration:
## Local development

Render compositions locally:

```console
kubectl delete configurations.pkg.crossplane.io configuration-getting-started
make render
```

Run end-to-end tests:

```console
make e2e
```

> **Note**: The `render` target uses the `crossplane` CLI under the hood (`crossplane render`), which has no `up` equivalent for classic configuration packages.

## Next Steps

We recommend you check out of one of Upbound's platform reference architectures to learn how to use Crossplane to provision real external resources, such as in a Cloud Serice Provider's environment. Have a look:
We recommend you check out one of Upbound's platform reference architectures to learn how to use Crossplane to provision real external resources:

* [AWS reference platform](https://github.com/upbound/platform-ref-aws/)
* [Azure reference platform](https://github.com/upbound/platform-ref-azure/)
Expand All @@ -109,4 +131,4 @@ We recommend you check out of one of Upbound's platform reference architectures

For any questions, thoughts and comments don't hesitate to [reach
out](https://www.upbound.io/contact) or drop by
[slack.crossplane.io](https://slack.crossplane.io), and say hi!
[slack.crossplane.io](https://slack.crossplane.io), and say hi!
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xaccountscaffolds.platform.acme.co
name: accountscaffolds.platform.acme.co
spec:
compositeTypeRef:
apiVersion: platform.acme.co/v1alpha1
kind: XAccountScaffold
kind: AccountScaffold
mode: Pipeline
pipeline:
- step: compose
Expand All @@ -24,23 +24,26 @@ spec:
oxr = option("params").oxr
items = [{
apiVersion: "platform.acme.co/v1alpha1"
kind: "XServiceAccount"
kind: "ServiceAccount"
metadata.name = "{}-sa".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
displayName: oxr.spec.parameters.name
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XNetwork"
kind: "Network"
metadata.name = "{}-net".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
autoCreateSubnetworks: True
routingMode: "GLOBAL"
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XSubnetwork"
kind: "Subnetwork"
metadata.name = "{}-subnet".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
ipCidrRange: "10.2.0.0/16"
networkRef.name: "{}-net".format(oxr.metadata.name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: xaccountscaffolds.platform.acme.co
name: accountscaffolds.platform.acme.co
spec:
scope: Namespaced
group: platform.acme.co
names:
kind: XAccountScaffold
plural: xaccountscaffolds
claimNames:
kind: AccountScaffold
plural: accountscaffolds
versions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xcompositeclusters.platform.acme.co
name: compositeclusters.platform.acme.co
spec:
compositeTypeRef:
apiVersion: platform.acme.co/v1alpha1
kind: XCompositeCluster
kind: CompositeCluster
mode: Pipeline
pipeline:
- step: compose
Expand All @@ -24,8 +24,9 @@ spec:
oxr = option("params").oxr
items = [{
apiVersion: "platform.acme.co/v1alpha1"
kind: "XCluster"
kind: "Cluster"
metadata.name = "{}-cluster".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
initialNodeCount: oxr.spec.parameters.nodeCount
networkRef.name: "{}-net".format(oxr.metadata.name)
Expand All @@ -35,15 +36,17 @@ spec:
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XServiceAccount"
kind: "ServiceAccount"
metadata.name = "{}-sa".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
displayName: "{} service account".format(oxr.metadata.name)
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XNodePool"
kind: "NodePool"
metadata.name = "{}-nodepool".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
nodeConfig = [{
machineType: oxr.spec.parameters.size
Expand All @@ -55,16 +58,18 @@ spec:
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XNetwork"
kind: "Network"
metadata.name = "{}-net".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
autoCreateSubnetworks: True
routingMode: "GLOBAL"
}
}, {
apiVersion: "platform.acme.co/v1alpha1"
kind: "XSubnetwork"
kind: "Subnetwork"
metadata.name = "{}-subnet".format(oxr.metadata.name)
metadata.namespace = oxr.metadata.namespace
spec.parameters = {
ipCidrRange: "10.2.0.0/16"
networkRef.name: "{}-net".format(oxr.metadata.name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: xcompositeclusters.platform.acme.co
name: compositeclusters.platform.acme.co
spec:
scope: Namespaced
group: platform.acme.co
names:
kind: XCompositeCluster
plural: xcompositeclusters
claimNames:
kind: CompositeCluster
plural: compositeclusters
versions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xclusters.platform.acme.co
name: clusters.platform.acme.co
spec:
compositeTypeRef:
apiVersion: platform.acme.co/v1alpha1
kind: XCluster
kind: Cluster
mode: Pipeline
pipeline:
- step: compose
Expand Down Expand Up @@ -41,6 +41,7 @@ spec:
apiVersion: "nop.crossplane.io/v1alpha1"
kind: "NopResource"
metadata.name = oxr.metadata.name
metadata.namespace = oxr.metadata.namespace
spec.forProvider = {
conditionAfter = [readyCondition] if readyCondition else [statusCondition]
fields = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: xclusters.platform.acme.co
name: clusters.platform.acme.co
spec:
scope: Namespaced
group: platform.acme.co
names:
kind: XCluster
plural: xclusters
claimNames:
kind: Cluster
plural: clusters
versions:
Expand Down
Loading
Loading