Provider Storage – Installation Guide
The provider-storage configuration packages let platform operators offer S3-compatible bucket self-service through Crossplane.
Buckets, access policies, sharing, lifecycle rules, and credentials are declared through one namespaced Storage spec.
Namespacing Model (Important)
Storage, provider Secrets, and namespaced ProviderConfigs use the target
namespace:
- You apply
Storageclaims to a namespace (e.g.,workspace). - The provisioned Secret lives in the same namespace as the
Storageclaim (Secret name = principal). - Any namespaced ProviderConfigs or supporting objects that the compositions depend on must exist in that same target namespace (e.g.,
workspace).
In short: choose your target namespace (e.g.,
workspace), apply the provider configs there, and create yourStorageclaims in that namespace.
EnvironmentConfig and Composition are cluster-scoped. Backend bootstrap
procedures can generate these resources when their scope requires it.
Prerequisites
- A running Kubernetes cluster (e.g.,
kind, managed K8s). kubectlaccess.- Crossplane installed in the cluster:
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane crossplane-stable/crossplane \
--namespace crossplane \
--create-namespace \
--version 2.4.1 \
--set provider.defaultActivations={}
To reduce control-plane load, we use a
ManagedResourceActivationPolicy(MRAP) per backend so only the needed Managed Resources are active.
Step 0 – Bootstrap the Cloud Identity
Required before cloud provider deployment
Before deployment, a cloud administrator must review the backend's
<cloud>/dependencies/iam.sh script and any policy templates. A managed
cloud backend needs a controller identity scoped to its cloud account,
domain, or project. Complete the steps in the order shown in the backend
guide.
The OVHcloud bootstrap needs the official ovhcloud CLI, jq, and an
administrator session. Follow its bootstrap README
and the
cloud IAM bootstrap guide.
Step 1 – Install Provider Dependencies (per backend)
All providers follow the same staged pattern you must install before the configuration package:
- ManagedResourceActivationPolicy – activate only the resource kinds that are needed.
- Deployment Runtime Configs – define how providers/functions run.
- Providers – install the required Crossplane providers.
- ProviderConfigs (namespaced) – point providers to endpoints/credentials in your target namespace.
- Functions – install supporting Crossplane Functions.
- RBAC – permissions for
provider-kubernetesto observe and reconcile objects.
Repository root: https://github.com/versioneer-tech/provider-storage/
Install only the backend packages you want to offer as platform service classes. If you install multiple backends, label each Storage claim so Crossplane selects the intended composition.
MinIO
You operate the MinIO endpoint yourself. It can run in the same cluster, another cluster, or another data center. For a local
kindsetup, see Local Setup.
- 00-mrap.yaml – Activate MinIO-specific Managed Resources.
- 01-deploymentRuntimeConfigs.yaml – Runtime configs for providers/functions.
- 02-providers.yaml – Install
provider-minioandprovider-kubernetes. - 03-providerConfigs.yaml – Apply in your target namespace (e.g.,
workspace); points to your MinIO endpoint/credentials. - 04-environmentConfigs.yaml – Backend settings consumed by the composition.
- functions.yaml – Functions used by compositions.
- rbac.yaml – RBAC for
provider-kubernetes.
AWS
Both AWS IAM modes require the runtime role ARN in the namespaced
ProviderConfig.bootstrap-useralso requires a Secret with the generated base credentials.assume-roleuses the configured source for the existing trusted identity.
- 00-mrap.yaml – Activate AWS S3/IAM Managed Resources.
- 01-deploymentRuntimeConfigs.yaml – Runtime configs for AWS + Kubernetes providers.
- 02-providers.yaml – Install
provider-upjet-awsandprovider-kubernetes. - 03-providerConfigs.yaml – Configure for the selected IAM mode and apply in each
Storagenamespace; both modes require the runtime role ARN, whilebootstrap-useralso requires the credentials Secret in that namespace. - 04-environmentConfigs.yaml – Backend settings consumed by the composition.
- functions.yaml – Functions used by compositions.
- rbac.yaml – RBAC for
provider-kubernetes.
OTC
You do not deploy OBS. Use the controller credentials created in Step 0 for the Secret referenced by
ProviderConfig.
- 00-mrap.yaml – Activate OTC Managed Resources.
- 01-deploymentRuntimeConfigs.yaml – Runtime configs for OTC + Kubernetes providers.
- 02-providers.yaml – Install OTC provider(s) and
provider-kubernetes. - 03-providerConfigs.yaml – Apply in your target namespace; references OTC credentials Secret.
- 04-environmentConfigs.yaml – Backend settings consumed by the composition.
- functions.yaml – Functions used by compositions.
- rbac.yaml – RBAC for
provider-kubernetes.
OVHcloud
Complete the
OVHcloud controller bootstrap
for the target Public Cloud project first. Its private JSON contains
endpoint, client_id, and client_secret.
Create ovh-provider-creds with a credentials key in every target
Storage namespace. The namespaced ProviderConfig references that Secret;
the administrator CLI login is separate and must not be used for it.
If you replace the Secret in a running cluster, restart the OVHcloud provider
Deployment so it uses the new controller credential.
- 00-mrap.yaml – Activate only the OVHcloud managed resource kinds used by the Composition.
- 01-deploymentRuntimeConfigs.yaml – Provider and function runtime settings.
- 02-providers.yaml – Install the OVHcloud provider and
provider-kubernetes. - 03-providerConfigs.yaml – Set the credential Secret namespace, then apply in each
Storagenamespace. - 04-environmentConfigs.yaml – Set
data.storage.serviceNameto the exact project ID. The initial configuration uses Object Storage regiondeand endpointhttps://s3.de.io.cloud.ovh.net; this is separate from the EU control-plane API region. - functions.yaml – Composition functions.
- rbac.yaml –
provider-kubernetespermissions.
The integration test guide shows the explicit-context Secret handoff and two-bucket integration run. Do not apply the placeholder project ID in the EnvironmentConfig.
CloudFerro
CloudFerro uses existing numbered OpenStack projects as team slots. Install
the shared dependencies and the storage-cloudferro Configuration before IAM
bootstrap. The bootstrap then creates the project-scoped resources for each
selected slot. Follow the exact order in the
CloudFerro bootstrap guide.
- 00-mrap.yaml – Activate the required OpenStack resources.
- 01-deploymentRuntimeConfigs.yaml – Provider and function runtime settings.
- 02-providers.yaml – Install the OpenStack and Kubernetes providers.
- 03-providerConfigs.yaml – Apply the shared Kubernetes ProviderConfig in each
Storagenamespace. - functions.yaml – Composition functions.
- rbac.yaml –
provider-kubernetespermissions.
Step 2 – Install the Configuration Package (after dependencies)
Once the provider dependencies are in place, install the configuration package for your chosen backend. This registers the Storage CRD and compositions and allows reconciliation because the providers and configs already exist.
Example: MinIO
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: storage-minio
spec:
package: ghcr.io/versioneer-tech/provider-storage/minio:0.3.1
Example: AWS
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: storage-aws
spec:
package: ghcr.io/versioneer-tech/provider-storage/aws:0.3.1
Example: OTC
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: storage-otc
spec:
package: ghcr.io/versioneer-tech/provider-storage/otc:0.3.1
Example: OVHcloud
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: storage-ovh
spec:
package: ghcr.io/versioneer-tech/provider-storage/ovh:0.3.1
Example: CloudFerro
apiVersion: pkg.crossplane.io/v1
kind: Configuration
metadata:
name: storage-cloudferro
spec:
package: ghcr.io/versioneer-tech/provider-storage/cloudferro:0.3.1
Apply your chosen one with:
kubectl apply -f configuration.yaml
Selecting the Storage Environment
Each composition loads a Crossplane EnvironmentConfig named storage by default. To select a different environment, add the annotation or label storages.pkg.internal/environment to the Storage resource:
metadata:
annotations:
storages.pkg.internal/environment: storage
This is the same hook used by higher-level workspace APIs to point new Storage resources at a specific provider-storage environment.
For a generated project slot, select its Composition with
spec.crossplane.compositionSelector.matchLabels.provider: cloudferro-0001
as shown in the CloudFerro overlay.
Step 3 – (Optional) Quick Verification
After the package installs and providers are healthy, create a minimal Storage claim in your target namespace and verify readiness and credentials. For AWS, Ready stays False until the current credentials are observed and the consumer Secret is ready. See the Usage & Concepts guide for details (kubectl get storages -n <ns>, and inspect the Secret named after the principal).