From Tickets to Autonomy: Self-Service Cloud Resources with Crossplane and GitOps
- Alex Galperin

- Jul 28
- 4 min read

This blog post is based on real-world implementations in cloud-native teams, focusing on how Crossplane, together with GitOps tools like ArgoCD, enables application teams to provision and manage cloud infrastructure independently without needing to open tickets or wait for infrastructure engineers.
The Cloud Infrastructure Bottleneck for Developers
Modern application teams move fast. But cloud provisioning workflows? Not so much.
In many organizations, developers still rely on infrastructure teams to provision cloud services even when those services are needed per application and vary across services. The result? Bottlenecks, slow feedback loops, and wasted developer cycles.
Imagine a developer building a microservice that needs:
An S3 bucket for storing logs
An SNS topic for broadcasting events
An SQS queue to process messages
In an ideal world, the developer would define these resources alongside their app code and deploy them to multiple environments (dev, staging, production) using a single consistent workflow.
But in reality, this often looks like:
Opening a ticket to the DevOps or infrastructure team
Waiting for someone to manually update Terraform
Dealing with drift when environments fall out of sync
Getting blocked for days or weeks when priorities don’t align
This disconnect between application development and infrastructure provisioning is a massive productivity drain and it’s entirely avoidable.
Shared vs. Per-Service Infrastructure
In most enterprise environments, infrastructure is split into two layers:
Shared foundational infrastructure - things like VPCs, EKS clusters, or security baselines, typically provisioned and maintained by a central platform or DevOps team using tools like Terraform.
Application-specific resources - things like S3, SQS, SNS, databases, or third-party services, needed by one service or workload. These are often dynamic and vary across services or environments.
While Terraform works well for shared infrastructure, it becomes unwieldy when every developer has to coordinate with the platform team just to get an S3 bucket.
So how do you enable self-service infrastructure for developers, without giving up control or security?
The Crossplane Solution: Infrastructure from Git
Crossplane turns cloud infrastructure into Kubernetes-native resources.
Instead of defining infrastructure in Terraform or external pipelines, developers can now write YAML files (or Helm templates) that declare infrastructure like this:
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
name: my-logs
spec:
forProvider:
region: us-east-1
providerConfigRef:
name: aws-providerThis file lives in the same Git repo as the app code. When committed, ArgoCD syncs it automatically, and Crossplane provisions the infrastructure all from within the cluster.
No CLI. No Terraform. No tickets.
How the Full GitOps Workflow Looks (Minikube + LocalStack Demo)Application + Infrastructure Deployment as One
Reusable Infrastructure as Code
The platform team defines reusable Helm charts for infrastructure resources such as S3, SNS, SQS, etc., managed by Crossplane and exposed as standard Kubernetes CRDs.

For this demo:
The Kubernetes cluster is running on Minikube
The AWS-compatible services (S3, SNS, SQS) are provided by LocalStack
Developer Self-Service
├── templates
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── provider-config.yaml
│ ├── s3.yaml
│ ├── service.yaml
│ ├── sns.yaml
│ └── sqs.yaml
├── Chart.yaml
└── values.yamlThe developer references these infrastructure charts in their own Git repository and provides environment-specific variables (like bucket names or topics) in their values.yaml file:
# Example: values.yaml
# App resources configuration
name: idp-demo
replicaCount: 1
image:
repository: python
tag: "3.11-slim"
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# AWS resources configuration (provisioned via LocalStack in this demo)
s3:
bucketName: "idp-demo-bucket"
sns:
topicName: "idp-demo-notifications"
sqs:
queueName: "idp-demo-queue"GitOps Flow Process:
Git Push → Repository update
ArgoCD → Detects changes and synchronizes
Helm → Renders templates with values
Crossplane → Creates AWS resources in LocalStack
Kubernetes → Deploys the application
Everything is automatic, no manual intervention! 🚀
Benefits Over Terraform for Per-Service Infrastructure
Capability | Terraform | Crossplane + GitOps |
Self-service for developers | No (requires CI/CD or CLI) | Yes (via Git + Kubernetes) |
Drift detection & reconciliation | No built-in reconciliation | Yes, continuous via ArgoCD |
Infrastructure visibility | Requires external tools | Unified in Kubernetes API |
Auditability | Terraform state only | Full Git history |
Multi-env promotion | Manual workflows | Git branches or Helm values |
Speed of provisioning | Manual apply or CI | Automatic on Git push |
Developer Autonomy with Guardrails
With this approach, developers can own their entire service stack from code to infrastructure without becoming infrastructure experts.
The platform team defines the guardrails, including:
Provider configurations (e.g., AWS credentials, allowed regions)
Resource policies (what can be provisioned)
Access boundaries (via namespaces or scopes)
Early Validation: CI/CD pipelines enforce standards like naming, tagging, and structure. using tools like OPA (Open Policy Agent), allowing policy-as-code checks early in the dev cycle.This prevents misconfigurations from reaching production and ensures consistency, compliance, and long-term maintainability.
Developers don’t need to request IAM roles, wait for manual provisioning, or understand cloud APIs. They define what they need in Git and the platform does the rest, with built-in safeguards in place.
Visualizing Cloud Resources Managed by Crossplane in ArgoCD
With Crossplane + ArgoCD, every cloud resource (like S3 buckets, SQS queues, SNS topics, and more) is represented as a native Kubernetes resource.

This means you can visualize, monitor, and manage all resources directly within the ArgoCD UI just like any other K8s object!

Key Benefits:
Infrastructure as Code: Everything is defined and versioned in Git.
Full Visibility: Resources appear and are managed directly in ArgoCD.
Real-Time Status: Always up-to-date view of resource health.
No Manual Work: Fast, repeatable, and scalable provisioning.
Developer Self-Service: Teams manage infra via Git updates.
Governance & Consistency: Platform team enforces secure, compliant templates.
Final Thoughts
GitOps isn’t just for applications anymore.
By extending GitOps to infrastructure with tools like Crossplane and ArgoCD we unlock a powerful pattern: infrastructure defined, versioned, and deployed just like application code.
This allows:
Developers to move faster without waiting for infra teams
Platform engineers to enforce guardrails without being blockers
Organizations to scale delivery across teams and environments
No more terraform apply for every S3 bucket. No more Slack tickets for every environment.
Infrastructure lives in Git. Deployment is automated. And delivery becomes a shared responsibility without the bottlenecks.

Comments