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 scopecomposition.yaml
- Composition using Pipeline mode with Go templatingrbac.yaml
- RBAC permissions for Crossplane to create ConfigMapsexamples/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
- XR Creation: Developer creates DNSRecord directly in their namespace
- Environment Loading: Composition loads DNS zone from EnvironmentConfig
- Resource Creation: Go template creates a ConfigMap in the same namespace
- Status Update: FQDN is computed and returned in status
- 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
Links and Resources
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:
- 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]
- Navigate to
/create
in your Backstage instance - 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:
- 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
- Navigate to the Software Catalog
- Click "Create Component"
- Select "MongoDB Database"
- 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
- Apply the XRD:
kubectl apply -f content/definition.yaml
- Apply the Composition:
kubectl apply -f content/composition.yaml
- Create a claim:
kubectl apply -f content/example.yaml
Parameters
Parameter | Description | Type | Default | Required |
---|---|---|---|---|
name | Instance name | string | - | Yes |
namespace | Kubernetes namespace | string | default | No |
storageSize | Storage size in GB | integer | 10 | No |
owner | Resource owner | string | group:platform | No |
Architecture
The template creates a composite resource that provisions:
- Cluster Resource: A simulated compute cluster for MongoDB
- DNS Record: Automatic DNS entry for database access
- ConfigMap: Stores configuration values
- 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
- Clone this repository
- 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:
- Edit
content/definition.yaml
to add parameters - Modify
content/composition.yaml
to change provisioning logic - 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:
- Fork the repository
- Create a feature branch
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
For issues and questions:
- GitHub Issues: open-service-portal/service-mongodb-template
- Discussions: open-service-portal/discussions
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:
- 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
- Navigate to the Software Catalog
- Click "Create Component"
- Select "Kubernetes Cluster"
- 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
- Apply the XRD:
kubectl apply -f content/definition.yaml
- Apply the Composition:
kubectl apply -f content/composition.yaml
- Create a claim:
kubectl apply -f content/example.yaml
Parameters
Parameter | Description | Type | Default | Required |
---|---|---|---|---|
name | Cluster name | string | - | Yes |
namespace | Kubernetes namespace | string | default | No |
nodeSize | Size of nodes | string | medium | No |
nodeCount | Number of nodes | integer | 3 | No |
storageSize | Storage per node (GB) | integer | 10 | No |
version | Kubernetes version | string | 1.31.1 | Yes |
cloudProvider | Cloud provider | string | azure | No |
owner | Resource owner | string | group:platform | No |
Node Sizes
Size | vCPU | Memory | Storage |
---|---|---|---|
Small | 2 | 4 GB | Configurable |
Medium | 4 | 8 GB | Configurable |
Large | 8 | 16 GB | Configurable |
Architecture
The template creates a composite resource that provisions:
- ConfigMap: Stores cluster configuration
- Cluster Resource: The actual Kubernetes cluster (simulated)
- Firewall Rule: Network security configuration
- 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
- Clone this repository
- 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:
- Edit
content/definition.yaml
to add parameters - Modify
content/composition.yaml
to change provisioning logic - 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:
- Fork the repository
- Create a feature branch
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
For issues and questions:
- GitHub Issues: open-service-portal/service-cluster-template
- Discussions: open-service-portal/discussions
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
- Navigate to the Software Catalog
- Click "Create Component"
- Select "Firewall Rule"
- 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
- Apply the XRD:
kubectl apply -f content/definition.yaml
- Apply the Composition:
kubectl apply -f content/composition.yaml
- Create a claim:
kubectl apply -f content/example.yaml
Parameters
Parameter | Description | Type | Default | Required |
---|---|---|---|---|
name | Rule name | string | - | Yes |
namespace | Kubernetes namespace | string | default | No |
source | Source IP/CIDR | string | - | Yes |
destination | Destination IP/CIDR | string | - | Yes |
protocol | Network protocol | string | ALL | No |
action | Rule action | string | ACCEPT | No |
owner | Resource owner | string | group:platform | No |
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:
- ConfigMap: Stores firewall rule configuration
- Provider Integration: Would connect to actual firewall/security group providers
- Rule Application: Applies rules to network infrastructure
Production Considerations
For production use, you'll need to:
- Install a Cloud Provider: Such as provider-aws, provider-azure, or provider-gcp
- Configure Provider Credentials: Set up authentication for your cloud provider
- 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
- Principle of Least Privilege: Only allow necessary traffic
- Default Deny: Start with blocking all, then allow specific traffic
- Segmentation: Use different rules for different network segments
- Logging: Enable logging for DROP/REJECT actions
- Regular Review: Periodically audit firewall rules
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
For issues and questions:
- GitHub Issues: open-service-portal/service-firewall-template
- Discussions: open-service-portal/discussions
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
- Navigate to the Software Catalog
- Click "Create Component"
- Select "DNS Record"
- 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
- Apply the XRD:
kubectl apply -f content/definition.yaml
- Apply the Composition:
kubectl apply -f content/composition.yaml
- Create a claim:
kubectl apply -f content/example.yaml
Parameters
Parameter | Description | Type | Default | Required |
---|---|---|---|---|
name | Resource name | string | - | Yes |
namespace | Kubernetes namespace | string | default | No |
recordType | DNS record type | string | A | No |
dnsName | DNS hostname | string | - | Yes |
recordValue | Record value | string | - | Yes |
owner | Resource owner | string | group:platform | No |
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:
- ConfigMap: Stores DNS record configuration
- DNS Provider Integration: Would connect to actual DNS provider (Route53, CloudDNS, etc.)
- 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
- Clone this repository
- 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:
- Edit
content/definition.yaml
to add parameters - Modify
content/composition.yaml
to integrate with your DNS provider - Update
template.yaml
to expose new parameters in Backstage
Production Considerations
For production use, you'll need to:
- Install a DNS Provider: Such as provider-aws, provider-azure, or provider-gcp
- Configure Provider Credentials: Set up authentication for your DNS provider
- 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:
- Fork the repository
- Create a feature branch
- Submit a pull request
License
MIT License - see LICENSE file for details
Support
For issues and questions:
- GitHub Issues: open-service-portal/service-dnsrecord-template
- Discussions: open-service-portal/discussions
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:
- MongoDB XRD defines the API
- Composition orchestrates the resource creation:
- Creates Kubernetes cluster
- Provisions MongoDB on the cluster
- Sets up DNS records
- Configures security rules
- 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
-
In Backstage UI:
- Navigate to "Create Component"
- Select "🚀 MongoDB Golden Path"
- Fill in just 3 fields:
- Stack name
- Storage size
- Team owner
-
Apply Infrastructure:
kubectl apply -f https://github.com/open-service-portal/[your-repo]/example.yaml
-
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 systemdependsOn
: Shows resource dependenciesownedBy
: 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:
- Backstage System Model - How to model infrastructure
- Crossplane Compositions - Infrastructure as Code
- Golden Path Pattern - Platform engineering concepts
- 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
- GitHub Issues: Report issues here
- Discussions: Ask questions
- Documentation: Platform Docs
Making infrastructure simple, one golden path at a time