Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Self-Service Infrastructure with Crossplane

By Kokil Thapa | Last reviewed: August 2026

Self-service infrastructure with Crossplane solves the most persistent bottleneck in modern web development: engineers waiting days for DevOps to provision databases, buckets, or DNS records. Instead of filing tickets, your team declares infrastructure needs directly in Kubernetes manifests, treating cloud resources exactly like application deployments. This shift transforms infrastructure from a gatekept service into a scalable, auditable API surface that integrates natively with your existing CI/CD pipelines and GitOps workflows.

How does self-service infrastructure with Crossplane differ from Terraform?

The distinction between microservice architecture strategies and infrastructure tooling often blurs, but the operational model differs fundamentally. Terraform operates as an imperative pipeline tool: you write HCL, run terraform apply, and state is reconciled at execution time. Crossplane runs as a continuous control plane inside your Kubernetes cluster, constantly reconciling desired state against actual cloud state using the same reconciliation loop pattern familiar to any K8s operator.

Terraform ModelDeveloper writes HCLCI Pipeline triggers applyState reconciled onceDrift until next applyCrossplane ModelDeveloper commits YAMLK8s API Server acceptsControl Plane reconcilesContinuous drift correction
Terraform reconciles state only during pipeline execution; Crossplane continuously enforces desired state through the Kubernetes control plane

In practice, this means Crossplane detects and corrects drift automatically. If someone manually modifies an RDS instance in the AWS console, Crossplane’s reconciliation loop will revert it to match the declared spec within minutes. Terraform won’t catch this until the next planned apply. For teams running production Laravel APIs or eCommerce platforms where configuration drift causes subtle bugs, this continuous enforcement is transformative.

CriteriaTerraformCrossplane
Execution ModelImperative pipeline runsContinuous K8s controller
Drift DetectionOnly on plan/applyAutomatic reconciliation
State StorageExternal backend (S3, Consul)etcd (K8s native)
Abstraction LayerModules (HCL)XRDs + Compositions (YAML)
RBAC IntegrationSeparate IAM policiesNative K8s RBAC
Multi-cloudProvider pluginsProvider CRDs unified API
Learning CurveHCL syntaxK8s CRD authoring

What are Composite Resource Definitions and why do they matter?

Composite Resource Definitions (XRDs) are the abstraction layer that makes self-service infrastructure with Crossplane actually safe for developer consumption. Without XRDs, you’re just exposing raw cloud provider CRDs directly to application teams — which defeats the purpose entirely. An XRD defines a simplified, opinionated interface that hides provider-specific complexity while enforcing organizational standards.

Think of XRDs as the contract between your platform team and your application developers. The platform team encodes best practices, security requirements, and naming conventions into the composition. The developer sees only the fields relevant to their workload. On a recent legal-tech portal project, we defined a PostgreSQLInstance XRD that exposed only database name, storage size, and performance tier. Backup schedules, encryption settings, VPC placement, and parameter groups were all enforced by the composition — developers couldn’t accidentally create unencrypted public databases even if they tried.

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: postgresqlinstances.platform.example.com
spec:
  group: platform.example.com
  names:
    kind: PostgreSQLInstance
    plural: postgresqlinstances
  claimNames:
    kind: PostgreSQLClaim
    plural: postgresqlclaims
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                dbName:
                  type: string
                  description: "Application database name"
                storageGB:
                  type: integer
                  minimum: 20
                  maximum: 500
                tier:
                  type: string
                  enum: [development, staging, production]
              required: [dbName, tier]

This XRD constrains input at the schema level. The tier enum prevents typos. Storage bounds prevent both under-provisioning and runaway costs. When a developer submits a claim against this XRD, Crossplane’s composition engine maps these simple fields to dozens of underlying AWS or GCP resource specifications. The developer never touches RDSInstance, SecurityGroup, or DBSubnetGroup CRDs directly.

DeveloperPostgreSQLClaimdbName, tier, sizeCrossplane Control PlaneXRD Schema ValidationComposition EngineProvider ControllersCloud ProvidersAWS RDSGCP Cloud SQLAzure DatabaseUpcloud / Local
XRD abstraction layer decouples developer-facing claims from underlying provider resources, enabling multi-cloud portability and enforced standards

The composition itself uses patch-and-transform or function pipelines to wire everything together. In 2026, function pipelines have largely replaced patch-and-transform for non-trivial compositions because they support conditional logic, iteration, and external data lookups without resorting to fragile nested patches. You write compositions in Go, Python, or TypeScript as containerized functions, giving you real programming language expressiveness instead of YAML templating gymnastics.

How do you implement safe self-service infrastructure with Crossplane guardrails?

Exposing infrastructure APIs without guardrails is how you get a Rs 800,000/month (~USD 6,000) surprise bill from orphaned GPU instances. Safety in self-service infrastructure with Crossplane requires defense in depth across four layers: schema validation, RBAC scoping, policy enforcement, and cost controls.

  1. Schema-level constraints: Use OpenAPI validation in your XRDs to enforce minimums, maximums, enums, and regex patterns. Never trust developers to pick appropriate instance sizes or storage tiers voluntarily. Encode your organization’s approved catalog directly in the schema.
  2. Namespace-scoped RBAC: Give each team or project its own namespace with RoleBindings that permit only specific claim types. A frontend team shouldn’t be able to provision VPCs or IAM roles. Use Kubernetes’ native RBAC rather than building custom admission webhooks when possible.
  3. OPA/Kyverno policies: Deploy Open Policy Agent or Kyverno as a secondary validation layer for rules that don’t fit cleanly in OpenAPI schemas. Examples include requiring specific tags for cost allocation, blocking certain regions, or enforcing encryption-at-rest on all storage resources. These policies evaluate claims before Crossplane processes them.
  4. Budget alerts and quotas: Configure cloud provider budget alerts independently of Crossplane. Crossplane doesn’t track spend. Set up AWS Budgets, GCP Billing Alerts, or Azure Cost Management to notify platform teams when projected spend exceeds thresholds. Consider integrating with tools like Kubecost for cluster-level attribution.

On production systems I’ve worked on, the combination of XRD schema constraints plus OPA policies caught roughly 90% of misconfiguration attempts before resources were ever provisioned. The remaining 10% were edge cases involving composition bugs — which is why testing compositions in isolated clusters before promoting to production is non-negotiable.

# Example Kyverno policy enforcing mandatory cost-allocation tags
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-cost-tags
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-tags
      match:
        any:
          - resources:
              kinds:
                - PostgreSQLClaim
                - RedisClaim
                - S3BucketClaim
      validate:
        message: "All infrastructure claims must include team and project tags"
        pattern:
          metadata:
            labels:
              team: "?*"
              project: "?*"

This policy blocks any claim missing required labels. Combined with namespace RBAC, it ensures every provisioned resource is attributable to a specific team and project for chargeback or showback reporting. For Nepal-based clients operating on tighter budgets, this attribution is often more important than the technical capability itself.

What does a production Crossplane deployment architecture look like?

A common mistake is deploying Crossplane into the same cluster as your application workloads. Don’t do this. Crossplane manages infrastructure that your applications depend on; if the app cluster dies, you lose the ability to manage the infrastructure keeping it alive. Production deployments use a dedicated management cluster pattern.

Management ClusterCrossplane CoreProvider ControllersXRDs + CompositionsGitOps (ArgoCD/Flux)OPA / Kyverno PoliciesWorkload Cluster ALaravel App + VueClaims consumed hereWorkload Cluster BWooCommerce StoreClaims consumed hereWorkload Cluster CLegal-tech PortalCloud ResourcesRDS / Cloud SQLElastiCache / RedisS3 / GCS BucketsVPC / NetworkingIAM / Secrets
Production topology separates the Crossplane management cluster from workload clusters, ensuring infrastructure control survives application cluster failures

The management cluster should be small (3 nodes, modest instance sizes) and boring. It runs Crossplane core, provider controllers, your compositions, and GitOps tooling. Nothing else. Application teams interact with it exclusively through Git pull requests that modify claim manifests. ArgoCD or Flux syncs those changes into the management cluster, triggering Crossplane reconciliation.

Workload clusters consume infrastructure through connection secrets that Crossplane writes automatically. When a developer creates a PostgreSQLClaim, Crossplane provisions the RDS instance, creates a Kubernetes Secret containing the connection string, and optionally propagates that secret to the target workload cluster using a secret store provider. Your Laravel application mounts the secret and connects — no manual credential distribution, no environment variable sprawl. For teams already practicing GitOps for CI/CD pipeline automation, this fits naturally into existing workflows.

When should you choose self-service infrastructure with Crossplane over alternatives?

Crossplane isn’t universally superior. It excels when your team already operates Kubernetes as a primary platform and wants infrastructure management to follow the same declarative, GitOps-driven patterns. It struggles when your team lacks K8s operational maturity or when infrastructure needs are simple enough that Terraform modules suffice.

Choose Crossplane when you need continuous drift correction, native K8s RBAC integration, multi-cloud abstraction through a single API, or tight coupling between application deployments and their infrastructure dependencies. Avoid it when your team is still learning Kubernetes basics, when you have fewer than three developers consuming infrastructure, or when your cloud footprint is single-provider and stable. The operational overhead of maintaining a management cluster, authoring compositions, and debugging provider controller issues is real — budget at least one engineer’s ongoing attention for platforms serving fewer than ten teams.

For Nepal-based organizations evaluating this technology, consider your team’s existing skill set honestly. If your developers are comfortable with kubectl, Helm, and GitOps workflows, Crossplane accelerates delivery significantly. If they’re primarily PHP/Laravel developers who touch infrastructure occasionally, Terraform with well-documented modules and a simple CI pipeline may deliver faster time-to-value. The best tool is the one your team can operate reliably at 2 AM during an outage, not the one with the most elegant architecture diagram.

Getting Started with Self-Service Infrastructure with Crossplane

Start small. Pick one resource type your developers request frequently — typically PostgreSQL, Redis, or object storage. Define an XRD with conservative defaults, write a single composition targeting your primary cloud provider, and deploy it in a test management cluster. Let two or three teams use it for non-production workloads for a month before expanding scope. Measure adoption friction, document gaps, and iterate on the abstraction before declaring victory. Self-service infrastructure with Crossplane succeeds through incremental trust-building, not big-bang platform launches. If you’re evaluating whether this approach fits your organization’s infrastructure maturity, reach out to discuss your specific context.

Frequently Asked Questions

Crossplane extends Kubernetes to manage cloud infrastructure via declarative APIs, enabling developers to provision resources like databases and buckets using standard kubectl commands without direct cloud console access.

Crossplane runs as a continuous control plane inside Kubernetes, reconciling desired state automatically, whereas Terraform is typically a CLI-driven, push-based tool requiring separate CI pipelines and state management for each execution.

Crossplane requires Kubernetes 1.28 or higher, Helm 3.x, and sufficient RBAC permissions; production clusters should allocate at least 500m CPU and 512Mi RAM for the core controller plus additional resources per installed provider.

Yes, Crossplane is Apache 2.0 licensed open-source software with no licensing fees, though you still pay underlying cloud provider costs for provisioned resources and operational overhead for maintaining the management cluster.

Choose Crossplane when your team already operates Kubernetes natively and wants GitOps-native infrastructure that integrates directly with existing Kustomize, ArgoCD, or Flux workflows rather than adopting a separate IaC runtime or language SDK.

Install via Helm using helm install crossplane crossplane-stable/crossplane --namespace crossplane-system --create-namespace, then add providers like provider-aws-s3 with ProviderConfig referencing an IRSA-enabled service account for secure AWS authentication without static credentials.

Yes, platform teams define CompositeResourceDefinitions and Compositions that expose simplified abstractions; developers request only approved resource types through custom APIs while guardrails enforce tagging, networking, and security policies automatically during reconciliation.

Crossplane integrates with external secret stores like AWS Secrets Manager, HashiCorp Vault, or Kubernetes External Secrets Operator via StoreConfigs, ensuring credentials never appear in CRDs and are injected securely at provisioning time.

The Crossplane controller continuously reconciles actual cloud state against the declared spec every few minutes, automatically correcting drift caused by manual console changes or external processes without requiring manual intervention or re-running apply commands.

Use kubectl describe on the composite and managed resources to inspect events and conditions, check crossplane-controller-manager logs for reconciliation errors, and validate provider credentials and API quotas since most failures stem from permission or limit issues.

Yes, Crossplane supports simultaneous AWS, GCP, Azure, and on-premise providers within a single cluster, allowing compositions to orchestrate resources across clouds while maintaining unified lifecycle management and consistent developer interfaces.

Upgrade providers by updating the Provider package version in your manifest and applying it; Crossplane performs rolling updates of provider controllers while preserving existing managed resources, but always test upgrades in staging first since breaking schema changes can occur between major versions.

Teams often underestimate composition complexity, skip proper RBAC scoping leading to overprivileged service accounts, neglect observability setup making debugging difficult, and fail to establish clear ownership boundaries between platform and application teams causing operational friction.

Crossplane CRDs are standard Kubernetes manifests fully compatible with ArgoCD sync policies; commit XRDs, Compositions, and claims to Git, let ArgoCD reconcile them, and Crossplane handles cloud provisioning, creating a fully declarative end-to-end infrastructure pipeline.

Enable Prometheus metrics via the built-in /metrics endpoint, monitor crossplane_controller_reconcile_errors_total and provider-specific failure gauges, alert on sustained reconciliation failures exceeding five minutes, and track managed resource readiness status to catch provisioning bottlenecks early.

Share this article

Quick Contact Options
Choose how you want to connect me: