Skip to content
Draft
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
3 changes: 3 additions & 0 deletions docs/users/00-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Learn the basics of working with OpenControlPlane:
- **[Onboarding](./getting-started/onboard)** - Create your first project and workspace
- **[Connect](./getting-started/connect)** - Access your control plane
- **[Configure](./getting-started/configure)** - Set up services and resources
- **Usage**
- **[to Kubernetes](./usage/usage-kubernetes)** - OCM, Flux, ArgoCD, or kubectl
- **[to SAP BTP](./usage/usage-btp)** - Provision BTP services via Crossplane

### Core Concepts

Expand Down
4 changes: 3 additions & 1 deletion docs/users/getting-started/03-configure.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ The chart source, image pull secret, and Helm values are configured cluster-wide

## Next Steps

Congratulations! You have a working ControlPlane with managed services. Here's what you can explore next:
Congratulations! You have a working ControlPlane with managed services. Ready to deploy workloads? See **[Deploy to Kubernetes](../usage/usage-kubernetes)** for a comparison of OCM, Flux, ArgoCD, and kubectl, or **[Deploy to SAP BTP](../usage/usage-btp)** to provision BTP services via Crossplane.

Other things to explore:

- **[What is a ControlPlane?](../concepts/controlplane)** — Deeper understanding of ControlPlanes
- **[Service Providers](../concepts/providers)** — How managed services work
Expand Down
211 changes: 211 additions & 0 deletions docs/users/usage/01-kubernetes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
sidebar_position: 1
id: usage-kubernetes
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Deploy to Kubernetes

Your `ControlPlane` manages infrastructure — **it does not run your workloads itself**. This page covers how to deploy applications to a **Kubernetes cluster** that is managed by your `ControlPlane` (e.g. a Gardener cluster requested via a `ClusterRequest`).

## Which approach should I use?

| Approach | Air-gap / Sovereign Cloud | GitOps | Helm support | Complexity |
| ----------------------- | --------------------------- | ------ | ------------ | ---------- |
| **OCM** ✓ recommended | Yes — built-in localization | Yes | Yes | Medium |
| **Flux** | No | Yes | Yes | Low |
| **ArgoCD** | No | Yes | Yes | Medium |

**TL;DR**: If you operate in regulated or sovereign-cloud environments, or need to transport components across air-gapped networks, use OCM. For standard internet-connected clusters with simple GitOps needs, Flux is a quick win.

---

## OCM — Recommended

[Open Component Model (OCM)](https://ocm.software/) packages your software as _components_ that can be transferred, signed, and deployed to any environment — including air-gapped and sovereign clouds. The OCM Kubernetes deployer acts as a controller that pulls resources from an OCM repository and applies them to your target cluster.

**Key advantages over other approaches:**
- **Localization** — image references and registry URLs are rewritten at transfer time, enabling deployment to sovereign clouds without manual manifest patching. See [transfer & transport](https://ocm.software/docs/concepts/transfer-and-transport/).
- **Verification** — components can be signed and verified before deployment.
- **Air-gap support** — `ocm transfer` moves a component to any OCI registry, including on-premise ones.

### Prerequisite

Install the OCM operator on your `ControlPlane` — see [Configure → OCM](../getting-started/configure). The OCM operator running on the `ControlPlane` then manages deployments to the target cluster on your behalf. More details on [how to build OCM Artifacts](https://ocm.software/docs/how-to/deploy-manifests-with-deployer/).

### Deploy a plain Kubernetes resource

```yaml
# 1. Point to an OCM repository
apiVersion: delivery.ocm.software/v1alpha1
kind: Repository
metadata:
name: my-registry
namespace: default
spec:
interval: 1h
repositorySpec:
baseUrl: ghcr.io/my-org/ocm
type: OCIRegistry
---
# 2. Select a component version
apiVersion: delivery.ocm.software/v1alpha1
kind: Component
metadata:
name: my-app
namespace: default
spec:
component: github.com/my-org/my-app
downgradePolicy: "Deny"
semver: "1.0.0"
interval: 1h
repositoryRef:
name: my-registry
---
# 3. Reference the resource inside the component
apiVersion: delivery.ocm.software/v1alpha1
kind: Resource
metadata:
name: my-app-manifests
namespace: default
spec:
componentRef:
name: my-app
resource:
byReference:
resource:
name: manifest
---
# 4. Apply it to the target cluster
apiVersion: delivery.ocm.software/v1alpha1
kind: Deployer
metadata:
name: my-app-deployer
namespace: default
spec:
resourceRef:
name: my-app-manifests
namespace: default
```

### Deploy a kro ResourceGraphDefinition via OCM

Package a [kro](https://kro.run) `ResourceGraphDefinition` as an OCM resource. The deployer applies the definition, and kro reconciles it into a custom CRD your platform users can instantiate:

```yaml
apiVersion: delivery.ocm.software/v1alpha1
kind: Resource
metadata:
name: my-platform-api
namespace: default
spec:
componentRef:
name: my-platform
resource:
byReference:
resource:
name: resource-graph-definition # kro RGD packaged as OCM resource
---
apiVersion: delivery.ocm.software/v1alpha1
kind: Deployer
metadata:
name: my-platform-api-deployer
namespace: default
spec:
resourceRef:
name: my-platform-api
namespace: default
```

Once applied, users can create instances of the generated CRD as if it were a native Kubernetes resource.

---

## Flux — Traditional GitOps

[Flux](https://fluxcd.io/) keeps a cluster in sync with a Git repository. It's well understood and easy to get started with.

### Prerequisite

Install Flux on your `ControlPlane` — see [Configure → Flux](../getting-started/configure). Flux runs on the `ControlPlane` and reconciles resources onto the target cluster.

### GitRepository + HelmRelease

```yaml
# 1. Point Flux at your Git repo
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 5m
url: https://github.com/my-org/my-app
ref:
branch: main
---
# 2. Install a Helm chart from that repo
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-app
namespace: default
spec:
interval: 10m
chart:
spec:
chart: ./charts/my-app
sourceRef:
kind: GitRepository
name: my-app
namespace: flux-system
values:
replicaCount: 2
```

:::warning No localization for sovereign clouds
Flux pulls images and manifests directly from the upstream source. It has no built-in mechanism to rewrite registry references when deploying to air-gapped or sovereign-cloud environments. If you need to move software across network boundaries, consider OCM instead — it handles [transfer and localization](https://ocm.software/docs/concepts/transfer-and-transport/) natively.
:::

---

## ArgoCD

[ArgoCD](https://argoproj.github.io/cd/) provides a full GitOps UI and RBAC model on top of Git-driven deployments.

:::note
ArgoCD does not currently have a managed service provider in OpenControlPlane. Install it manually on your `ControlPlane` as you would on any Kubernetes cluster.
:::

Install ArgoCD on your `ControlPlane` via `kubectl` or Helm, then create an `Application`:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/my-org/my-app
targetRevision: main
path: manifests/
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
```

---

## Summary

- **Start with OCM** if you need portability, signing, or sovereign-cloud support.
- **Use Flux** for simple GitOps on internet-connected clusters where air-gap is not a concern.
- **Use ArgoCD** if your team prefers a UI-driven GitOps workflow.
36 changes: 36 additions & 0 deletions docs/users/usage/02-btp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
sidebar_position: 2
id: usage-btp
---

# Deploy to SAP BTP

Your `ControlPlane` can provision and manage **SAP Business Technology Platform (BTP)** resources — service instances, bindings, and subaccounts — using [Crossplane](https://crossplane.io/) with the [SAP BTP provider](https://sap.github.io/crossplane-provider-docs/).

This means BTP resources are managed the same way as any other Kubernetes resource: declaratively, with drift detection and automatic reconciliation.

## Prerequisites

1. **Crossplane** installed on your `ControlPlane` — see [Configure → Crossplane](../getting-started/configure).
2. **SAP BTP Crossplane provider** installed and configured. Ask your platform owner to set up the `ProviderConfig` with the appropriate BTP service account credentials.

Once the provider is running, you can verify it:

```bash
kubectl get providers
# NAME INSTALLED HEALTHY PACKAGE AGE
# provider-sap-btp True True ghcr.io/sap/crossplane-provider-btp:... 5m
```

---

Now follow the complete guide at [Crossplane BTP provider docs](https://sap.github.io/crossplane-provider-docs/) to provision and manage BTP resources.

---

## Further reading

- [SAP BTP Crossplane provider docs](https://sap.github.io/crossplane-provider-docs/)
- [Crossplane compositions](https://docs.crossplane.io/latest/composition) — alternative to kro for composing BTP resources
- [Configure → Crossplane](../getting-started/configure) — enabling Crossplane on your `ControlPlane`
- [Configure → Kro](../getting-started/configure) — enabling Kro on your `ControlPlane`
5 changes: 5 additions & 0 deletions docs/users/usage/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"label": "Usage",
"position": 4,
"collapsible": true
}