This repository has been archived by the owner on Jun 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An example sketch of a platform configuration
Signed-off-by: Nic Cope <negz@rk0n.org>
- Loading branch information
Showing
10 changed files
with
833 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,100 @@ | ||
# aac | ||
Platform API as Configuration | ||
# Platform API as Configuration | ||
|
||
This repository contains configuration for the Cloud Native Platform (CNP). CNP | ||
consists of a series of Crossplane packages that are automatically built and | ||
pushed to the Upbound Cloud Registry by CI/CD when commits are merged to this | ||
repository. The following packages exist: | ||
|
||
* `eks.clusters.cnp.example.org` - Defines a composite resource representing an | ||
EKS cluster (including all network and IAM dependencies). | ||
* `fluentbits.charts.cnp.example.org` - Defines a composite resource | ||
representing a Helm release of the Fluent Bit logging daemonset. | ||
* `clusters.cnp.example.org` - Defines a composite resource representing a 'CNP | ||
Kubernetes Cluster'. This cluster is composed of the EKS cluster and Fluent | ||
Bit composite resources above, and thus this package depends on the above two. | ||
**The files in this package contain explanatory annotations; it's the most | ||
interesting one to look at.** | ||
|
||
The root of each package dependency contains a file named `crossplane.yaml`. | ||
This file indicates that the directory represents a Crossplane package. A | ||
Crossplane package is an OCI image that is expected to emit this file, followed | ||
by any packaged resources in the order they should be applied, when its | ||
entrypoint is invoked. | ||
|
||
To create a package, the package author (or their CI/CD system runs) the | ||
following commands: | ||
|
||
```bash | ||
|
||
# default `crossplane package unpack` will emit this file, then discover and | ||
# emit any packagable resources (XRDs, Compositions, etc) at or below its path | ||
# in lexicographical order. Alternately we could shift this discovery and | ||
# ordering logic into the 'build' subcommand, creating a tiny package image | ||
# with an ENTRYPOINT of `cat bigstreamofresources.yaml`. | ||
|
||
# Any OCI image that omits a YAML resource of kind: Configuration or kind: | ||
# Provider (in the pkg.crossplane.io API Group) followed by zero or more | ||
# supplemental resources when its ENTRYPOINT is invoked is considered a valid | ||
# Crossplane package. This tools builds a valid package by reading a file named | ||
# crossplane.yaml at the root of the package directory (which must contain a | ||
# kind: Configuration or a kind: Provider), then discovering all Crossplane | ||
# resources at or below the level of crossplane.yaml in the directory tree. | ||
# These resources are concatenated into a YAML stream in a randomly generated | ||
# filename (to avoid implementations relying on the path of this file), and the | ||
# ENTRYPOINT of the OCI image is set to `cat randomlynamedstream.yaml`. | ||
$ crossplane package build --tag exampleorg/cnp-cluster:v0.1.0 | ||
|
||
# The `crossplane package` command provides a similar interface to the `docker` | ||
# tool frequently used to build, tag, and push images. `crossplane package` | ||
# publishes packages to the Upbound Cloud Registry rather than the Docker Hub | ||
# by default. | ||
$ crossplane package push exampleorg/cnp-cluster:v0.1.0 | ||
``` | ||
|
||
Note that package metadata does not include a version. Crossplane packages use | ||
the package (image) tag as their version, and thus require that tags be valid | ||
semantic versions. Images built by CI/CD as part of a gitops flow are encouraged | ||
to derive their semantic version from a git tag. In such a case all packages | ||
defined in this repository would be versioned in lock-step. | ||
|
||
## Proposed Changes | ||
|
||
This sketch assumes the acceptance of the in-flight [Package Manager refactor]. | ||
It also: | ||
|
||
* Renames `InfrastructureDefinition` to `CompositeResourceDefinition` (XRD). | ||
* Replaces `InfrastructurePublication` with a configuration field on an XRD. | ||
* Automatically derives UI metadata from the OpenAPI schema of an XRD. | ||
* Renames the `spec.to` and `spec.from` of a `Composition` to | ||
`spec.compositeResource` and `spec.composedResources`, in order to allow for | ||
'bidirectional patching' - i.e. patching from composed resource status to | ||
composite resource status in addition to patching from composite resource spec | ||
to composed resource spec (not yet demonstrated in this repo). | ||
* Uses `metadata.annotations` to represent most package metadata (maintainer, | ||
company, etc) in order to loosen the contract around purely informational | ||
package metadata. | ||
* Couples the creation and aggregation of suggested RBAC ClusterRoles to the | ||
existence of XRDs, rather than Packages. | ||
|
||
When automatic RBAC ClusterRole management is enabled by an XRD (management is | ||
enabled by default) Crossplane will create `admin`, `edit`, and `view` RBAC | ||
ClusterRoles granting access to the defined kind and its requirement (if any). | ||
These ClusterRoles will labelled such that they aggregate (as appropriate) to | ||
the ClusterRoles intended to be granted to: | ||
|
||
* The Crossplane (Deployment) service account. | ||
* The Crossplane superuser (`crossplane-admin`). | ||
* Subjects allowed to administrate, edit, or view all Crossplane resources. | ||
|
||
Furthermore, Crossplane will create `admin`, `edit`, and `view` ClusterRoles | ||
corresponding to any namespace that is labelled with the name of one or more | ||
XRD, for example `rbac.crossplane.io/clusters.cnp.example.org`. If the named XRD | ||
exists and has `rbacPolicy: ManageClusterRoles` the ClusterRole corresponding to | ||
the labelled namespace will have a `matchLabels` stanza added to its | ||
`clusterRoleSelectors` such that the XRD's managed cluster roles aggregate up | ||
to it. This allows consumers of the Crossplane API that wish to simulate a | ||
kind of resource existing or not existing at the namespace level (i.e. Upbound | ||
Cloud) to read and write namespace annotations to determine which resources are | ||
allowed (by RBAC) in a particular namespace. | ||
|
||
[Package Manager refactor]: https://github.com/crossplane/crossplane/pull/1616 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
apiVersion: apiextensions.crossplane.io/v1alpha1 | ||
kind: Composition | ||
metadata: | ||
name: clusters.cnp.example.org | ||
spec: | ||
writeConnectionSecretsToNamespace: crossplane-system | ||
reclaimPolicy: Delete | ||
compositeResource: | ||
apiVersion: cnp.example.org/v1alpha1 | ||
kind: Cluster | ||
composedResources: | ||
- base: | ||
apiVersion: clusters.cnp.example.org/v1alpha1 | ||
kind: EKS | ||
patches: | ||
- fromFieldPath: metadata.annotations[crossplane.io/external-name] | ||
toFieldPath: metadata.annotations[crossplane.io/external-name] | ||
- fromFieldPath: metadata.uid | ||
toFieldPath: spec.writeConnectionSecretToRef.name | ||
transforms: | ||
- type: string | ||
string: | ||
fmt: "%s-eks" | ||
- fromFieldPath: spec.parameters.nodes.count | ||
toFieldPath: spec.parameters.nodes.count | ||
- fromFieldPath: spec.parameters.nodes.size | ||
toFieldPath: spec.parameters.nodes.size | ||
- base: | ||
apiVersion: charts.cnp.example.org/v1alpha1 | ||
kind: FluentBit | ||
patches: | ||
- fromFieldPath: metadata.uid | ||
toFieldPath: spec.providerRef.name | ||
transforms: | ||
- type: string | ||
string: | ||
fmt: "%s-eks" | ||
- fromFieldPath: spec.parameters.logging.token | ||
toFieldPath: spec.parameters.splunk.token |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# The Configuration resource follows Kubernetes API conventions, but is simply | ||
# a configuration file rather than a custom resource in an API server. This is | ||
# similar to the approach the kubelet and kind take with their configuration. | ||
# The content of this file is emitted by the `crossplane package unpack` tool | ||
# when a Package CR is created, and used to create a PackageRevision. | ||
apiVersion: pkg.crossplane.io/v1alpha1 | ||
kind: Configuration | ||
metadata: | ||
name: cnp-cluster | ||
annotations: | ||
# Package metadata is stored as well-known but optional, free-form metadata | ||
# ala https://packaging.python.org/specifications/core-metadata/. The data | ||
# is opaque to Crossplane and its tooling, allowing for maximum flexibility | ||
# in the contract between the authors and consumers of package metadata (at | ||
# the expense of some loss of schema). | ||
company: ExampleCo | ||
maintainer: Wan Jillies <wan@example.org> | ||
keywords: cloud-native, kubernetes | ||
source: github.com/negz/aac | ||
license: Apache-2.0 | ||
description: | | ||
An ExampleCo Cloud Native Platform (CNP) Kubernetes Cluster, complete with | ||
supporting infrastructure services such as logging and monitoring daemons. | ||
spec: | ||
dependsOn: | ||
- package: exampleco/cnp-eks | ||
version: "0.1.0" | ||
- package: exampleco/cnp-fluentbit | ||
version: "0.1.0" | ||
# Optional. Matching paths will be ignored by `crossplane package build`. | ||
ignore: | ||
- path: examples/ | ||
# crossplane.yaml may be of kind: Provider, rather than kind: Configuration. | ||
# A Provider contains additional configuration, including an image to run. | ||
# controllerImage: crossplane/provider-gcp:v0.11.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
apiVersion: apiextensions.crossplane.io/v1alpha1 | ||
kind: CompositeResourceDefinition | ||
metadata: | ||
name: clusters.cnp.example.org | ||
spec: | ||
defaultCompositionRef: | ||
name: clusters.cnp.example.org | ||
# This policy is equivalent to the existing InfrastructurePublication. Making | ||
# this a field of the InfrastructureDefinition implies that the package author | ||
# controls the publication of packaged types; it cannot easily be overridden | ||
# without forking/duplicating the package. | ||
publicationPolicy: PublishRequirement | ||
# This policy determines whether Crossplane will automatically create cluster | ||
# roles for this composite resource and its requirement. ManageClusterRoles is | ||
# the default. Under this policy Crossplane will create edit and view RBAC | ||
# cluster roles for the composite resource and requirement (if any). The roles | ||
# will aggregate to the Crossplane service account, crossplane-admin role, the | ||
# global edit and view roles, and any matching namespaced edit and view roles. | ||
rbacPolicy: ManageClusterRoles | ||
connectionSecretKeys: | ||
- kubeconfig | ||
# Note that there is no distinct UI metadata; UI forms are derived from the | ||
# crdSpecTemplate, which includes enough detail to infer how to build a form. | ||
crdSpecTemplate: | ||
group: cnp.example.org | ||
version: v1alpha1 | ||
names: | ||
kind: Cluster | ||
listKind: ClusterList | ||
plural: clusters | ||
singular: cluster | ||
validation: | ||
openAPIV3Schema: | ||
type: object | ||
properties: | ||
spec: | ||
type: object | ||
properties: | ||
parameters: | ||
type: object | ||
description: Cluster configuration parameters. | ||
nodes: | ||
type: object | ||
description: Cluster node configuration parameters. | ||
count: | ||
type: int | ||
description: Desired node count, from 1 to 100. | ||
size: | ||
type: string | ||
description: Size of node. | ||
enum: | ||
- small | ||
- medium | ||
- large | ||
required: | ||
- count | ||
- type | ||
logging: | ||
type: object | ||
description: Splunk logging configuration for cluster logs. | ||
token: | ||
type: string | ||
description: Splunk API token. | ||
required: | ||
- token | ||
required: | ||
- nodes | ||
- splunk | ||
required: | ||
- parameters |
Oops, something went wrong.