GitOps Workflow: Pull-Based Deployment with Backstage, Flux, and Crossplane
Overviewβ
This document illustrates how developers use Backstage to create full-stack applications that are automatically deployed via Flux using a pull-based GitOps model.
Architecture Diagramβ
graph TB
%% Actors - Using GitLab Personas
%% https://handbook.gitlab.com/handbook/product/personas/
Sasha["π©βπ» Sasha<br/>Software Developer<br/>Builds Features"]
Priyanka["ποΈ Priyanka<br/>Platform Engineer<br/>Creates Infrastructure"]
Rachel["π¦ Rachel<br/>Release Manager<br/>Ships to Production"]
Sidney["π§ Sidney<br/>Systems Admin<br/>Maintains Clusters"]
Amy["π Amy<br/>Security Engineer<br/>Ensures Compliance"]
%% Backstage Layer
subgraph Backstage["π Backstage Portal"]
Catalog["Software Catalog"]
Scaffolder["Scaffolder Engine"]
NodeTemplate["π¦ Node Development<br/>Template"]
K8sPlugin["π Kubernetes Plugin<br/>Resource Monitor"]
end
%% Simone's Templates
subgraph Templates["Platform Templates"]
FrontendTpl["Frontend App<br/>Template"]
BackendTpl["Backend API<br/>Template"]
PostgresTpl["PostgreSQL<br/>Template"]
Composition["π― Composition:<br/>Node Development<br/>Frontend + Backend + DB"]
end
%% GitHub Repositories
subgraph GitHub["π GitHub Organization"]
subgraph AppRepos["Application Repositories"]
FrontendRepo["dashboard-frontend<br/>React App"]
BackendRepo["dashboard-backend<br/>Node.js API"]
end
DeployRepo["π dashboard-deploy<br/>Flux Manifests<br/>β
flux-managed"]
end
%% Flux GitOps
subgraph FluxGitOps["π Flux - Pull-Based GitOps"]
GitController["Source Controller<br/>Polls every 1min"]
Kustomization["Kustomization Controller"]
Note["β‘ PULL not PUSH<br/>Flux pulls from Git"]
end
%% Environments
subgraph Environments["π Multi-Environment Infrastructure"]
subgraph DevEnv["Development Environment"]
subgraph CrossplaneDev["π― Crossplane Dev"]
XRDDev["XNodeApp<br/>Custom Resource"]
CompDefDev["Composition Definition"]
ResourcesDev["Managed Resources"]
end
subgraph K8sDev["βΈοΈ Kubernetes Dev Cluster"]
subgraph NamespaceDev["dashboard-dev namespace"]
FrontendDev["Frontend<br/>Deployment"]
BackendDev["Backend<br/>Deployment"]
PostgresDev["PostgreSQL<br/>StatefulSet"]
end
end
end
subgraph QAEnv["QA Environment"]
subgraph CrossplaneQA["π― Crossplane QA"]
XRDQA["XNodeApp<br/>Custom Resource"]
CompDefQA["Composition Definition"]
ResourcesQA["Managed Resources"]
end
subgraph K8sQA["βΈοΈ Kubernetes QA Cluster"]
subgraph NamespaceQA["dashboard-qa namespace"]
FrontendQA["Frontend<br/>Deployment"]
BackendQA["Backend<br/>Deployment"]
PostgresQA["PostgreSQL<br/>StatefulSet"]
end
end
end
subgraph ProdEnv["Production Environment"]
subgraph CrossplaneProd["π― Crossplane Prod"]
XRDProd["XNodeApp<br/>Custom Resource"]
CompDefProd["Composition Definition"]
ResourcesProd["Managed Resources"]
end
subgraph K8sProd["βΈοΈ Kubernetes Prod Cluster"]
subgraph NamespaceProd["dashboard namespace"]
FrontendProd["Frontend<br/>Deployment"]
BackendProd["Backend<br/>Deployment"]
PostgresProd["PostgreSQL<br/>StatefulSet"]
ServiceProd["Services"]
IngressProd["Ingress"]
end
end
end
end
%% Priyanka's Flow (Platform Engineering)
Priyanka -->|"Step 1: Creates Templates"| Templates
FrontendTpl --> Composition
BackendTpl --> Composition
PostgresTpl --> Composition
Composition -->|"Step 2: Registers"| NodeTemplate
%% Sasha's Flow (Developer Experience)
Sasha -->|"Step 3: Browse Catalog"| Catalog
Catalog -->|"Step 4: Select Template"| NodeTemplate
NodeTemplate -->|"Step 5: Fill Parameters"| Scaffolder
Scaffolder -->|"Step 6a: Create Frontend Repo"| FrontendRepo
Scaffolder -->|"Step 6b: Create Backend Repo"| BackendRepo
Scaffolder -->|"Step 6c: Create Deploy Repo"| DeployRepo
%% Amy's Security Review
Amy -->|"Reviews Security"| DeployRepo
Amy -.->|"Security Policies"| Kustomization
%% Rachel's Release Management
Rachel -->|"Manages Releases"| DeployRepo
Rachel -.->|"Approves Prod Deploy"| ProdEnv
%% Sidney's Operations
Sidney -->|"Monitors Infrastructure"| K8sPlugin
Sidney -.->|"Manages Clusters"| Environments
%% GitOps Pull Flow
DeployRepo -.->|"Step 7: PULL Changes<br/>Not Push!"| GitController
GitController -->|"Step 8: Fetch Manifests"| Kustomization
Kustomization -->|"Step 9: Apply to Dev"| XRDDev
Kustomization -->|"Step 9: Apply to QA"| XRDQA
Kustomization -->|"Step 9: Apply to Prod"| XRDProd
%% Crossplane Provisioning - Dev
XRDDev -->|"Step 10: Use Composition"| CompDefDev
CompDefDev -->|"Step 11: Create Resources"| ResourcesDev
ResourcesDev -->|"Step 12: Deploy Frontend"| FrontendDev
ResourcesDev -->|"Step 13: Deploy Backend"| BackendDev
ResourcesDev -->|"Step 14: Deploy Database"| PostgresDev
%% Crossplane Provisioning - QA
XRDQA --> CompDefQA
CompDefQA --> ResourcesQA
ResourcesQA --> FrontendQA
ResourcesQA --> BackendQA
ResourcesQA --> PostgresQA
%% Crossplane Provisioning - Prod
XRDProd --> CompDefProd
CompDefProd --> ResourcesProd
ResourcesProd --> FrontendProd
ResourcesProd --> BackendProd
ResourcesProd --> PostgresProd
ResourcesProd --> ServiceProd
ResourcesProd --> IngressProd
%% Backstage Monitoring
K8sPlugin -.->|"Reads Resource Status"| ResourcesDev
K8sPlugin -.->|"Reads Resource Status"| ResourcesQA
K8sPlugin -.->|"Reads Resource Status"| ResourcesProd
K8sPlugin -.->|"Syncs to Catalog"| Catalog
%% Styling
classDef actor fill:#e1f5fe,stroke:#01579b,stroke-width:2px
classDef backstage fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
classDef template fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef repo fill:#f5f5f5,stroke:#424242,stroke-width:2px
classDef deploy fill:#e8f5e9,stroke:#1b5e20,stroke-width:3px
classDef flux fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
classDef crossplane fill:#fce4ec,stroke:#880e4f,stroke-width:2px
classDef k8s fill:#e3f2fd,stroke:#0d47a1,stroke-width:2px
classDef environment fill:#fff9c4,stroke:#f57f17,stroke-width:3px
classDef monitor fill:#e1bee7,stroke:#6a1b9a,stroke-width:2px
class Sasha,Priyanka,Rachel,Sidney,Amy actor
class Catalog,Scaffolder,NodeTemplate backstage
class K8sPlugin monitor
class FrontendTpl,BackendTpl,PostgresTpl,Composition template
class FrontendRepo,BackendRepo repo
class DeployRepo deploy
class GitController,Kustomization,Note flux
class XRDDev,XRDProd,XRDQA,CompDefDev,CompDefQA,CompDefProd,ResourcesDev,ResourcesQA,ResourcesProd crossplane
class FrontendDev,BackendDev,PostgresDev,FrontendQA,BackendQA,PostgresQA,FrontendProd,BackendProd,PostgresProd,ServiceProd,IngressProd,NamespaceDev,NamespaceQA,NamespaceProd k8s
class DevEnv,QAEnv,ProdEnv environment
User Storiesβ
We use GitLab's documented personas to represent typical users of our platform. These personas are based on extensive user research and help us design better experiences.
ποΈ Priyanka's Story: Building the Platformβ
Priyanka (Platform Engineer) is responsible for building and maintaining the platform that development teams use. Priyanka creates reusable templates, manages Kubernetes clusters, and provides self-service infrastructure.
What Priyanka Creates:β
-
Individual Component Templates:
- Frontend Template: React app with TypeScript, routing, and state management
- Backend Template: Node.js API with Express, authentication, and database connection
- PostgreSQL Template: Database with persistent storage and backups
-
Composition: Node Development
- Combines all three components into one deployable unit
- Uses Crossplane Composition to define infrastructure
- Creates Frontend Deployment, Backend Deployment, and PostgreSQL database
- Example composition structure:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: node-development
spec:
compositeTypeRef:
apiVersion: platform.io/v1
kind: XNodeApp
resources:
- name: frontend
base:
apiVersion: apps/v1
kind: Deployment
- name: backend
base:
apiVersion: apps/v1
kind: Deployment
- name: database
base:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
-
Backstage Template Registration:
- Creates
template-node-development
repository - Backstage auto-discovers and adds to catalog
- Developers can now self-serve complete stacks
- Creates
π©βπ» Sasha's Story: Creating a Dashboardβ
Sasha (Software Developer) is a software developer who wants to ship features as quickly and reliably as possible. Sasha needs to create a metrics dashboard for the team.
Sasha's Journey:β
-
Discovery
- Opens Backstage portal
- Browses Software Catalog
- Finds "Node Development" template
-
Configuration
- Fills in the form:
- Project name:
dashboard
- Team:
platform-team
- Database name:
metrics
- API port:
3001
- Enable monitoring:
true
- Project name:
- Fills in the form:
-
Magic Happens β¨
- Backstage creates THREE repositories:
dashboard-frontend
- React application codedashboard-backend
- Node.js API codedashboard-deploy
- Deployment manifests (marked withflux-managed
)
- Backstage creates THREE repositories:
-
Automatic Deployment
- Flux detects the new
dashboard-deploy
repository - Pulls the manifests (within 1 minute)
- Applies Crossplane XR (XNodeApp)
- Crossplane provisions all resources
- Full stack is running in Kubernetes!
- Flux detects the new
π Amy's Story: Securing the Platformβ
Amy (Application Security Engineer) ensures that applications meet security standards and compliance requirements.
Amy's Security Workflow:β
-
Template Security Review
- Reviews Priyanka's templates for security best practices
- Ensures secrets management is properly configured
- Validates network policies and RBAC settings
-
Deployment Manifest Scanning
- Automatically scans
dashboard-deploy
repository - Checks for exposed secrets or misconfigurations
- Enforces security policies via OPA/Gatekeeper
- Automatically scans
-
Runtime Security
- Monitors running workloads for vulnerabilities
- Sets up security policies in Crossplane compositions
- Ensures compliance with industry standards
π¦ Rachel's Story: Managing Releasesβ
Rachel (Release Manager) coordinates releases across environments and ensures smooth deployments.
Rachel's Release Process:β
-
Environment Promotion
- Reviews changes in Dev environment
- Approves promotion to QA
- Coordinates production releases
-
GitOps Workflow
- Uses Git tags for release versions
- Manages Kustomize overlays for each environment
- Controls Flux sync policies
-
Rollback Strategy
- Can quickly revert via Git
- Flux automatically applies rollback
- Zero-downtime deployments
π§ Sidney's Story: Operating the Infrastructureβ
Sidney (Systems Administrator) maintains the Kubernetes clusters and ensures platform reliability.
Sidney's Operations:β
-
Cluster Management
- Monitors cluster health via Backstage Kubernetes Plugin
- Manages node scaling and upgrades
- Configures cluster-level resources
-
Observability
- Sets up monitoring and alerting
- Uses Backstage to visualize resource usage
- Troubleshoots issues across environments
-
Disaster Recovery
- Implements backup strategies
- Tests failover procedures
- Maintains runbooks in TechDocs
Key Conceptsβ
Pull vs Push GitOpsβ
Aspect | Pull-Based (Flux) β | Push-Based (CI/CD) β |
---|---|---|
Direction | Flux pulls from Git | CI pushes to cluster |
Security | No external cluster access | Cluster credentials in CI |
Network | Cluster never exposed | Requires ingress/API access |
Source of Truth | Git only | Multiple sources |
Reconciliation | Automatic | Manual triggers |
Repository Structureβ
dashboard-frontend/ # Application code
βββ .github/
β βββ workflows/
β βββ ci.yaml # Test & build
β βββ release.yaml # Build & push image
βββ src/
βββ package.json
βββ Dockerfile
dashboard-backend/ # Application code
βββ .github/
β βββ workflows/
β βββ ci.yaml # Test & build
β βββ release.yaml # Build & push image
βββ src/
βββ package.json
βββ Dockerfile
dashboard-deploy/ # GitOps manifests
βββ base/
β βββ frontend-deployment.yaml
β βββ backend-deployment.yaml
β βββ postgres-xr.yaml
βββ overlays/
β βββ dev/
β βββ prod/
βββ kustomization.yaml
Benefitsβ
For Developers (Sasha)β
- One-click deployment - Complete stack from a form
- No YAML wrestling - Templates handle complexity
- Separation of concerns - Code separate from deployment
- Fast iteration - Push code, Flux deploys automatically
For Platform Engineers (Simone)β
- Standardization - All teams use same patterns
- Reusability - Write once, use many times
- Governance - Control via templates and compositions
- Self-service - Reduces support tickets
For Operationsβ
- GitOps - Everything tracked in Git
- Security - No cluster credentials outside
- Rollback - Simple
git revert
- Observability - Flux provides metrics and alerts
How It Worksβ
- Template Selection β Developer picks template in Backstage
- Repository Creation β Backstage creates app + deploy repos
- Code Development β Developers work in app repos
- Manifest Management β Deploy repo contains all K8s resources
- Flux Polling β Flux continuously pulls from deploy repo
- Crossplane Magic β Compositions create actual resources
- Kubernetes Reality β Everything running in the cluster
Summaryβ
This architecture provides:
- Pull-based security - Cluster pulls, never exposed
- Developer productivity - Self-service everything
- Platform scalability - Templates reduce support burden
- GitOps benefits - Version control, audit, rollback
- Multi-repo pattern - Clean separation of code and config
About the Personasβ
We use GitLab's well-researched personas to ensure our platform meets real user needs. Each persona represents real users based on extensive research:
Core Personas in Our Workflowβ
Sasha - Software Developerβ
- Goal: Ship features quickly and reliably
- Challenges: Complex infrastructure, slow deployment processes
- How we help: Self-service templates, automated GitOps deployments
Priyanka - Platform Engineerβ
- Goal: Build and maintain scalable platform infrastructure
- Challenges: Supporting diverse teams, ensuring consistency
- How we help: Crossplane compositions, Backstage templates
Rachel - Release Managerβ
- Goal: Coordinate smooth releases across environments
- Challenges: Managing dependencies, ensuring quality
- How we help: GitOps workflows, environment promotion
Sidney - Systems Administratorβ
- Goal: Maintain reliable infrastructure
- Challenges: Monitoring multiple clusters, incident response
- How we help: Backstage Kubernetes Plugin, centralized observability
Amy - Application Security Engineerβ
- Goal: Ensure applications meet security standards
- Challenges: Shift-left security, compliance requirements
- How we help: Security policies in templates, automated scanning
Additional GitLab Personasβ
The complete GitLab persona framework includes many other roles that interact with our platform:
- Parker - Product Manager: Defines requirements and priorities
- Delaney - Development Team Lead: Manages development teams
- Presley - Product Designer: Designs user experiences
- Allison - Application Ops: Manages application operations
- Cameron - Compliance Manager: Ensures regulatory compliance
These personas help us build a platform that serves the entire organization's needs.