html
+
+
symfony
+
wasm
jax
meteor
*
+
+
>=
--
+
dns
+
k8s
node
+
matplotlib
+
|>
+
+
wsl
++
+
+
php
gulp
+
alpine
saml
+
==
+
+
django
+
+
+
+
+
+
+
::
+
saml
jasmine
cargo
pascal
+
+
+
gatsby
+
!!
terraform
+
+
+
dns
termux
stencil
fortran
keras
cypress
cypress
+
+
+
+
+
&&
fastapi
||
+
+
cobol
goland
+
+=
+
http
+
sails
toml
+
Back to Blog
☁️ Crossplane Infrastructure as Code on AlmaLinux 9: Complete Guide
almalinux crossplane infrastructure-as-code

☁️ Crossplane Infrastructure as Code on AlmaLinux 9: Complete Guide

Published Sep 6, 2025

Control cloud infrastructure with Crossplane on AlmaLinux 9! Learn Kubernetes-native resource management for AWS, Azure, GCP with compositions and practical examples.

5 min read
0 views
Table of Contents

☁️ Crossplane Infrastructure as Code on AlmaLinux 9: Complete Guide

Ready to manage ALL cloud resources with Kubernetes? 🚀 Today we’ll deploy Crossplane on AlmaLinux 9, turning Kubernetes into a universal cloud control plane! Let’s orchestrate everything! ✨🌍

🤔 Why is Crossplane Important?

Imagine managing AWS, Azure, and GCP from one place! 🎯 That’s Crossplane’s superpower! Here’s why it’s revolutionary:

  • 🌍 Universal Control Plane - Manage any cloud from Kubernetes!
  • 📦 Cloud Resources as CRDs - Databases, storage, networks as K8s objects
  • 🔄 Self-Healing Infrastructure - Continuous reconciliation loop
  • 🎨 Composable Resources - Build abstractions from primitives
  • 🔐 GitOps Ready - Infrastructure as code in Git
  • 🚀 No Vendor Lock-in - Switch clouds easily
  • 📊 Unified API - One way to manage everything
  • 💡 Platform Building - Create internal developer platforms

🎯 What You Need

Before we control the clouds, gather these:

  • ✅ AlmaLinux 9 server (8GB RAM minimum, 16GB recommended)
  • ✅ Kubernetes cluster 1.16+ (K3s, K8s, or any flavor)
  • ✅ kubectl configured and working
  • ✅ Helm 3.0+ installed
  • ✅ Cloud provider accounts (AWS/Azure/GCP)
  • ✅ Cloud credentials ready
  • ✅ Basic Kubernetes knowledge
  • ✅ Ready for cloud domination! 🎉

📝 Step 1: Prepare AlmaLinux Environment

Let’s prepare your system for Crossplane! 🛠️

Install Prerequisites

# Update system packages
sudo dnf update -y  # Keep everything current

# Install required tools
sudo dnf install -y git curl wget jq

# Verify Kubernetes cluster
kubectl get nodes  # All should be Ready
kubectl version --short  # Check version 1.16+

# Install Helm if not present
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Verify Helm
helm version  # Shows version info

# Create crossplane-system namespace
kubectl create namespace crossplane-system

Install Crossplane CLI

# Download Crossplane CLI
curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh

# Or download specific version
CROSSPLANE_VERSION="1.14.0"  # Check latest at crossplane.io
curl -LO "https://releases.crossplane.io/stable/v${CROSSPLANE_VERSION}/bin/linux_amd64/crank"
chmod +x crank
sudo mv crank /usr/local/bin/crossplane
sudo ln -s /usr/local/bin/crossplane /usr/local/bin/kubectl-crossplane

# Verify installation
crossplane --version  # Shows version
kubectl crossplane --help  # Plugin works

🔧 Step 2: Install Crossplane

Time to deploy the universal control plane! 🎊

Install with Helm

# Add Crossplane Helm repository
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update

# Install Crossplane
helm install crossplane \
  --namespace crossplane-system \
  --create-namespace \
  crossplane-stable/crossplane \
  --version 1.14.0 \
  --wait

# Verify installation
kubectl get pods -n crossplane-system  # Should be Running
kubectl get crds | grep crossplane  # Shows CRDs

# Check Crossplane status
kubectl get all -n crossplane-system
helm list -n crossplane-system

Configure RBAC

# Create service account for Crossplane
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: crossplane-admin
  namespace: crossplane-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: crossplane-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: crossplane-admin
  namespace: crossplane-system
EOF

🌟 Step 3: Configure Cloud Providers

Let’s connect to cloud providers! ☁️

Install AWS Provider

# Install AWS Provider
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws
spec:
  package: xpkg.upbound.io/upbound/provider-aws:v0.47.0
EOF

# Wait for provider to be healthy
kubectl get providers
watch kubectl get providers  # Wait for HEALTHY

# Create AWS credentials secret
cat <<EOF > aws-credentials.txt
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY
aws_secret_access_key = YOUR_AWS_SECRET_KEY
EOF

kubectl create secret generic aws-secret \
  -n crossplane-system \
  --from-file=creds=./aws-credentials.txt

# Configure the Provider
cat <<EOF | kubectl apply -f -
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-secret
      key: creds
  region: us-west-2
EOF

# Clean up credentials file
rm aws-credentials.txt

Install Azure Provider

# Install Azure Provider
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-azure
spec:
  package: xpkg.upbound.io/upbound/provider-azure:v0.42.0
EOF

# Create Azure credentials
# First, create service principal in Azure:
# az ad sp create-for-rbac --role Owner --scopes /subscriptions/YOUR_SUB_ID

cat <<EOF > azure-credentials.json
{
  "clientId": "YOUR_CLIENT_ID",
  "clientSecret": "YOUR_CLIENT_SECRET",
  "subscriptionId": "YOUR_SUBSCRIPTION_ID",
  "tenantId": "YOUR_TENANT_ID"
}
EOF

kubectl create secret generic azure-secret \
  -n crossplane-system \
  --from-file=creds=./azure-credentials.json

# Configure Azure Provider
cat <<EOF | kubectl apply -f -
apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: azure-secret
      key: creds
EOF

rm azure-credentials.json

Install GCP Provider

# Install GCP Provider
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-gcp
spec:
  package: xpkg.upbound.io/upbound/provider-gcp:v0.44.0
EOF

# Create GCP credentials (use service account JSON)
kubectl create secret generic gcp-secret \
  -n crossplane-system \
  --from-file=creds=./gcp-credentials.json

# Configure GCP Provider
cat <<EOF | kubectl apply -f -
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  projectID: YOUR_PROJECT_ID
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: gcp-secret
      key: creds
EOF

✅ Step 4: Create Cloud Resources

Let’s provision real cloud infrastructure! 🏗️

Create AWS S3 Bucket

# Create S3 bucket with Crossplane
cat <<EOF | kubectl apply -f -
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  name: crossplane-demo-bucket
  namespace: default
spec:
  forProvider:
    region: us-west-2
    tags:
      Environment: Demo
      ManagedBy: Crossplane
  providerConfigRef:
    name: default
EOF

# Check bucket status
kubectl get bucket
kubectl describe bucket crossplane-demo-bucket

# Bucket appears in AWS! 🎉

Create Azure Storage Account

# Create Resource Group first
cat <<EOF | kubectl apply -f -
apiVersion: azure.upbound.io/v1beta1
kind: ResourceGroup
metadata:
  name: crossplane-demo-rg
spec:
  forProvider:
    location: West US 2
    tags:
      ManagedBy: Crossplane
  providerConfigRef:
    name: default
EOF

# Create Storage Account
cat <<EOF | kubectl apply -f -
apiVersion: storage.azure.upbound.io/v1beta1
kind: Account
metadata:
  name: crossplanedemo2024
spec:
  forProvider:
    resourceGroupNameRef:
      name: crossplane-demo-rg
    location: West US 2
    accountTier: Standard
    accountReplicationType: LRS
    tags:
      Environment: Demo
  providerConfigRef:
    name: default
EOF

# Monitor creation
kubectl get resourcegroup,account

Create Multi-Cloud Database Setup

# Create Composition for database abstraction
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: database-composition
spec:
  compositeTypeRef:
    apiVersion: platform.example.io/v1alpha1
    kind: XDatabase
  resources:
    # AWS RDS Instance
    - name: aws-rds
      base:
        apiVersion: rds.aws.upbound.io/v1beta1
        kind: Instance
        spec:
          forProvider:
            region: us-west-2
            instanceClass: db.t3.micro
            engine: postgres
            engineVersion: "14"
            allocatedStorage: 20
            username: dbadmin
      patches:
        - fromFieldPath: "spec.parameters.size"
          toFieldPath: "spec.forProvider.allocatedStorage"
    # Azure PostgreSQL
    - name: azure-postgres
      base:
        apiVersion: dbforpostgresql.azure.upbound.io/v1beta1
        kind: Server
        spec:
          forProvider:
            location: West US 2
            version: "14"
            sslEnforcement: Enabled
            sku:
              name: B_Gen5_1
              tier: Basic
EOF

🎮 Quick Examples

Let’s explore Crossplane’s amazing features! 🚀

Example 1: Create Kubernetes Cluster on AWS

# Create EKS cluster with Crossplane
cat <<EOF | kubectl apply -f -
apiVersion: eks.aws.upbound.io/v1beta1
kind: Cluster
metadata:
  name: crossplane-eks-demo
spec:
  forProvider:
    region: us-west-2
    version: "1.28"
    roleArnRef:
      name: eks-cluster-role
    vpcConfig:
      - subnetIdRefs:
        - name: subnet-1
        - name: subnet-2
---
apiVersion: eks.aws.upbound.io/v1beta1
kind: NodeGroup
metadata:
  name: crossplane-eks-nodes
spec:
  forProvider:
    region: us-west-2
    clusterNameRef:
      name: crossplane-eks-demo
    scalingConfig:
      - desiredSize: 2
        maxSize: 3
        minSize: 1
    instanceTypes:
      - t3.medium
EOF

# Watch cluster creation
watch kubectl get cluster,nodegroup

Example 2: Build Platform API

# Create XRD (Composite Resource Definition)
cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xapplications.platform.example.io
spec:
  group: platform.example.io
  names:
    kind: XApplication
    plural: xapplications
  versions:
  - name: v1alpha1
    served: true
    referenceable: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              parameters:
                type: object
                properties:
                  storageGB:
                    type: integer
                    default: 10
                  dbSize:
                    type: string
                    default: small
                required:
                - storageGB
EOF

# Now developers can request apps!
cat <<EOF | kubectl apply -f -
apiVersion: platform.example.io/v1alpha1
kind: Application
metadata:
  name: my-app
spec:
  parameters:
    storageGB: 20
    dbSize: medium
EOF

Example 3: GitOps with ArgoCD

# Create Crossplane Application in ArgoCD
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: crossplane-resources
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/crossplane-configs
    targetRevision: main
    path: resources
  destination:
    server: https://kubernetes.default.svc
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

# Now infrastructure is GitOps managed! 🎉

🚨 Fix Common Problems

Don’t panic! Here are solutions! 💪

Problem 1: Provider Not Healthy

# Check provider status
kubectl get providers
kubectl describe provider provider-aws

# Check provider pod logs
kubectl get pods -n crossplane-system
kubectl logs -n crossplane-system provider-aws-xxx

# Reinstall provider
kubectl delete provider provider-aws
kubectl apply -f provider.yaml

# Check RBAC permissions
kubectl auth can-i '*' '*' --as=system:serviceaccount:crossplane-system:crossplane

Problem 2: Resources Not Creating

# Check resource status
kubectl describe bucket my-bucket

# Look for events
kubectl get events --sort-by='.lastTimestamp'

# Check provider config
kubectl get providerconfig
kubectl describe providerconfig default

# Verify credentials
kubectl get secret aws-secret -n crossplane-system -o yaml

# Force reconciliation
kubectl annotate bucket my-bucket crossplane.io/paused-

Problem 3: Composition Issues

# List compositions
kubectl get compositions

# Check XRD
kubectl get xrd
kubectl describe xrd xapplications.platform.example.io

# Debug composition
crossplane beta trace xapplication.platform.example.io/my-app

# Check composite resource
kubectl get composite -A

📋 Simple Commands Summary

Your Crossplane command toolkit! 📚

CommandWhat It DoesWhen to Use
helm install crossplaneInstall CrossplaneInitial setup
kubectl get providersList providersCheck health
kubectl get managedShow all resourcesView infrastructure
kubectl get bucket,instanceList specific resourcesCheck status
crossplane beta traceDebug compositionsTroubleshoot
kubectl get xrdList XRDsView APIs
kubectl get compositionsShow compositionsCheck templates
kubectl describe <resource>Resource detailsDebug issues
kubectl delete <resource>Delete resourceClean up
kubectl get eventsShow eventsDebug problems

💡 Tips for Success

Master Crossplane with these pro tips! 🏆

Resource Management

  • 🏷️ Always tag resources appropriately
  • 📝 Use provider configs for different environments
  • 🔄 Implement deletion policies carefully
  • 💾 Back up resource definitions
  • 🎯 Start small, then compose

Best Practices

  • 🔐 Rotate cloud credentials regularly
  • 📊 Monitor provider health
  • 🛡️ Implement RBAC properly
  • 📈 Track resource costs
  • 🔍 Use management policies
  • 🎨 Build reusable compositions
  • 💡 Version your configurations

Platform Building

  • 🏗️ Create abstractions for developers
  • 📦 Hide complexity in compositions
  • 🎯 Provide self-service APIs
  • 🔄 Standardize resource configurations
  • 📝 Document your platform APIs

🏆 What You Learned

Incredible work! You’re now a Crossplane expert! 🎉 You can:

  • ✅ Install Crossplane on AlmaLinux 9
  • ✅ Configure multiple cloud providers
  • ✅ Create cloud resources declaratively
  • ✅ Build compositions and abstractions
  • ✅ Implement GitOps for infrastructure
  • ✅ Create platform APIs with XRDs
  • ✅ Troubleshoot common issues
  • ✅ Manage multi-cloud infrastructure

🎯 Why This Matters

You’ve unified ALL cloud infrastructure management! 🚀 With Crossplane:

  • One Control Plane - Manage everything from Kubernetes
  • True Multi-Cloud - AWS, Azure, GCP from one place
  • Self-Healing - Continuous reconciliation keeps everything in sync
  • GitOps Native - Infrastructure as code in Git
  • Platform Building - Create internal developer platforms
  • No Lock-in - Switch clouds without changing tools
  • Cost Control - Unified view of all resources

Your infrastructure is now as cloud-native as your applications! No more Terraform state files, no more cloud console clicking. Everything is Kubernetes resources!

Keep exploring advanced features like provider functions, nested compositions, and building complete platform APIs. You’re doing infrastructure like the cloud giants! 🌟

Remember: The cloud is just someone else’s computer - Crossplane makes it yours! Happy orchestrating! 🎊☁️


P.S. - Join the Crossplane community, contribute providers, and share your platform engineering journey! The future is control planes! ⭐🙌