Skip to main content

Control Your Chaotic Deployment Workflows with Upbound

In the realm of infrastructure and cloud resource management, one must tread lightly upon the path between complexity and chaos, much like the treacherous terrain on the path to Mordor. Complex workflows hold the potential to ensnare even the most seasoned platform wizard when scaling or modifying workspaces. Just as the One Ring brought perilous consequences, so too can unchecked complexity descend into calamity in our cloud domains.

In these dark places, Upbound may be a light for you, when all other lights go out. In this post, we’ll embark on a journey to find how Upbound can help you battle the Balrog of complexity in your workspace deployments.

Let’s identify the essential elements of this example deployment:

  • Workload cluster
  • Workspace environments
  • Application delivery

The first step in this quest is to provision a cluster to manage the underlying work for the application.

Gather your fellowship

This example repository contains an AWS cluster example. The directory contains the underlying infrastructure for you to deploy your workspaces and applications.

The `cluster` directory contains the following resources:

├── composition.yaml
├── definition.yaml
├── eks
│   ├── composition.yaml
│   └── definition.yaml
├── network
│   ├── basic
│   │   └── composition.yaml
│   └── definition.yaml
├── services
│   ├── default
│   │   └── composition.yaml
│   ├── definition.yaml
│   └── gitops-master
└──     └── composition.yaml

These resources are the foundation of your application workspace and you can deploy them with Crossplane or Upbound.

This example is based on the `Cluster-as-a-Service` configuration, an "out of the box" pre-built configuration that exposes an API to create Kubernetes clusters in AWS.

After you’ve gathered your fellowship of nodes, it’s time to segment them into different environments.

Construct the realms of your workspace environments

You can create Composite Resource Definitions to help you divide your workspace environments. In this example, we're creating individual namespaces by team. These teams contain the `kind`, metadata, and users that have access to that team with their associated role.

Here's an example of a generic team composition that shapes your team configurations:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xtenant.k8s.example.com
spec:
  compositeTypeRef:
    apiVersion: k8s.example.com/v1alpha1
    kind: XTenant
  mode: Pipeline
  pipeline:
    - step: template-resources
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        inline: 
          template: |
            {{- range $i, $team := .observed.composite.resource.spec.teams  }}
            ---
            apiVersion: kubernetes.crossplane.io/v1alpha1
            kind: Object
            metadata:
              annotations:
                {{ setResourceNameAnnotation (print "namespace-" $team) }}
            spec:
              forProvider:
                manifest:
                  apiVersion: v1
                  kind: Namespace
                  metadata:
                    name: {{ $team }}
            {{- end }}

This composition uses the go-template function to patch multiple teams into your deployment workflow.

To deploy a specific team namespace, you can construct your `team` manifest like:

apiVersion: example.upbound.io/v1alpha1
kind: XTeam
metadata:
 name: rohan
spec:
 namespaces:
   - name: namespace-rohan
 users:
   - name: eomer
     role: developer
   - name: eowyn
     role: tester

This approach can help you with resource isolation and resource management. Each team can work within their own dedicated cluster with appropriately scaled resources like CPU, memory, and storage. These segmented clusters provide flexibility and autonomy to each team as they have more control over their clusters and can tailor the environment to their specific requirements and workflows.

Namespaced team segmentation can provide a practical approach to scaling clusters. With specific clusters scaling up or down as needed, your teams can optimize their cluster configurations without impacting other teams.

You've gathered your fellowship of clusters, gathered your namespaced armies, now is the hour to deploy your application.

Light the beacons of your application

You're almost at the end of your journey, but the most important step is still ahead. Deploying your application with the workspace and cluster already built ensures your workflow stays consistent and repeatable.

The application definition references your target cluster, namespace, and the repository you've stored your application:

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xapps.example.upbound.io
spec:
  group: example.upbound.io
  names:
	kind: XApp
	plural: xapps
  claimNames:
	kind: App
	plural: apps
  versions:
  - name: v1alpha1
	served: true
	referenceable: true
	schema:
  	openAPIV3Schema:
    	type: object
    	properties:
      	spec:
        	type: object
        	properties:
          	parameters:
            	type: object
            	properties:
              	cluster:
                	description: the target cluster
                	type: string
              	namespace:
                	description: the target namespace
                	type: string
              	source:
                	description: the source repository for the application
                	type: string
              	path:
                	description: the path in the source repository for the application
                	type: string

The Cluster-as-a-Service configuration you've built includes a gitops based deployment system with the option to configure flux or ArgoCD.

With this example, you'll use ArgoCD to complete the process.

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xapps.example.upbound.io
spec:
  writeConnectionSecretsToNamespace: upbound-system
  compositeTypeRef:
	apiVersion: example.upbound.io/v1alpha1
	kind: XApp
  resources:
	- name: namespace
  	base:
    	apiVersion: kubernetes.crossplane.io/v1alpha1
    	kind: Object
    	spec:
      	forProvider:
        	manifest:
          	apiVersion: v1
          	kind: Namespace
  	patches:
  	- fromFieldPath: spec.parameters.namespace
    	toFieldPath: spec.forProvider.manifest.metadata.name
  	- fromFieldPath: spec.parameters.cluster
    	toFieldPath: spec.providerConfigRef.name
	- name: application
  	base:
    	apiVersion: kubernetes.crossplane.io/v1alpha1
    	kind: Object
    	spec:
      	forProvider:  
        	manifest:
          	apiVersion: argoproj.io/v1alpha1
          	kind: Application
          	metadata:
            	namespace: argocd
          	spec:
            	project: default
            	source:
              	targetRevision: HEAD
            	destination: {}
      	providerConfigRef:
        	name: gitops-host
  	patches:
  	- fromFieldPath: metadata.name
    	toFieldPath: spec.forProvider.manifest.metadata.name
  	- fromFieldPath: spec.parameters.source
    	toFieldPath: spec.forProvider.manifest.spec.source.repoURL
  	- fromFieldPath: spec.parameters.path
    	toFieldPath: spec.forProvider.manifest.spec.source.path
  	- fromFieldPath: spec.parameters.namespace
    	toFieldPath: spec.forProvider.manifest.spec.destination.namespace
  	- fromFieldPath: spec.parameters.cluster
    	toFieldPath: spec.forProvider.manifest.spec.destination.name

Each of your namespaces and clusters are patched as endpoints in this composition so you can control how and when your application gets deployed.

For more information on integrating a gitops workflow into your deployment process, check out this guide on GitOps with Control Planes.

There and back again: control plane chronicles and what’s next

In this blog, you walked through how to deploy your applications in namespaced clusters for your teams.

Of course, the journey doesn’t end here. Crossplane and Upbound have so much to offer to help you simplify your infrastructure and resource management.

For more information on Upbound as an Internal Developer Platform, check out this talk on driving a developer self service workflow.

Ready to take the first step? Check out the Crossplane Getting Started guide to learn the foundations of universal control planes.

If you’re ready for your next cloud adventure, sign up for a free trial of Upbound.

Pioneer your platform with Upbound.