Skip to main content

Templates Documentation

Crossplane Templates

template-dns-record

Advanced Crossplane v2 template for managing DNS records using namespaced XRs.

Overview

This template provides DNS record management using Crossplane v2's latest features including:

  • Namespaced XRs - Developers create DNSRecord XRs directly (no separate claims needed!)
  • Go Templating for flexible resource creation
  • Environment Configs for shared DNS zone configuration
  • Direct Kubernetes resource creation without provider-kubernetes
  • Status field updates to return computed FQDN

Contents

  • xrd.yaml - Composite Resource Definition (XRD) with namespaced scope
  • composition.yaml - Composition using Pipeline mode with Go templating
  • rbac.yaml - RBAC permissions for Crossplane to create ConfigMaps
  • examples/xr.yaml - Example DNSRecord resources (direct creation, no claims)

Requirements

Core Requirements

  • Crossplane v2.0+
  • Kubernetes cluster
  • Flux (for GitOps sync)

Composition Functions

Crossplane v2 requires composition functions for Pipeline mode (installed by setup-cluster.sh):

  • function-go-templating
  • function-environment-configs
  • function-auto-ready
  • function-patch-and-transform

Setup Instructions

1. Apply RBAC Permissions

# Grant Crossplane permission to create ConfigMaps
kubectl apply -f rbac.yaml

2. Verify Environment Config

# dns-config should be installed by setup-cluster.sh
kubectl get environmentconfig dns-config

# If missing, run the setup script or create manually

3. Install the XRD

kubectl apply -f xrd.yaml

4. Install the Composition

kubectl apply -f composition.yaml

5. Create a DNS Record

# Apply DNSRecord
kubectl apply -f examples/xr.yaml

# Check the status
kubectl get dnsrecords -A
kubectl describe xdnsrecord my-app-dns -n default

Usage

Creating a DNS Record (Namespaced XR)

With Crossplane v2, developers create DNSRecord resources directly in their namespaces:

apiVersion: platform.io/v1alpha1
kind: DNSRecord
metadata:
name: my-app
namespace: default
spec:
type: A
name: my-app
value: "192.168.1.100"
ttl: 3600

Key Difference: No separate claim resource needed! The DNSRecord is created directly.

Supported Record Types

  • A - IPv4 address
  • AAAA - IPv6 address
  • CNAME - Canonical name (alias)
  • TXT - Text record

Getting the FQDN

The composition automatically computes and returns the FQDN in the status:

kubectl get xdnsrecord my-app -n default -o jsonpath='{.status.fqdn}'
# Output: my-app.portal.example.com

How It Works

  1. XR Creation: Developer creates DNSRecord directly in their namespace
  2. Environment Loading: Composition loads DNS zone from EnvironmentConfig
  3. Resource Creation: Go template creates a ConfigMap in the same namespace
  4. Status Update: FQDN is computed and returned in status
  5. Ready State: Auto-ready function marks the resource as ready

Restaurant Analogy

Using our restaurant analogy from the documentation:

  • XRD (xrd.yaml) = The Menu - Shows what DNS records you can order
  • Composition = The Recipe - How to create the DNS record
  • Environment Config = The Kitchen Settings - Shared configuration (DNS zone)
  • DNSRecord = The Direct Order - Developers order directly (v2 style, no waiter/claim needed!)
  • Functions = The Kitchen Equipment - Tools for complex preparation
  • RBAC = Kitchen Access - Who can use what equipment
  • Namespace = The Table - Where your order is delivered

Customization

Changing the DNS Zone

Edit the platform environment config:

# Edit the dns-config EnvironmentConfig
kubectl edit environmentconfig dns-config

# Or update via the platform setup:
# scripts/cluster-manifests/environment-configs.yaml

Adding More Record Types

Update the XRD to include additional DNS record types in the enum.

Troubleshooting

Functions Not Working

# Check function status
kubectl get functions
kubectl describe function function-go-templating

# Check composition events
kubectl describe composition dnsrecord

RBAC Issues

# Verify RBAC is applied
kubectl get clusterrole | grep crossplane

# Check Crossplane service account permissions
kubectl auth can-i create configmaps --as=system:serviceaccount:crossplane-system:crossplane

Environment Config Not Loading

# Check environment config exists (installed by setup-cluster.sh)
kubectl get environmentconfig dns-config

# View the config
kubectl describe environmentconfig dns-config

# Check composition pipeline logs
kubectl logs -n crossplane-system deployment/crossplane -f | grep environment

DNS Record Not Creating

# Check XRD status
kubectl get xrd dnsrecords.platform.io

# Check DNSRecord resources
kubectl get xdnsrecord -A

# Check created ConfigMap
kubectl get configmap -A | grep dns

# View XR events
kubectl describe xdnsrecord my-app-dns -n default

Backstage Service Templates

service-nodejs-template

A Backstage template for creating Node.js microservices.

Features

This template creates a new Node.js service with:

  • Basic Express.js setup
  • Package.json with common dependencies
  • Backstage catalog-info.yaml for service registration
  • Ready-to-deploy structure

Using this Template

This template is automatically discovered by Backstage through GitHub integration.

Prerequisites

  • Backstage instance with GitHub integration
  • GitHub App configured for repository creation

Parameters

  • Name: The name of your service (will be used in package.json and catalog-info.yaml)
  • Repository Location: Where to create the new repository (defaults to open-service-portal organization)

Development

To test changes to this template locally:

  1. Reference it in your Backstage app-config.yaml:
catalog:
locations:
- type: url
target: https://github.com/open-service-portal/service-nodejs-template/blob/main/template.yaml
rules:
- allow: [Template]
  1. Navigate to /create in your Backstage instance
  2. The template should appear in the template list

Template Structure

.
├── template.yaml # Template definition
├── content/ # Files to be scaffolded
│ ├── catalog-info.yaml # Backstage catalog info
│ ├── package.json # Node.js package definition
│ └── index.js # Main application file
└── README.md # This file

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

service-mongodb-template

A Backstage Software Template for provisioning MongoDB database instances using Crossplane.

Overview

This template creates the necessary Crossplane resources to provision a MongoDB database instance in your Kubernetes cluster. It includes:

  • XRD (Composite Resource Definition): Defines the MongoDB API
  • Composition: Implements the MongoDB provisioning logic
  • Example Claim: Shows how to request a MongoDB instance

Features

  • 🚀 Self-Service Provisioning: Developers can provision MongoDB instances through Backstage
  • ⚙️ Configurable Storage: Choose storage size from 1GB to 100GB
  • 🔧 Automatic DNS: Creates DNS records for database access
  • 📊 Status Tracking: Connection strings available in resource status

Prerequisites

Crossplane Installation

Ensure Crossplane is installed in your cluster:

kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

Required Providers

This template requires the following Crossplane providers:

  1. Provider NOP (for simulation/testing):
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-nop
spec:
package: xpkg.upbound.io/crossplane-contrib/provider-nop:v0.2.0
EOF

Required Functions

Install the necessary Crossplane composition functions:

kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.10.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-sequencer
spec:
package: xpkg.upbound.io/crossplane-contrib/function-sequencer:v0.3.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-environment-configs
spec:
package: xpkg.upbound.io/crossplane-contrib/function-environment-configs:v0.1.0
EOF

Usage

Through Backstage

  1. Navigate to the Software Catalog
  2. Click "Create Component"
  3. Select "MongoDB Database"
  4. Fill in the required parameters:
    • Instance Name: Unique identifier for your MongoDB instance
    • Namespace: Kubernetes namespace (default: default)
    • Storage Size: Size in GB (1-100)
    • Owner: Team or user who owns this resource

Manual Deployment

  1. Apply the XRD:
kubectl apply -f content/definition.yaml
  1. Apply the Composition:
kubectl apply -f content/composition.yaml
  1. Create a claim:
kubectl apply -f content/example.yaml

Parameters

ParameterDescriptionTypeDefaultRequired
nameInstance namestring-Yes
namespaceKubernetes namespacestringdefaultNo
storageSizeStorage size in GBinteger10No
ownerResource ownerstringgroup:platformNo

Architecture

The template creates a composite resource that provisions:

  1. Cluster Resource: A simulated compute cluster for MongoDB
  2. DNS Record: Automatic DNS entry for database access
  3. ConfigMap: Stores configuration values
  4. NOP Resource: Simulates database provisioning delay (30s)

Connection String

After provisioning, the connection string is available in the resource status:

kubectl get mongodb <instance-name> -n <namespace> -o jsonpath='{.status.connString}'

Format: mongodb+srv://<username>:<password>@<fqdn>/<database>

Development

Testing Locally

  1. Clone this repository
  2. Install the template in Backstage:
catalog:
locations:
- type: url
target: https://github.com/open-service-portal/service-mongodb-template/blob/main/template.yaml

Customization

To customize the MongoDB provisioning:

  1. Edit content/definition.yaml to add parameters
  2. Modify content/composition.yaml to change provisioning logic
  3. Update template.yaml to expose new parameters in Backstage

Troubleshooting

Common Issues

MongoDB stuck in Creating state

  • Check if all required functions are installed
  • Verify the NOP provider is running: kubectl get providers

Connection string not appearing

  • Ensure DNS record creation succeeded
  • Check composition logs: kubectl describe composition mongodb

Permission denied errors

  • Verify Crossplane has necessary RBAC permissions
  • Check ServiceAccount bindings

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

License

MIT License - see LICENSE file for details

Support

For issues and questions:


service-cluster-template

A Backstage Software Template for provisioning Kubernetes clusters using Crossplane.

Overview

This template creates the necessary Crossplane resources to provision a Kubernetes cluster in your cloud provider. It includes:

  • XRD (Composite Resource Definition): Defines the Cluster API
  • Composition: Implements the cluster provisioning logic
  • Example Claim: Shows how to request a Kubernetes cluster

Features

  • 🚀 Multi-Cloud Support: Deploy to AWS, Azure, GCP, or on-premises
  • ⚙️ Flexible Sizing: Choose from small, medium, or large node sizes
  • 🔢 Scalable: Support for 3 to 100 nodes
  • 🔧 Version Control: Deploy specific Kubernetes versions
  • 🔒 Automatic Firewall: Security rules configured automatically
  • 📊 Kubeconfig Access: Connection details available in resource status

Prerequisites

Crossplane Installation

Ensure Crossplane is installed in your cluster:

kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

Required Providers

This template requires the following Crossplane providers:

  1. Provider NOP (for simulation/testing):
kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-nop
spec:
package: xpkg.upbound.io/crossplane-contrib/provider-nop:v0.2.0
EOF

Required Functions

Install the necessary Crossplane composition functions:

kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.10.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-sequencer
spec:
package: xpkg.upbound.io/crossplane-contrib/function-sequencer:v0.3.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-environment-configs
spec:
package: xpkg.upbound.io/crossplane-contrib/function-environment-configs:v0.1.0
EOF

Usage

Through Backstage

  1. Navigate to the Software Catalog
  2. Click "Create Component"
  3. Select "Kubernetes Cluster"
  4. Fill in the required parameters:
    • Cluster Name: Unique identifier for your cluster
    • Namespace: Kubernetes namespace (default: default)
    • Node Size: Small, medium, or large
    • Node Count: Number of nodes (3-100)
    • Storage Size: Storage per node in GB
    • Kubernetes Version: Select from available versions
    • Cloud Provider: AWS, Azure, GCP, or on-premises
    • Owner: Team or user who owns this resource

Manual Deployment

  1. Apply the XRD:
kubectl apply -f content/definition.yaml
  1. Apply the Composition:
kubectl apply -f content/composition.yaml
  1. Create a claim:
kubectl apply -f content/example.yaml

Parameters

ParameterDescriptionTypeDefaultRequired
nameCluster namestring-Yes
namespaceKubernetes namespacestringdefaultNo
nodeSizeSize of nodesstringmediumNo
nodeCountNumber of nodesinteger3No
storageSizeStorage per node (GB)integer10No
versionKubernetes versionstring1.31.1Yes
cloudProviderCloud providerstringazureNo
ownerResource ownerstringgroup:platformNo

Node Sizes

SizevCPUMemoryStorage
Small24 GBConfigurable
Medium48 GBConfigurable
Large816 GBConfigurable

Architecture

The template creates a composite resource that provisions:

  1. ConfigMap: Stores cluster configuration
  2. Cluster Resource: The actual Kubernetes cluster (simulated)
  3. Firewall Rule: Network security configuration
  4. NOP Resource: Simulates cluster provisioning delay (30s)

Accessing the Cluster

After provisioning, retrieve the kubeconfig:

# Get the base64-encoded kubeconfig
kubectl get cluster <cluster-name> -n <namespace> -o jsonpath='{.status.kubeconfig}' | base64 -d > kubeconfig.yaml

# Use the kubeconfig
export KUBECONFIG=kubeconfig.yaml
kubectl get nodes

Get the cluster IP address:

kubectl get cluster <cluster-name> -n <namespace> -o jsonpath='{.status.ipaddress}'

Development

Testing Locally

  1. Clone this repository
  2. Install the template in Backstage:
catalog:
locations:
- type: url
target: https://github.com/open-service-portal/service-cluster-template/blob/main/template.yaml

Customization

To customize the cluster provisioning:

  1. Edit content/definition.yaml to add parameters
  2. Modify content/composition.yaml to change provisioning logic
  3. Update template.yaml to expose new parameters in Backstage

Supported Kubernetes Versions

  • 1.31.1 (latest)
  • 1.30.5
  • 1.29.x series
  • 1.28.x series

Troubleshooting

Common Issues

Cluster stuck in Creating state

  • Check if all required functions are installed
  • Verify the NOP provider is running: kubectl get providers
  • Check composition status: kubectl describe composition cluster

Kubeconfig not appearing

  • Ensure environment config is properly set
  • Check if cluster resource reached Ready state
  • Verify composition pipeline completed successfully

Firewall rule errors

  • Check if FirewallRule XRD is installed
  • Verify network policies allow rule creation

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

License

MIT License - see LICENSE file for details

Support

For issues and questions:


service-firewall-template

A Backstage Software Template for managing firewall rules using Crossplane.

Overview

This template creates the necessary Crossplane resources to manage firewall rules in your infrastructure. It includes:

  • XRD (Composite Resource Definition): Defines the FirewallRule API
  • Composition: Implements the firewall rule management logic
  • Example Claim: Shows how to create a firewall rule

Features

  • 🔒 Security Management: Define network access control rules
  • 🌐 Protocol Support: TCP, UDP, ICMP, or all protocols
  • Action Control: Accept, drop, or reject traffic
  • 📊 CIDR Support: Full IPv4 CIDR notation support

Prerequisites

Crossplane Installation

Ensure Crossplane is installed in your cluster:

kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

Required Functions

Install the necessary Crossplane composition functions:

kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.10.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1
EOF

Usage

Through Backstage

  1. Navigate to the Software Catalog
  2. Click "Create Component"
  3. Select "Firewall Rule"
  4. Fill in the required parameters:
    • Rule Name: Unique identifier for this firewall rule
    • Namespace: Kubernetes namespace (default: default)
    • Source IP/CIDR: Source address or network
    • Destination IP/CIDR: Destination address or network
    • Protocol: ALL, TCP, UDP, or ICMP
    • Action: ACCEPT, DROP, or REJECT
    • Owner: Team or user who owns this resource

Manual Deployment

  1. Apply the XRD:
kubectl apply -f content/definition.yaml
  1. Apply the Composition:
kubectl apply -f content/composition.yaml
  1. Create a claim:
kubectl apply -f content/example.yaml

Parameters

ParameterDescriptionTypeDefaultRequired
nameRule namestring-Yes
namespaceKubernetes namespacestringdefaultNo
sourceSource IP/CIDRstring-Yes
destinationDestination IP/CIDRstring-Yes
protocolNetwork protocolstringALLNo
actionRule actionstringACCEPTNo
ownerResource ownerstringgroup:platformNo

Rule Examples

Allow All Traffic

spec:
source: 0.0.0.0/0
destination: 0.0.0.0/0
protocol: ALL
action: ACCEPT

Block Specific Network

spec:
source: 192.168.1.0/24
destination: 10.0.0.0/8
protocol: ALL
action: DROP

Allow HTTPS Traffic

spec:
source: 0.0.0.0/0
destination: 10.0.0.100
protocol: TCP
action: ACCEPT
# Note: Port specification would be added in production

Allow Ping (ICMP)

spec:
source: 10.0.0.0/24
destination: 10.0.1.0/24
protocol: ICMP
action: ACCEPT

Actions Explained

ACCEPT

Allows the traffic to pass through. This is the default action for permissive rules.

DROP

Silently discards the packet without sending any response to the source. Used for stealth blocking.

REJECT

Blocks the traffic and sends an ICMP response to the source indicating the traffic was rejected.

Architecture

The template creates a composite resource that:

  1. ConfigMap: Stores firewall rule configuration
  2. Provider Integration: Would connect to actual firewall/security group providers
  3. Rule Application: Applies rules to network infrastructure

Production Considerations

For production use, you'll need to:

  1. Install a Cloud Provider: Such as provider-aws, provider-azure, or provider-gcp
  2. Configure Provider Credentials: Set up authentication for your cloud provider
  3. Update Composition: Replace the mock implementation with actual security group resources

Example with AWS Security Groups:

- step: create-security-group-rule
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: ec2.aws.upbound.io/v1beta1
kind: SecurityGroupRule
spec:
forProvider:
region: us-east-1
type: ingress
fromPort: 443
toPort: 443
protocol: tcp
cidrBlocks:
- {{ .observed.composite.resource.spec.source }}
securityGroupIdRef:
name: my-security-group

Example with Azure Network Security Groups:

- step: create-nsg-rule
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: network.azure.upbound.io/v1beta1
kind: SecurityRule
spec:
forProvider:
access: {{ .observed.composite.resource.spec.action }}
direction: Inbound
priority: 100
protocol: {{ .observed.composite.resource.spec.protocol }}
sourceAddressPrefix: {{ .observed.composite.resource.spec.source }}
destinationAddressPrefix: {{ .observed.composite.resource.spec.destination }}

CIDR Notation

The template supports standard CIDR notation:

  • Individual IP: 192.168.1.1
  • Subnet: 192.168.1.0/24 (256 addresses)
  • Large Network: 10.0.0.0/8 (16,777,216 addresses)
  • All IPs: 0.0.0.0/0

Troubleshooting

Common Issues

Rule not being applied

  • Check if the composition is properly configured
  • Verify ConfigMap was created successfully
  • Check composition logs: kubectl describe composition firewallrule

Invalid CIDR format

  • Ensure IP addresses are valid (0-255 for each octet)
  • CIDR suffix must be 0-32
  • Use online CIDR calculators to verify format

Rule conflicts

  • Check for overlapping rules with different actions
  • Verify rule priority/order if supported by provider

Security Best Practices

  1. Principle of Least Privilege: Only allow necessary traffic
  2. Default Deny: Start with blocking all, then allow specific traffic
  3. Segmentation: Use different rules for different network segments
  4. Logging: Enable logging for DROP/REJECT actions
  5. Regular Review: Periodically audit firewall rules

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

License

MIT License - see LICENSE file for details

Support

For issues and questions:


service-dnsrecord-template

A Backstage Software Template for managing DNS records using Crossplane.

Overview

This template creates the necessary Crossplane resources to manage DNS records in your infrastructure. It includes:

  • XRD (Composite Resource Definition): Defines the DNSRecord API
  • Composition: Implements the DNS record management logic
  • Example Claim: Shows how to create a DNS record

Features

  • 🌐 Multiple Record Types: Support for A, AAAA, CNAME, and TXT records
  • 🔧 Simple Configuration: Easy-to-use parameters for DNS management
  • 📊 FQDN Tracking: Fully qualified domain name available in status
  • Quick Provisioning: Instant DNS record creation

Prerequisites

Crossplane Installation

Ensure Crossplane is installed in your cluster:

kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

Required Functions

Install the necessary Crossplane composition functions:

kubectl apply -f - <<EOF
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.10.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-environment-configs
spec:
package: xpkg.upbound.io/crossplane-contrib/function-environment-configs:v0.1.0
EOF

Environment Configuration

Create an environment configuration for DNS settings:

apiVersion: apiextensions.crossplane.io/v1
kind: EnvironmentConfig
metadata:
name: dnsrecord
data:
zone: example.com # Your DNS zone

Usage

Through Backstage

  1. Navigate to the Software Catalog
  2. Click "Create Component"
  3. Select "DNS Record"
  4. Fill in the required parameters:
    • Resource Name: Unique identifier for this DNS record
    • Namespace: Kubernetes namespace (default: default)
    • Record Type: A, AAAA, CNAME, or TXT
    • DNS Name: The hostname (without domain)
    • Record Value: IP address, hostname, or text value
    • Owner: Team or user who owns this resource

Manual Deployment

  1. Apply the XRD:
kubectl apply -f content/definition.yaml
  1. Apply the Composition:
kubectl apply -f content/composition.yaml
  1. Create a claim:
kubectl apply -f content/example.yaml

Parameters

ParameterDescriptionTypeDefaultRequired
nameResource namestring-Yes
namespaceKubernetes namespacestringdefaultNo
recordTypeDNS record typestringANo
dnsNameDNS hostnamestring-Yes
recordValueRecord valuestring-Yes
ownerResource ownerstringgroup:platformNo

Record Types

A Record (IPv4)

Maps a hostname to an IPv4 address.

spec:
type: A
name: app
value: "192.168.1.100"

AAAA Record (IPv6)

Maps a hostname to an IPv6 address.

spec:
type: AAAA
name: app
value: "2001:db8::1"

CNAME Record

Creates an alias to another hostname.

spec:
type: CNAME
name: www
value: "app.example.com"

TXT Record

Stores text data, often used for verification or SPF records.

spec:
type: TXT
name: _verification
value: "v=spf1 include:_spf.example.com ~all"

Architecture

The template creates a composite resource that:

  1. ConfigMap: Stores DNS record configuration
  2. DNS Provider Integration: Would connect to actual DNS provider (Route53, CloudDNS, etc.)
  3. Status Updates: Returns FQDN in resource status

Getting the FQDN

After provisioning, retrieve the fully qualified domain name:

kubectl get dnsrecord <record-name> -n <namespace> -o jsonpath='{.status.fqdn}'

Development

Testing Locally

  1. Clone this repository
  2. Install the template in Backstage:
catalog:
locations:
- type: url
target: https://github.com/open-service-portal/service-dnsrecord-template/blob/main/template.yaml

Customization

To customize DNS record management:

  1. Edit content/definition.yaml to add parameters
  2. Modify content/composition.yaml to integrate with your DNS provider
  3. Update template.yaml to expose new parameters in Backstage

Production Considerations

For production use, you'll need to:

  1. Install a DNS Provider: Such as provider-aws, provider-azure, or provider-gcp
  2. Configure Provider Credentials: Set up authentication for your DNS provider
  3. Update Composition: Replace the mock implementation with actual DNS provider resources

Example with AWS Route53:

- step: create-route53-record
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: route53.aws.upbound.io/v1beta1
kind: Record
spec:
forProvider:
region: us-east-1
type: {{ .observed.composite.resource.spec.type }}
name: {{ .observed.composite.resource.spec.name }}
records:
- {{ .observed.composite.resource.spec.value }}
ttl: 300
zoneIdRef:
name: my-zone

Troubleshooting

Common Issues

DNS record not created

  • Check if environment configuration is properly set
  • Verify DNS zone is configured correctly
  • Check composition logs: kubectl describe composition dnsrecord

FQDN not appearing in status

  • Ensure the environment config contains the zone field
  • Check if the composition pipeline completed successfully

Permission errors

  • Verify Crossplane has necessary permissions for ConfigMap creation
  • Check RBAC settings for the namespace

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

License

MIT License - see LICENSE file for details

Support

For issues and questions:


service-mongodb-golden-path-template

The recommended way to provision production-ready MongoDB infrastructure with a single click

What is a Golden Path?

A Golden Path is an opinionated, well-architected solution that represents the best practice for a common use case. Instead of making developers choose between dozens of options and potentially making mistakes, the Golden Path provides a pre-validated, production-ready solution.

🎯 What This Template Does

With one simple request, this template automatically provisions:

Complete Infrastructure Stack

graph TB
subgraph "What You Get"
MongoDB["🗄️ MongoDB Database<br/>Document Store"]
Cluster["☸️ Kubernetes Cluster<br/>3 nodes, HA"]
DNS["🌐 DNS Record<br/>Stable endpoint"]
Network["🔒 Network Security<br/>Firewall rules"]
end

subgraph "How It's Connected"
MongoDB --> Cluster
DNS --> MongoDB
Network --> Cluster
end

Developer["👩‍💻 Developer"] -->|"One Template"| MongoDB

style MongoDB fill:#f9f,stroke:#333,stroke-width:4px
style Developer fill:#bbf,stroke:#333,stroke-width:2px

🆚 Golden Path vs. Individual Components

❌ The Hard Way (Individual Components)

# Step 1: Create a cluster
backstage template:create service-cluster-template

# Step 2: Wait for cluster...
# Step 3: Create DNS
backstage template:create service-dnsrecord-template

# Step 4: Configure DNS to point to cluster...
# Step 5: Create firewall rules
backstage template:create service-firewall-template

# Step 6: Configure network policies...
# Step 7: Finally create MongoDB
backstage template:create service-mongodb-template

# Step 8: Wire everything together...
# Step 9: Hope it all works...

Problems:

  • 🔴 7+ manual steps
  • 🔴 Complex dependencies to manage
  • 🔴 Easy to misconfigure
  • 🔴 No guarantee components work together
  • 🔴 Time consuming

✅ The Golden Path (This Template)

# Step 1: Create everything with proper configuration
backstage template:create service-mongodb-golden-path-template

# Done! ✨

Benefits:

  • 🟢 1 step
  • 🟢 Pre-validated configuration
  • 🟢 Guaranteed compatibility
  • 🟢 Production-ready defaults
  • 🟢 5 minutes to production

📊 Architecture

System Model in Backstage

System: mongodb-stack
├── Resource: mongodb (depends on → cluster, dns)
├── Resource: cluster
├── Resource: dns (depends on → cluster)
└── Resource: firewall (protects → cluster)

Crossplane Composition

The template uses Crossplane to manage the infrastructure declaratively:

  1. MongoDB XRD defines the API
  2. Composition orchestrates the resource creation:
    • Creates Kubernetes cluster
    • Provisions MongoDB on the cluster
    • Sets up DNS records
    • Configures security rules
  3. Single Claim triggers the entire stack

🚀 Quick Start

Prerequisites

  • Backstage instance with this template installed
  • Crossplane installed in your cluster
  • GitHub account for repository creation

Usage

  1. In Backstage UI:

    • Navigate to "Create Component"
    • Select "🚀 MongoDB Golden Path"
    • Fill in just 3 fields:
      • Stack name
      • Storage size
      • Team owner
  2. Apply Infrastructure:

    kubectl apply -f https://github.com/open-service-portal/[your-repo]/example.yaml
  3. Get Connection String:

    kubectl get mongodb [stack-name] -o jsonpath='{.status.connString}'

📈 Stacked Services Concept

This template demonstrates the Stacked Services pattern:

Level 1: Base Infrastructure

  • Kubernetes Cluster
  • Network Security

Level 2: Platform Services

  • DNS Management
  • Service Discovery

Level 3: Application Services

  • MongoDB Database
  • Connection Management

Each level depends on the one below, creating a stable, scalable stack.

🎯 When to Use This Template

Use the Golden Path when:

  • ✅ You need a production-ready MongoDB quickly
  • ✅ You want best-practice configuration
  • ✅ You prefer convention over configuration
  • ✅ You're building a standard application

Use Individual Templates when:

  • ⚠️ You have specific infrastructure requirements
  • ⚠️ You need custom networking setup
  • ⚠️ You're integrating with existing infrastructure
  • ⚠️ You need fine-grained control

📖 Backstage Concepts Used

1. Software Templates

  • Defined in template.yaml
  • Uses scaffolder actions to create resources
  • Implements the golden path pattern

2. System Model

  • Groups related components
  • Shows dependencies with dependsOn
  • Creates a system view in the catalog

3. Relations

  • partOf: Components are part of the system
  • dependsOn: Shows resource dependencies
  • ownedBy: Indicates team ownership

4. Catalog Registration

  • Automatically registers all components
  • Creates a unified view in Backstage
  • Enables discovery and documentation

🔧 Customization

While this is an opinionated template, you can customize:

In template.yaml:

  • Adjust parameter defaults
  • Add more configuration options
  • Modify the UI presentation

In composition.yaml:

  • Change cluster size/configuration
  • Adjust MongoDB settings
  • Modify network policies

📚 References & Best Practices

Based on industry best practices and official documentation:

  1. Backstage System Model - How to model infrastructure
  2. Crossplane Compositions - Infrastructure as Code
  3. Golden Path Pattern - Platform engineering concepts
  4. Spotify's Golden Paths - Original concept from Spotify

🤝 Contributing

We welcome contributions! Areas for improvement:

  • Add more cloud provider options
  • Support for different MongoDB configurations
  • Integration with monitoring/observability
  • Cost optimization options
  • Backup and disaster recovery

📝 License

MIT License - See LICENSE file

🆘 Support


Built with ❤️ by the Platform Engineering Team
Making infrastructure simple, one golden path at a time