Skip to content

Commit 4d87a16

Browse files
authored
Migrate platform-ref-azure from Crossplane v1 to v2 with namespaced resources (#172)
* Migrates platform-ref-azure from Crossplane v1 to v2 with namespaced resources. - XRD API version: `apiextensions.crossplane.io/v1` → `v2` - Resource kinds: Removed X-prefix (`XCluster` → `Cluster`, `XSQLInstance` → `SQLInstance`, etc.) - Scope: All XRs are now namespaced (`scope: Namespaced`) - File naming: Renamed examples from `*-claim.yaml` to `*-xr.yaml` - Management: `deletionPolicy` → `managementPolicies` array - **Dependencies**: Updated all 6 dependent configurations to v2.0.0 (configuration-app to v2.1.0) - **XRDs**: Updated to v2 API with namespace scope, removed `claimNames` and `connectionSecretKeys` - **Functions**: Updated to use namespaced provider APIs (`azurem`, `helmm`) and v2 patterns - **Tests**: Updated composition and E2E tests to v2 conventions with proper namespace handling - **Usage Resources**: Migrated to `protection.crossplane.io/v1beta1` API with namespace support - **Provider Config**: Added provider-family-azure to E2E test initResources for RBAC workaround - Fixed configuration-app label propagation to support Usage resource dependencies - Updated helm Release API to namespaced version in Usage resources - ✅ All composition tests passing - ✅ E2E test passing Signed-off-by: Yury Tsarev <yury@upbound.io> * Extend README with the Application access Signed-off-by: Yury Tsarev <yury@upbound.io> * Align composition tests to expect namespaced Release Signed-off-by: Yury Tsarev <yury@upbound.io> * Add ghost admin screenshot to the platform readme Signed-off-by: Yury Tsarev <yury@upbound.io> * Control screenshot size in the README Signed-off-by: Yury Tsarev <yury@upbound.io> * Remove unnecessary sequential instructions Signed-off-by: Yury Tsarev <yury@upbound.io> --------- Signed-off-by: Yury Tsarev <yury@upbound.io>
1 parent 91a900d commit 4d87a16

File tree

21 files changed

+286
-215
lines changed

21 files changed

+286
-215
lines changed

README.md

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This platform uses **Upbound DevEx** with:
2424
## Overview
2525

2626
This reference platform outlines a specialized API for generating an AKS cluster
27-
([XCluster](apis/xclusters/definition.yaml)) that incorporates XRs from the specified configurations:
27+
([Cluster](apis/clusters/definition.yaml)) that incorporates XRs from the specified configurations:
2828

2929
* [upbound-configuration-app](https://github.com/upbound/configuration-app)
3030
* [upbound-configuration-azure-database](https://github.com/upbound/configuration-azure-database)
@@ -35,12 +35,12 @@ This reference platform outlines a specialized API for generating an AKS cluster
3535

3636
```mermaid
3737
graph LR;
38-
MyApp(My App)---MyCluster(XRC: my-cluster);
39-
MyCluster---XRD1(XRD: XCluster);
40-
MyApp---MyDB(XRC: my-db);
41-
MyDB---XRD2(XRD: XSQLInstance);
38+
MyApp(My App)---MyCluster(XR: my-cluster);
39+
MyCluster---XRD1(XRD: Cluster);
40+
MyApp---MyDB(XR: my-db);
41+
MyDB---XRD2(XRD: SQLInstance);
4242
subgraph Configuration:upbound/platform-ref-azure;
43-
XRD1---Composition(XAKS, XNetwork, XServices);
43+
XRD1---Composition(AKS, Network, Services);
4444
XRD2---Composition2(Composition);
4545
end
4646
subgraph Provider:upbound/provider-azure
@@ -65,7 +65,7 @@ style Postgres.MRs color:#000,fill:#81CABB,stroke:#000,stroke-width:2px
6565
```
6666

6767
Learn more about Composite Resources in the [Crossplane
68-
Docs](https://docs.crossplane.io/latest/concepts/compositions/).
68+
Docs](https://docs.crossplane.io/latest/composition/compositions/).
6969

7070
## Quickstart
7171

@@ -89,7 +89,7 @@ up project build
8989
up test run tests/*
9090

9191
# Render compositions with examples
92-
up composition render apis/xclusters/definition.yaml apis/xclusters/composition.yaml examples/cluster-claim.yaml
92+
up composition render apis/clusters/definition.yaml apis/clusters/composition.yaml examples/cluster-xr.yaml
9393
```
9494

9595
## Using the Platform
@@ -98,19 +98,75 @@ Once installed, you can create platform resources using the provided examples:
9898

9999
```console
100100
# Create a cluster with networking, observability, and GitOps
101-
kubectl apply -f examples/cluster-claim.yaml
101+
kubectl apply -f examples/cluster-xr.yaml
102102

103-
# Create a MySQL database (after cluster is ready)
104-
kubectl apply -f examples/mysql-claim.yaml
103+
# Create a MySQL database
104+
kubectl apply -f examples/mysql-xr.yaml
105105

106106
# Deploy a sample application
107-
kubectl apply -f examples/app-claim.yaml
107+
kubectl apply -f examples/app-xr.yaml
108108
```
109109

110110
Monitor deployment status:
111111

112112
```console
113-
kubectl get claim,composite,managed
113+
kubectl get composite,managed
114+
```
115+
116+
### Accessing Your Application
117+
118+
Once your Ghost application is deployed, you can access it using one of these methods:
119+
120+
#### Option 1: Via LoadBalancer (External IP)
121+
122+
Get the AKS cluster kubeconfig and access Ghost:
123+
124+
```bash
125+
# Get the kubeconfig from the AKS connection secret
126+
kubectl get secret <cluster-id>-akscluster -n default -o jsonpath='{.data.kubeconfig}' | base64 -d > /tmp/aks-kubeconfig
127+
128+
# Use the AKS kubeconfig to check Ghost service
129+
export KUBECONFIG=/tmp/aks-kubeconfig
130+
kubectl get svc -n ghost -l app.kubernetes.io/name=ghost
131+
kubectl get pods -n ghost
132+
133+
# Get the external IP
134+
EXTERNAL_IP=$(kubectl get svc -n ghost -l app.kubernetes.io/name=ghost -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
135+
echo "Ghost Frontend: http://$EXTERNAL_IP"
136+
echo "Ghost Admin: http://$EXTERNAL_IP/ghost"
137+
```
138+
139+
Then access:
140+
- **Frontend**: `http://<EXTERNAL-IP>` (Your blog)
141+
- **Admin**: `http://<EXTERNAL-IP>/ghost` (Admin interface)
142+
143+
You should see the Ghost admin login screen with "Upbound Rocks!" confirming your deployment:
144+
145+
<p align="center">
146+
<img src="docs/images/ghost-admin.png" width="500" alt="Ghost Admin Interface showing Upbound Rocks!">
147+
</p>
148+
149+
#### Option 2: Via kubectl port-forward (No external IP needed)
150+
151+
```bash
152+
# Get the kubeconfig
153+
kubectl get secret <cluster-id>-akscluster -n default -o jsonpath='{.data.kubeconfig}' | base64 -d > /tmp/aks-kubeconfig
154+
export KUBECONFIG=/tmp/aks-kubeconfig
155+
156+
# Forward Ghost service to local port 8080
157+
kubectl port-forward -n ghost svc/$(kubectl get svc -n ghost -l app.kubernetes.io/name=ghost -o jsonpath='{.items[0].metadata.name}') 8080:80
158+
159+
# Access in browser
160+
open http://localhost:8080 # Frontend
161+
open http://localhost:8080/ghost # Admin interface
162+
```
163+
164+
**Reset KUBECONFIG** when done:
165+
166+
```bash
167+
unset KUBECONFIG
168+
# or
169+
export KUBECONFIG=~/.kube/config
114170
```
115171

116172
## Development
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
apiVersion: apiextensions.crossplane.io/v1
22
kind: Composition
33
metadata:
4-
name: xclusters.azure.platformref.upbound.io
4+
name: clusters.azure.platformref.upbound.io
55
spec:
66
compositeTypeRef:
77
apiVersion: azure.platformref.upbound.io/v1alpha1
8-
kind: XCluster
8+
kind: Cluster
99
mode: Pipeline
1010
pipeline:
1111
- functionRef:
12-
name: upbound-platform-ref-azurexcluster
13-
step: xcluster
12+
name: upbound-platform-ref-azurecluster
13+
step: cluster
1414
- functionRef:
1515
name: crossplane-contrib-function-auto-ready
1616
step: crossplane-contrib-function-auto-ready
Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
apiVersion: apiextensions.crossplane.io/v1
1+
apiVersion: apiextensions.crossplane.io/v2
22
kind: CompositeResourceDefinition
33
metadata:
4-
name: xclusters.azure.platformref.upbound.io
4+
name: clusters.azure.platformref.upbound.io
55
spec:
6+
scope: Namespaced
67
# We require Foreground Deletion for cases where XRs are generated without a Claim, like in XServices.
78
# In such situations, XService is deleted right away,
8-
# taking the Usage and XAKS with it,
9+
# taking the Usage and AKS with it,
910
# which causes issues for Release.helm's deletion process.
1011
defaultCompositeDeletePolicy: Foreground
1112
group: azure.platformref.upbound.io
1213
names:
13-
kind: XCluster
14-
plural: xclusters
15-
claimNames:
1614
kind: Cluster
1715
plural: clusters
18-
connectionSecretKeys:
19-
- kubeconfig
2016
versions:
2117
- name: v1alpha1
2218
served: true
@@ -38,13 +34,19 @@ spec:
3834
region:
3935
type: string
4036
description: Region is the region you'd like your resource to be created in.
41-
deletionPolicy:
42-
description: Delete the external resources when the Claim/XR is deleted. Defaults to Delete
43-
enum:
44-
- Delete
45-
- Orphan
46-
type: string
47-
default: Delete
37+
managementPolicies:
38+
description: "ManagementPolicies for resources. Defaults to [\"*\"] which includes all operations (Create, Observe, Update, Delete, LateInitialize). To orphan resources on deletion, use [\"Create\", \"Observe\", \"Update\", \"LateInitialize\"]."
39+
type: array
40+
items:
41+
type: string
42+
enum:
43+
- "*"
44+
- Create
45+
- Observe
46+
- Update
47+
- Delete
48+
- LateInitialize
49+
default: ["*"]
4850
providerConfigName:
4951
description: Crossplane ProviderConfig to use for provisioning this resources
5052
type: string
@@ -53,10 +55,10 @@ spec:
5355
type: string
5456
description: Kubernetes version of the Cluster
5557
enum:
56-
- "1.31"
57-
- "1.30"
58-
- "1.29"
59-
default: "1.31"
58+
- "1.34"
59+
- "1.33"
60+
- "1.32"
61+
default: "1.34"
6062
nodes:
6163
type: object
6264
description: Cluster node configuration parameters.
@@ -161,7 +163,7 @@ spec:
161163
required:
162164
- git
163165
required:
164-
- deletionPolicy
166+
- managementPolicies
165167
- gitops
166168
- id
167169
- nodes

docs/images/ghost-admin.png

93.9 KB
Loading
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ metadata:
66
labels:
77
platform.upbound.io/deletion-ordering: enabled
88
spec:
9-
compositeDeletePolicy: Foreground
109
parameters:
10+
helm:
11+
chart:
12+
name: ghost
13+
repo: "oci://registry-1.docker.io/bitnamicharts"
14+
version: 25.0.4
15+
wait: false
1116
providerConfigName: platform-ref-azure-cluster
1217
passwordSecretRef:
1318
namespace: default
1419
name: platform-ref-azure-cluster-db-conn-mysql
15-
writeConnectionSecretToRef:
16-
name: platform-ref-azure-cluster-app-conn
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
apiVersion: azure.upbound.io/v1beta1
1+
apiVersion: azure.m.upbound.io/v1beta1
22
kind: ProviderConfig
33
metadata:
44
name: default
5+
namespace: default
56
spec:
67
credentials:
78
source: Secret
89
secretRef:
9-
namespace: upbound-system
1010
name: azure-creds
1111
key: credentials

examples/cluster-claim.yaml

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
apiVersion: azure.platformref.upbound.io/v1alpha1
2-
kind: XCluster
2+
kind: Cluster
33
metadata:
44
name: platform-ref-azure-cluster
5+
namespace: default
56
spec:
67
parameters:
78
id: platform-ref-azure-cluster
89
region: westus
9-
version: "1.31"
10+
version: "1.34"
1011
nodes:
1112
count: 1
1213
instanceType: Standard_B2s
@@ -18,6 +19,3 @@ spec:
1819
interval: 5m0s
1920
timeout: 60s
2021
path: /
21-
writeConnectionSecretToRef:
22-
name: platform-ref-azure-cluster-kubeconfig
23-
namespace: default
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ metadata:
44
name: platform-ref-azure-cluster-db-mysql
55
namespace: default
66
spec:
7-
compositionSelector:
8-
matchLabels:
9-
dbengine: mysql
7+
crossplane:
8+
compositionSelector:
9+
matchLabels:
10+
dbengine: mysql
1011
parameters:
1112
region: westus
1213
storageGB: 20 #Minimum value is 20 for MySQL
1314
version: "8.0"
1415
passwordSecretRef:
15-
namespace: default
1616
name: mysqlsecret
1717
key: password
1818
networkRef:

examples/network-xr.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
apiVersion: azure.platformref.upbound.io/v1alpha1
2-
kind: XNetwork
1+
apiVersion: azure.platform.upbound.io/v1alpha1
2+
kind: Network
33
metadata:
44
name: ref-azure-network
5+
namespace: default
56
spec:
67
parameters:
78
id: ref-azure-network-from-xr

0 commit comments

Comments
 (0)