Skip to content

Commit aeb68d9

Browse files
Merge branch 'feature/orch-001/BD-848-kubernetes-deployment'
2 parents d357941 + f4c8800 commit aeb68d9

19 files changed

+660
-0
lines changed

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,29 @@ jobs:
9393
- name: Run Code Analysis
9494
run: dotnet build --no-restore --configuration Release /p:TreatWarningsAsErrors=false
9595

96+
validate-manifests:
97+
name: Validate K8s Manifests
98+
runs-on: ubuntu-latest
99+
100+
steps:
101+
- name: Checkout code
102+
uses: actions/checkout@v4
103+
104+
- name: Validate YAML syntax
105+
run: |
106+
pip install pyyaml
107+
for f in k8s/base/*.yaml; do
108+
echo "Validating $f..."
109+
python3 -c "import yaml; yaml.safe_load(open('$f'))"
110+
done
111+
112+
- name: Validate Kustomize overlays
113+
run: |
114+
echo "Validating staging overlay..."
115+
kubectl kustomize k8s/overlays/staging > /dev/null
116+
echo "Validating production overlay..."
117+
kubectl kustomize k8s/overlays/production > /dev/null
118+
96119
security:
97120
name: Security Scan
98121
runs-on: ubuntu-latest

.github/workflows/deploy.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
workflow_dispatch:
7+
inputs:
8+
environment:
9+
description: 'Target environment'
10+
required: true
11+
type: choice
12+
options:
13+
- staging
14+
- production
15+
image_tag:
16+
description: 'Docker image tag to deploy'
17+
required: true
18+
type: string
19+
20+
env:
21+
REGISTRY: ghcr.io
22+
IMAGE_NAME: ${{ github.repository }}
23+
24+
jobs:
25+
prepare:
26+
name: Prepare Deployment
27+
runs-on: ubuntu-latest
28+
outputs:
29+
image_tag: ${{ steps.resolve-tag.outputs.tag }}
30+
version: ${{ steps.resolve-tag.outputs.version }}
31+
steps:
32+
- name: Resolve image tag
33+
id: resolve-tag
34+
run: |
35+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
36+
echo "tag=${{ inputs.image_tag }}" >> $GITHUB_OUTPUT
37+
echo "version=${{ inputs.image_tag }}" >> $GITHUB_OUTPUT
38+
else
39+
TAG="${GITHUB_REF#refs/tags/}"
40+
echo "tag=${TAG}" >> $GITHUB_OUTPUT
41+
echo "version=${TAG}" >> $GITHUB_OUTPUT
42+
fi
43+
44+
- name: Verify image exists
45+
run: |
46+
echo "Verifying image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.resolve-tag.outputs.tag }}"
47+
48+
deploy-staging:
49+
name: Deploy to Staging
50+
needs: prepare
51+
runs-on: ubuntu-latest
52+
environment:
53+
name: staging
54+
url: https://ordermonitor-api.staging.printerpix.com/health
55+
steps:
56+
- name: Checkout code
57+
uses: actions/checkout@v4
58+
59+
- name: Set image tag in manifests
60+
run: |
61+
cd k8s/overlays/staging
62+
kustomize edit set image ghcr.io/printerpix/printerpix-backoffice-ordermonitor-api=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}
63+
64+
- name: Deploy to staging
65+
run: |
66+
echo "Deploying ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }} to staging"
67+
echo "kubectl apply -k k8s/overlays/staging"
68+
# Uncomment when cluster credentials are configured:
69+
# kubectl apply -k k8s/overlays/staging
70+
# kubectl -n ordermonitor-staging rollout status deployment/staging-ordermonitor-api --timeout=300s
71+
72+
- name: Run smoke tests
73+
run: |
74+
echo "Running smoke tests against staging..."
75+
# Uncomment when staging is accessible:
76+
# chmod +x scripts/smoke-test.sh
77+
# ./scripts/smoke-test.sh https://ordermonitor-api.staging.printerpix.com
78+
79+
- name: Staging deployment summary
80+
run: |
81+
echo "## Staging Deployment" >> $GITHUB_STEP_SUMMARY
82+
echo "- **Image:** ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}" >> $GITHUB_STEP_SUMMARY
83+
echo "- **Version:** ${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
84+
echo "- **Environment:** staging" >> $GITHUB_STEP_SUMMARY
85+
86+
deploy-production:
87+
name: Deploy to Production
88+
needs: [prepare, deploy-staging]
89+
runs-on: ubuntu-latest
90+
environment:
91+
name: production
92+
url: https://ordermonitor-api.printerpix.com/health
93+
steps:
94+
- name: Checkout code
95+
uses: actions/checkout@v4
96+
97+
- name: Set image tag in manifests
98+
run: |
99+
cd k8s/overlays/production
100+
kustomize edit set image ghcr.io/printerpix/printerpix-backoffice-ordermonitor-api=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}
101+
102+
- name: Deploy to production
103+
run: |
104+
echo "Deploying ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }} to production"
105+
echo "kubectl apply -k k8s/overlays/production"
106+
# Uncomment when cluster credentials are configured:
107+
# kubectl apply -k k8s/overlays/production
108+
# kubectl -n ordermonitor rollout status deployment/ordermonitor-api --timeout=300s
109+
110+
- name: Run smoke tests
111+
run: |
112+
echo "Running smoke tests against production..."
113+
# Uncomment when production is accessible:
114+
# chmod +x scripts/smoke-test.sh
115+
# ./scripts/smoke-test.sh https://ordermonitor-api.printerpix.com
116+
117+
- name: Production deployment summary
118+
run: |
119+
echo "## Production Deployment" >> $GITHUB_STEP_SUMMARY
120+
echo "- **Image:** ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.image_tag }}" >> $GITHUB_STEP_SUMMARY
121+
echo "- **Version:** ${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
122+
echo "- **Environment:** production" >> $GITHUB_STEP_SUMMARY

k8s/base/configmap.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: ordermonitor-api-config
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: config
9+
app.kubernetes.io/part-of: printerpix
10+
data:
11+
ASPNETCORE_ENVIRONMENT: "Production"
12+
ASPNETCORE_URLS: "http://+:8080"
13+
Logging__LogLevel__Default: "Information"
14+
Logging__LogLevel__Microsoft.AspNetCore: "Warning"
15+
Logging__LogLevel__Microsoft.EntityFrameworkCore: "Warning"

k8s/base/deployment.yaml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: ordermonitor-api
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: api
9+
app.kubernetes.io/part-of: printerpix
10+
spec:
11+
replicas: 2
12+
selector:
13+
matchLabels:
14+
app.kubernetes.io/name: ordermonitor-api
15+
template:
16+
metadata:
17+
labels:
18+
app.kubernetes.io/name: ordermonitor-api
19+
app.kubernetes.io/component: api
20+
app.kubernetes.io/part-of: printerpix
21+
spec:
22+
containers:
23+
- name: ordermonitor-api
24+
image: ghcr.io/printerpix/printerpix-backoffice-ordermonitor-api:latest
25+
ports:
26+
- name: http
27+
containerPort: 8080
28+
protocol: TCP
29+
envFrom:
30+
- configMapRef:
31+
name: ordermonitor-api-config
32+
- secretRef:
33+
name: ordermonitor-api-secrets
34+
resources:
35+
requests:
36+
cpu: 100m
37+
memory: 128Mi
38+
limits:
39+
cpu: 500m
40+
memory: 512Mi
41+
livenessProbe:
42+
httpGet:
43+
path: /health
44+
port: http
45+
initialDelaySeconds: 15
46+
periodSeconds: 30
47+
timeoutSeconds: 10
48+
failureThreshold: 3
49+
readinessProbe:
50+
httpGet:
51+
path: /health
52+
port: http
53+
initialDelaySeconds: 5
54+
periodSeconds: 10
55+
timeoutSeconds: 5
56+
failureThreshold: 3
57+
startupProbe:
58+
httpGet:
59+
path: /health
60+
port: http
61+
initialDelaySeconds: 5
62+
periodSeconds: 5
63+
timeoutSeconds: 5
64+
failureThreshold: 12
65+
restartPolicy: Always
66+
terminationGracePeriodSeconds: 30

k8s/base/hpa.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
apiVersion: autoscaling/v2
2+
kind: HorizontalPodAutoscaler
3+
metadata:
4+
name: ordermonitor-api
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: autoscaling
9+
app.kubernetes.io/part-of: printerpix
10+
spec:
11+
scaleTargetRef:
12+
apiVersion: apps/v1
13+
kind: Deployment
14+
name: ordermonitor-api
15+
minReplicas: 2
16+
maxReplicas: 10
17+
metrics:
18+
- type: Resource
19+
resource:
20+
name: cpu
21+
target:
22+
type: Utilization
23+
averageUtilization: 70
24+
- type: Resource
25+
resource:
26+
name: memory
27+
target:
28+
type: Utilization
29+
averageUtilization: 80
30+
behavior:
31+
scaleUp:
32+
stabilizationWindowSeconds: 60
33+
policies:
34+
- type: Pods
35+
value: 2
36+
periodSeconds: 60
37+
scaleDown:
38+
stabilizationWindowSeconds: 300
39+
policies:
40+
- type: Pods
41+
value: 1
42+
periodSeconds: 120

k8s/base/ingress.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: Ingress
3+
metadata:
4+
name: ordermonitor-api
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: ingress
9+
app.kubernetes.io/part-of: printerpix
10+
annotations:
11+
nginx.ingress.kubernetes.io/rewrite-target: /$2
12+
nginx.ingress.kubernetes.io/ssl-redirect: "true"
13+
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
14+
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
15+
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
16+
spec:
17+
ingressClassName: nginx
18+
tls:
19+
- hosts:
20+
- ordermonitor-api.printerpix.com
21+
secretName: ordermonitor-api-tls
22+
rules:
23+
- host: ordermonitor-api.printerpix.com
24+
http:
25+
paths:
26+
- path: /api(/|$)(.*)
27+
pathType: ImplementationSpecific
28+
backend:
29+
service:
30+
name: ordermonitor-api
31+
port:
32+
number: 8080
33+
- path: /health
34+
pathType: Exact
35+
backend:
36+
service:
37+
name: ordermonitor-api
38+
port:
39+
number: 8080
40+
- path: /swagger(.*)
41+
pathType: ImplementationSpecific
42+
backend:
43+
service:
44+
name: ordermonitor-api
45+
port:
46+
number: 8080

k8s/base/kustomization.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: kustomize.config.k8s.io/v1beta1
2+
kind: Kustomization
3+
4+
namespace: ordermonitor
5+
6+
commonLabels:
7+
app.kubernetes.io/managed-by: kustomize
8+
9+
resources:
10+
- namespace.yaml
11+
- deployment.yaml
12+
- service.yaml
13+
- configmap.yaml
14+
- secret.yaml
15+
- hpa.yaml
16+
- ingress.yaml

k8s/base/namespace.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: ordermonitor
5+
labels:
6+
app.kubernetes.io/name: ordermonitor-api
7+
app.kubernetes.io/part-of: printerpix

k8s/base/secret.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: ordermonitor-api-secrets
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: config
9+
app.kubernetes.io/part-of: printerpix
10+
type: Opaque
11+
data:
12+
# Base64-encoded placeholders - replace with actual values in each environment
13+
# echo -n "Server=host;Database=db;User Id=user;Password=pass;TrustServerCertificate=True" | base64
14+
ConnectionStrings__DefaultConnection: "REPLACE_WITH_BASE64_ENCODED_CONNECTION_STRING"

k8s/base/service.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: ordermonitor-api
5+
namespace: ordermonitor
6+
labels:
7+
app.kubernetes.io/name: ordermonitor-api
8+
app.kubernetes.io/component: api
9+
app.kubernetes.io/part-of: printerpix
10+
spec:
11+
type: ClusterIP
12+
selector:
13+
app.kubernetes.io/name: ordermonitor-api
14+
ports:
15+
- name: http
16+
port: 8080
17+
targetPort: http
18+
protocol: TCP

0 commit comments

Comments
 (0)