KubeProvisioner is a Kubernetes operator that lets you manage cloud infrastructure as native Kubernetes resources. Instead of switching between the AWS console, Terraform, or CLI tools, you declare the resources you need in YAML — and KubeProvisioner creates, monitors, and cleans them up automatically.
The operator is built to grow. It currently supports AWS, and is designed to add new resource types and new cloud providers (GCP, Azure) without changing how you interact with it.
The Helm chart lives at ./dist/chart and installs the CRDs, RBAC, and the controller in one step.
helm install kubeprovisioner --create-namespace -n kubeprovisioner \
--values ./dist/chart/values.yaml \
--set controllerManager.container.env.AWS_ACCESS_KEY_ID=<your-key-id> \
--set controllerManager.container.env.AWS_SECRET_ACCESS_KEY=<your-secret> \
./dist/chart/To upgrade an existing release:
helm upgrade kubeprovisioner -n kubeprovisioner \
--values ./dist/chart/values.yaml \
./dist/chart/To uninstall:
helm uninstall kubeprovisioner -n kubeprovisionerapiVersion: compute.cloud.com/v1
kind: Ec2Instance
metadata:
name: my-web-server
spec:
instanceType: t3.micro
amiId: ami-0c55b159cbfafe1f0
region: us-east-1
keyPair: my-key
subnet: subnet-abc123
tags:
env: dev
team: platformkubectl apply -f my-instance.yaml
kubectl get ec2instances -wThe State, PublicIP, and InstanceID columns populate once the instance is running. To delete:
kubectl delete ec2instance my-web-serverThe operator terminates the EC2 instance on AWS and then removes the CR.
apiVersion: compute.cloud.com/v1
kind: S3Bucket
metadata:
name: my-app-assets
spec:
bucketName: my-app-assets-kube-provisioner
region: us-east-1
versioning: true
tags:
env: dev
team: platformkubectl apply -f my-bucket.yaml
kubectl get s3buckets -wThe BucketName, State, and Endpoint columns populate once the bucket is ready. To delete:
kubectl delete s3bucket my-app-assetsNote: The bucket must be empty before deletion. The operator will retry until it is empty.
apiVersion: compute.cloud.com/v1
kind: SQSQueue
metadata:
name: my-app-queue
spec:
queueName: my-app-queue-kube-provisioner
region: us-east-1
visibilityTimeoutSeconds: 30
messageRetentionSeconds: 86400
tags:
env: dev
team: platformFor a FIFO queue, set fifo: true and make sure queueName ends with .fifo.
kubectl apply -f my-queue.yaml
kubectl get sqsqueues -wThe QueueName, State, and QueueURL columns populate once the queue is ready. The QueueURL is what your application uses to send and receive messages. To delete:
kubectl delete sqsqueue my-app-queueSample manifests for all resources are in kubernetes/sample-manifests/.
1. Start a kind cluster:
kind create cluster --name kubeprovisioner
kubectl config use-context kind-kubeprovisioner2. Install via Helm:
helm install kubeprovisioner --create-namespace -n kubeprovisioner \
--values ./dist/chart/values.yaml \
--set controllerManager.container.env.AWS_ACCESS_KEY_ID=<your-key-id> \
--set controllerManager.container.env.AWS_SECRET_ACCESS_KEY=<your-secret> \
./dist/chart/Alternative — run the controller locally (faster iteration without rebuilding the image):
make install # installs only the CRDs
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
go run cmd/main.goThe operator running in the helm.ReleaseNS namespace:
Applying the sample EC2 instance manifest:
Instance comes up running:
AWS console confirms the instance is live:
Build and push the image:
make docker-build docker-push IMG=<registry>/kubeprovisioner:tagInstall CRDs only:
make installDeploy the controller with a custom image:
make deploy IMG=<registry>/kubeprovisioner:tagApply all sample CRs:
kubectl apply -k config/samples/Delete all sample CRs:
kubectl delete -k config/samples/Remove the CRDs:
make uninstallRemove the controller:
make undeployRun make help for the full list of targets.
Copyright 2025.
Licensed under the Apache License, Version 2.0. See LICENSE for details.



