From cba8dfb680188b508ec2c6bf910d2235f79e0f07 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 07:44:12 +0000 Subject: [PATCH 1/2] Add Inventory service IaC: Dockerfile, Helm chart, ArgoCD manifests - Add docker/inventory/Dockerfile: .NET 8 multi-stage build for Inventory.Api - Add helm/inventory/ chart with Deployment, Service, Ingress, NetworkPolicy, ServiceMonitor, HPA templates (mirrors ordermanager chart patterns) - NetworkPolicy allows traffic from ordermanager pods and ingress-nginx, plus Prometheus scraping from monitoring namespace - Health check probes point to /health endpoint - Add ArgoCD Application manifests for dev and staging environments - Add values-dev.yaml and values-staging.yaml environment overrides --- argocd/inventory-dev.yaml | 24 +++++++++ argocd/inventory-staging.yaml | 24 +++++++++ docker/inventory/Dockerfile | 15 ++++++ helm/inventory/Chart.yaml | 6 +++ helm/inventory/templates/_helpers.tpl | 27 ++++++++++ helm/inventory/templates/deployment.yaml | 44 +++++++++++++++++ helm/inventory/templates/hpa.yaml | 22 +++++++++ helm/inventory/templates/ingress.yaml | 29 +++++++++++ helm/inventory/templates/networkpolicy.yaml | 48 ++++++++++++++++++ helm/inventory/templates/service.yaml | 15 ++++++ helm/inventory/templates/servicemonitor.yaml | 16 ++++++ helm/inventory/values-dev.yaml | 28 +++++++++++ helm/inventory/values-staging.yaml | 25 ++++++++++ helm/inventory/values.yaml | 52 ++++++++++++++++++++ 14 files changed, 375 insertions(+) create mode 100644 argocd/inventory-dev.yaml create mode 100644 argocd/inventory-staging.yaml create mode 100644 docker/inventory/Dockerfile create mode 100644 helm/inventory/Chart.yaml create mode 100644 helm/inventory/templates/_helpers.tpl create mode 100644 helm/inventory/templates/deployment.yaml create mode 100644 helm/inventory/templates/hpa.yaml create mode 100644 helm/inventory/templates/ingress.yaml create mode 100644 helm/inventory/templates/networkpolicy.yaml create mode 100644 helm/inventory/templates/service.yaml create mode 100644 helm/inventory/templates/servicemonitor.yaml create mode 100644 helm/inventory/values-dev.yaml create mode 100644 helm/inventory/values-staging.yaml create mode 100644 helm/inventory/values.yaml diff --git a/argocd/inventory-dev.yaml b/argocd/inventory-dev.yaml new file mode 100644 index 0000000..be7b23a --- /dev/null +++ b/argocd/inventory-dev.yaml @@ -0,0 +1,24 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: inventory-dev + namespace: argocd +spec: + project: default + source: + repoURL: https://github.com/Cognition-Partner-Workshops/ordermanager-iac.git + targetRevision: main + path: helm/inventory + helm: + valueFiles: + - values.yaml + - values-dev.yaml + destination: + server: https://kubernetes.default.svc + namespace: decomposition-dev + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/argocd/inventory-staging.yaml b/argocd/inventory-staging.yaml new file mode 100644 index 0000000..19da130 --- /dev/null +++ b/argocd/inventory-staging.yaml @@ -0,0 +1,24 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: inventory-staging + namespace: argocd +spec: + project: default + source: + repoURL: https://github.com/Cognition-Partner-Workshops/ordermanager-iac.git + targetRevision: main + path: helm/inventory + helm: + valueFiles: + - values.yaml + - values-staging.yaml + destination: + server: https://kubernetes.default.svc + namespace: decomposition-staging + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/docker/inventory/Dockerfile b/docker/inventory/Dockerfile new file mode 100644 index 0000000..ae5d6cf --- /dev/null +++ b/docker/inventory/Dockerfile @@ -0,0 +1,15 @@ +# Stage 1: Build .NET Inventory API +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /src +COPY src/Inventory.Api/Inventory.Api.csproj src/Inventory.Api/ +RUN dotnet restore src/Inventory.Api/Inventory.Api.csproj +COPY src/Inventory.Api/ src/Inventory.Api/ +RUN dotnet publish src/Inventory.Api/Inventory.Api.csproj -c Release -o /app/publish + +# Stage 2: Runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS runtime +WORKDIR /app +COPY --from=build /app/publish . +EXPOSE 8080 +ENV ASPNETCORE_URLS=http://+:8080 +ENTRYPOINT ["dotnet", "Inventory.Api.dll"] diff --git a/helm/inventory/Chart.yaml b/helm/inventory/Chart.yaml new file mode 100644 index 0000000..07dcfb3 --- /dev/null +++ b/helm/inventory/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: inventory +description: Helm chart for the Inventory microservice (extracted from OrderManager monolith) +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/helm/inventory/templates/_helpers.tpl b/helm/inventory/templates/_helpers.tpl new file mode 100644 index 0000000..6ebda70 --- /dev/null +++ b/helm/inventory/templates/_helpers.tpl @@ -0,0 +1,27 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "inventory.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "inventory.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{- define "inventory.labels" -}} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }} +app.kubernetes.io/name: {{ include "inventory.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{- define "inventory.selectorLabels" -}} +app.kubernetes.io/name: {{ include "inventory.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm/inventory/templates/deployment.yaml b/helm/inventory/templates/deployment.yaml new file mode 100644 index 0000000..fa4e7ec --- /dev/null +++ b/helm/inventory/templates/deployment.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "inventory.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "inventory.selectorLabels" . | nindent 8 }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + {{- if .Values.env }} + env: + {{- toYaml .Values.env | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 5 + periodSeconds: 10 diff --git a/helm/inventory/templates/hpa.yaml b/helm/inventory/templates/hpa.yaml new file mode 100644 index 0000000..a3f435a --- /dev/null +++ b/helm/inventory/templates/hpa.yaml @@ -0,0 +1,22 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "inventory.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} +{{- end }} diff --git a/helm/inventory/templates/ingress.yaml b/helm/inventory/templates/ingress.yaml new file mode 100644 index 0000000..e6dce11 --- /dev/null +++ b/helm/inventory/templates/ingress.yaml @@ -0,0 +1,29 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ingressClassName: {{ .Values.ingress.className }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "inventory.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/inventory/templates/networkpolicy.yaml b/helm/inventory/templates/networkpolicy.yaml new file mode 100644 index 0000000..c7e7fd8 --- /dev/null +++ b/helm/inventory/templates/networkpolicy.yaml @@ -0,0 +1,48 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "inventory.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + ports: + - protocol: TCP + port: {{ .Values.service.targetPort }} + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: ordermanager + ports: + - protocol: TCP + port: {{ .Values.service.targetPort }} + {{- if .Values.monitoring.enabled }} + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: monitoring + ports: + - protocol: TCP + port: {{ .Values.monitoring.port }} + {{- end }} + egress: + - to: [] + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + - to: [] + ports: + - protocol: TCP + port: 443 diff --git a/helm/inventory/templates/service.yaml b/helm/inventory/templates/service.yaml new file mode 100644 index 0000000..cb22945 --- /dev/null +++ b/helm/inventory/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.targetPort }} + protocol: TCP + name: http + selector: + {{- include "inventory.selectorLabels" . | nindent 4 }} diff --git a/helm/inventory/templates/servicemonitor.yaml b/helm/inventory/templates/servicemonitor.yaml new file mode 100644 index 0000000..1c7302c --- /dev/null +++ b/helm/inventory/templates/servicemonitor.yaml @@ -0,0 +1,16 @@ +{{- if .Values.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "inventory.fullname" . }} + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "inventory.selectorLabels" . | nindent 6 }} + endpoints: + - port: http + path: {{ .Values.monitoring.path }} + interval: 30s +{{- end }} diff --git a/helm/inventory/values-dev.yaml b/helm/inventory/values-dev.yaml new file mode 100644 index 0000000..6ee6e5d --- /dev/null +++ b/helm/inventory/values-dev.yaml @@ -0,0 +1,28 @@ +replicaCount: 1 + +image: + tag: dev-latest + +ingress: + hosts: + - host: inventory-dev.workshop.local + paths: + - path: / + pathType: Prefix + +resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + +env: + - name: ASPNETCORE_ENVIRONMENT + value: Development + - name: ConnectionStrings__DefaultConnection + value: "Data Source=inventory.db" + +persistence: + enabled: false diff --git a/helm/inventory/values-staging.yaml b/helm/inventory/values-staging.yaml new file mode 100644 index 0000000..854bbcd --- /dev/null +++ b/helm/inventory/values-staging.yaml @@ -0,0 +1,25 @@ +replicaCount: 2 + +image: + tag: staging-latest + +ingress: + hosts: + - host: inventory-staging.workshop.local + paths: + - path: / + pathType: Prefix + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + +autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 4 + targetCPUUtilizationPercentage: 75 diff --git a/helm/inventory/values.yaml b/helm/inventory/values.yaml new file mode 100644 index 0000000..b6b4e76 --- /dev/null +++ b/helm/inventory/values.yaml @@ -0,0 +1,52 @@ +replicaCount: 1 + +image: + repository: 599083837640.dkr.ecr.us-east-1.amazonaws.com/workshop/inventory + tag: latest + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 + targetPort: 8080 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-staging + hosts: + - host: inventory.workshop.local + paths: + - path: / + pathType: Prefix + +resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + +env: + - name: ASPNETCORE_ENVIRONMENT + value: Production + - name: ConnectionStrings__DefaultConnection + value: "Data Source=/data/inventory.db" + +persistence: + enabled: true + size: 1Gi + storageClass: gp2 + +monitoring: + enabled: true + path: /metrics + port: 8080 From df85bcc03645d10952e2aae4b2d85d5381d59e45 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 06:55:23 +0000 Subject: [PATCH 2/2] Add PVC and volume mount for inventory /data persistence --- helm/inventory/templates/deployment.yaml | 11 +++++++++++ helm/inventory/templates/pvc.yaml | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 helm/inventory/templates/pvc.yaml diff --git a/helm/inventory/templates/deployment.yaml b/helm/inventory/templates/deployment.yaml index fa4e7ec..e3974bb 100644 --- a/helm/inventory/templates/deployment.yaml +++ b/helm/inventory/templates/deployment.yaml @@ -30,6 +30,11 @@ spec: {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if .Values.persistence.enabled }} + volumeMounts: + - name: data + mountPath: /data + {{- end }} livenessProbe: httpGet: path: /health @@ -42,3 +47,9 @@ spec: port: http initialDelaySeconds: 5 periodSeconds: 10 + {{- if .Values.persistence.enabled }} + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ include "inventory.fullname" . }}-data + {{- end }} diff --git a/helm/inventory/templates/pvc.yaml b/helm/inventory/templates/pvc.yaml new file mode 100644 index 0000000..e5d3abd --- /dev/null +++ b/helm/inventory/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "inventory.fullname" . }}-data + labels: + {{- include "inventory.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + {{- if .Values.persistence.storageClass }} + storageClassName: {{ .Values.persistence.storageClass }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size }} +{{- end }}