https://github.com/saadaouialaeddine/ecommerce-cloud-platform
A Repo for a Smart AI-based Order Management Platform Prototype
https://github.com/saadaouialaeddine/ecommerce-cloud-platform
ai consul kafka keycloak kubernetes prototype python security spark streaming vae-pytorch vault
Last synced: about 1 month ago
JSON representation
A Repo for a Smart AI-based Order Management Platform Prototype
- Host: GitHub
- URL: https://github.com/saadaouialaeddine/ecommerce-cloud-platform
- Owner: SaadaouiAlaeddine
- Created: 2025-02-04T23:58:12.000Z (over 1 year ago)
- Default Branch: dev
- Last Pushed: 2025-03-31T23:56:16.000Z (about 1 year ago)
- Last Synced: 2025-04-01T00:28:57.056Z (about 1 year ago)
- Topics: ai, consul, kafka, keycloak, kubernetes, prototype, python, security, spark, streaming, vae-pytorch, vault
- Language: Python
- Homepage:
- Size: 93.8 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Smart AI-based Order Management Platform
This project is a prototype using Kubernetes as platform to integrate and orchestrate all the required components to speed up order processing and filter orders for validations using AI jobs.
## Architecture
The Lucidchart diagram is a high level picture of the different Kubernetes components organised by namespaces to separate concerns, management and enable required network policies and RBAC roles
- [@Lucidchart Diagram](https://lucid.app/publicSegments/view/dea8c52d-a918-4d66-a2ba-acd018dfdea7/image.jpeg)
Click on the image to open it in new tab and zoom in

## Installation
**k is an alias for kubectl**
1) **install kind:**
kind create cluster --config /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/kind/clusters-def.yaml
2) **install metallb**
k create namespacemetallb-system
helm install metallb metallb/metallb -n metallb-system
**use the range from this output:**
docker network inspect kind | grep Subnet
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/metallb/metallb-config.yaml
**verify installation**
kubectl get ipaddresspool -n metallb-system
kubectl get l2advertisement -n metallb-system
3) **install nginx**
k create namespace nginx
k create deployment nginx --image=nginx -n nginx
kubectl expose deployment nginx --type=LoadBalancer --port=80 --target-port=80 -n nginx
4) **install prometheus + grafana**
k create namespace prometheus
helm install prometheus prometheus-community/kube-prometheus-stack --namespace prometheus --set prometheus.prometheusSpec.service.type=LoadBalancer
k patch svc prometheus-kube-prometheus-prometheus -n prometheus --type='json' -p '[{"op": "replace", "path": "/spec/type", "value": "LoadBalancer"}]'
5) **install rabbitmq**
helm install my-rabbitmq bitnami/rabbitmq \
--set persistence.existingClaim=rabbitmq-pvc \
--set persistence.size=1Gi \
--set auth.username=admin \
--set auth.password=adminpassword \
--set service.type=LoadBalancer \
--set metrics.enabled=true \
--set metrics.serviceMonitor.enabled=true \
-n rabbitmq
6) **install cert-manager**
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
7) **install consul**
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/consul/pv.yaml
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/consul/pvc.yaml
helm upgrade --install consul hashicorp/consul -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/consul/values.yaml -n consul
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/consul/consul-mesh-gateway.yaml
8) **install mongo**
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/mongodb
kubectl exec -it mongodb-0 -n mongo -- mongosh
rs.reconfig({
_id: "rs0",
members: [
{ _id: 0, host: "192.168.97.206:27017" },
{ _id: 1, host: "192.168.97.207:27017" }
]
}, {force: true})
9) **install postgres**
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/postgres
10) **install vault**
helm install vault hashicorp/vault \
--namespace vault \
--set "server.service.type=LoadBalancer" \
--set "server.ha.enabled=false" \
--set "server.ha.raft.enabled=false" \
--set "server.dataStorage.enabled=true" \
--set "server.dataStorage.size=1Gi" \
--set "server.dataStorage.storageClass=standard" \
--set "server.dataStorage.persistentVolumeReclaimPolicy=Delete"
k cp key1.asc vault-0:/tmp/key1.asc -n vault
k exec -it vault-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 -pgp-keys="/tmp/key1.asc"
echo "encrypted unsealed key " | base64 --decode | keybase pgp decrypt
update the bach file with VAULT_TOKEN and VAULT_ADDR
vault operator unseal unseal_key
11) **install registry**
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/registry
12) **install redis**
k apply -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/redis/redis-deployment.yaml
13) **install kafka**
helm install kafka bitnami/kafka --namespace kafka \
--set persistence.enabled=true \
--set persistence.size=1Gi \
--set persistence.storageClass=manual \
--set replicaCount=1 \
--set service.type=LoadBalancer \
--set externalAccess.enabled=true \
--set externalAccess.service.type=LoadBalancer \
--set externalAccess.service.port=9094 \
--set externalAccess.autoDiscovery.enabled=true \
--set rbac.create=true \
--set controller.automountServiceAccountToken=true \
--set broker.automountServiceAccountToken=true
**install kafka ui:**
docker compose up -d path-to-file
14) **install spark**
helm install spark bitnami/spark --set service.type=LoadBalancer --namespace spark
k edit statefulset spark-worker -n spark to increase cores, mem….
retrieve the password: "$(kubectl get secret kafka-user-passwords --namespace kafka -o jsonpath='{.data.client-passwords}' | base64 -d | cut -d , -f 1)";
15) **install keycloak**
helm install keycloak bitnami/keycloak -f /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/keycloak/values.yaml -n keycloak
get user passsword: kubectl get secret --namespace keycloak keycloak -o jsonpath="{.data.admin-password}" | base64 --decode
postgress passwords: kubectl get secret keycloak-postgresql -n keycloak -o yaml
16) **install install airflow**
helm install airflow apache-airflow/airflow \
--namespace airflow \
--values /Users/alaeddinesaadaoui/PycharmProjects/ecommerce-cloud-platform/config/airflow/values.yaml
## Components
### $${\color{red}Consul}$$
- Consul is deployed to enable service discoverability

- Intentions are created to define access between microservices

### $${\color{red}Keycloak}$$
- Keycloak is installed to define an identity layer for microservices to enable authentication and authorization features

- Scopes are required to define the required jwt entries, in this case the audience and roles are required to connect later on with vault

- Realm Roles with associated Client Roles are required to define the resource_access section in jwt

- The generated JWT contains the client scope and access_token using the client's credentials

- The decoded access token contains aud, resources_access and scope entries passed to vault to access microservice secrets

- The generated JWT is signed using R256 algorithm, the kid entry will be used to fetch the public key from the keycloak certification entries

- To enable JWT signature, a provided was added to the Keycloak realm with a generated certificate and private key

- Using the same certificate and private key, we can verify the signature of JWT using jwt.io

- At the code level, the kid entry will be used to fetch the public key from the Keycloak certs page

### $${\color{red}Vault}$$
- Vault is deployed to store the microservices secrets. Kubernetes allows the secrets creation and encoding using Base64 but it doesn't secure it.

- To use Keycloak as identity provider, JWT is enabled in vault and JWT Authentication Method is defined using Keycloak

- A role is created to connect to vault using the JWT of the Keycloak client

- To enable the secrets access, the Vault policy vault-reader-scope is need to be created

- At the code level, post request will be made to /v1/auth/jwt/login using the role name and the Keycloak JAWT to retrieve client token to access the microservice secretrs

### $${\color{red}Rabbitmq}$$
- RabbitMQ is deployed to create the required exchanges and queues for orders processing.

- To simplify the messages flows, all the orders will be sent to a central exchange: order-exchange. Three queues and one exchange are bound to order-exchange
- The created queues are durable and priority-orders queue is a priority queue to prioritize the incoming orders based on their priority values
- The digital orders are separated and have their own exchange

### $${\color{red}MongoDB}$$
- The regular orders come in different formats with different user/product attributes. So for fast storage and post-processing, a Mongo database will be used for storage. To enable Kafka streaming, replication has to be enabled. So the Mongo database is created with two replicas.

### $${\color{red}Kafka}$$
Kafka is deployed to enable realtime validation and processing of regular orders. The orders-topics will be a bridge between Mongo orders database and Spark jobs.

### $${\color{red} API Authorization}$$
- To validate the jwt used for all the sensitive incomning requests, a decorator pattern is used to call a validation function validate_jwt.

- The validation function will fetch the authorization token to validate it. In case there is any issue, an error is raised.

- For non sensitive calls like healthcheck requests, the decorator is not used

- To automate token generation for test calls using postman, a pre-request script is added to generate the token and update the dev environment variable.

### $${\color{red} Blue/Green Deployment}$$
- To enable B/G deployment, a second kind cluster is created with consul deployed and a mesh-gateway enabled.

- A peering connection should be established between the two clusters

- The service should be exported in the second cluster with indicating the main cluster(dc2) as a consumer.


- On the main cluster (dc2) side, the peer (dc1) and the imported service should be shown.

- Now, we can see the two instances of the stock-service. The instance deployed in the main cluster and the exported instance from the peer cluster.

- A failover should be enabled from the main cluster with the peer cluster (dc1) as a failover target.

- Finally, to get a fully functional B/G deployment. All the services should be deployed in both clusters and the previous steps should be implemented symmetrically on both sides.
## Authors
- [@alaeddine saadaoui](https://github.com/SaadaouiAlaeddine)