diff --git a/.scripts/test-score-files.sh b/.scripts/test-score-files.sh index d4c7d38..6652b75 100755 --- a/.scripts/test-score-files.sh +++ b/.scripts/test-score-files.sh @@ -13,7 +13,9 @@ do cd $feature if [[ "$category" = "samples/" ]]; then make compose-test + make compose-down make k8s-test + make k8s-down else score-compose init --no-sample score-compose generate score.yaml diff --git a/README.md b/README.md index b2926ce..fe671f6 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,5 @@ - [Specification](./specification/) - [Resources](./resources/) - [Samples](./samples/) - - [OnlineBoutique](./samples/onlineboutique/) \ No newline at end of file + - [OnlineBoutique](./samples/onlineboutique/) + - [AKS Store Demo](./samples/aks-store-demo/) \ No newline at end of file diff --git a/samples/aks-store-demo/Makefile b/samples/aks-store-demo/Makefile new file mode 100644 index 0000000..b1ac538 --- /dev/null +++ b/samples/aks-store-demo/Makefile @@ -0,0 +1,91 @@ +# Disable all the default make stuff +MAKEFLAGS += --no-builtin-rules +.SUFFIXES: + +## Display a list of the documented make targets +.PHONY: help +help: + @echo Documented Make targets: + @perl -e 'undef $$/; while (<>) { while ($$_ =~ /## (.*?)(?:\n# .*)*\n.PHONY:\s+(\S+).*/mg) { printf "\033[36m%-30s\033[0m %s\n", $$2, $$1 } }' $(MAKEFILE_LIST) | sort + +.PHONY: .FORCE +.FORCE: + +.score-compose/state.yaml: + score-compose init \ + --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-compose/10-service.provisioners.yaml + +compose.yaml: order/score.yaml product/score.yaml store-front/score.yaml store-admin/score.yaml makeline/score.yaml .score-compose/state.yaml Makefile + score-compose generate \ + order/score.yaml \ + product/score.yaml \ + store-front/score.yaml \ + store-admin/score.yaml \ + makeline/score.yaml + +## Generate a compose.yaml file from the score specs and launch it. +.PHONY: compose-up +compose-up: compose.yaml + docker compose up --build -d --remove-orphans + sleep 5 + +## Generate a compose.yaml file from the score spec, launch it and test (curl) the exposed container. +.PHONY: compose-test +compose-test: compose-up + curl $$(score-compose resources get-outputs 'dns.default#store-front.dns' --format '{{ .host }}:8080') + +## Delete the containers running via compose down. +.PHONY: compose-down +compose-down: + docker compose down -v --remove-orphans || true + +.score-k8s/state.yaml: + score-k8s init \ + --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml + +manifests.yaml: makeline/score.yaml order/score.yaml product/score.yaml store-admin/score.yaml store-front/score.yaml .score-k8s/state.yaml Makefile + score-k8s generate \ + makeline/score.yaml \ + order/score.yaml \ + product/score.yaml \ + store-admin/score.yaml \ + store-front/score.yaml + +## Create a local Kind cluster. +.PHONY: kind-create-cluster +kind-create-cluster: + ./scripts/setup-kind-cluster.sh + +NAMESPACE ?= default +## Generate a manifests.yaml file from the score spec and apply it in Kubernetes. +.PHONY: k8s-up +k8s-up: manifests.yaml + kubectl apply \ + -f manifests.yaml \ + -n ${NAMESPACE} + kubectl wait deployments/store-front \ + -n ${NAMESPACE} \ + --for condition=Available \ + --timeout=90s + kubectl wait pods \ + -n ${NAMESPACE} \ + -l app.kubernetes.io/name=store-front \ + --for condition=Ready \ + --timeout=90s + sleep 5 + kubectl get pods -n ${NAMESPACE} + +## Expose the container deployed in Kubernetes via port-forward. +.PHONY: k8s-test +k8s-test: k8s-up + curl $$(score-k8s resources get-outputs dns.default#store-front.dns --format '{{ .host }}') + +## Delete the deployment of the local container in Kubernetes. +.PHONY: k8s-down +k8s-down: + kubectl delete \ + -f manifests.yaml \ + -n ${NAMESPACE} + sleep 5 \ No newline at end of file diff --git a/samples/aks-store-demo/README.md b/samples/aks-store-demo/README.md new file mode 100644 index 0000000..96b8772 --- /dev/null +++ b/samples/aks-store-demo/README.md @@ -0,0 +1,8 @@ +# AKS Store demo + +![](https://github.com/Azure-Samples/aks-store-demo/raw/main/assets/demo-arch.png) + +Deploy the [Azure-Samples/aks-store-demo](https://github.com/Azure-Samples/aks-store-demo) with Score: + +- [`score-compose`](./score-compose.md) +- [`score-k8s`](./score-k8s.md) \ No newline at end of file diff --git a/samples/aks-store-demo/makeline/score.yaml b/samples/aks-store-demo/makeline/score.yaml new file mode 100644 index 0000000..e781a57 --- /dev/null +++ b/samples/aks-store-demo/makeline/score.yaml @@ -0,0 +1,42 @@ +apiVersion: score.dev/v1b1 +metadata: + name: makeline-service + annotations: + tags: "golang,backend" +containers: + makeline-service: + image: ghcr.io/azure-samples/aks-store-demo/makeline-service:2.1.0 + variables: + ORDER_QUEUE_URI: "amqp://${resources.orders-queue.host}:${resources.orders-queue.port}" + ORDER_QUEUE_USERNAME: "${resources.orders-queue.username}" + ORDER_QUEUE_PASSWORD: "${resources.orders-queue.password}" + ORDER_QUEUE_NAME: "orders" + ORDER_DB_URI: "${resources.orders-database.connection}" + ORDER_DB_NAME: "orderdb" + ORDER_DB_COLLECTION_NAME: "orders" + livenessProbe: + httpGet: + path: /health + port: 3001 + readinessProbe: + httpGet: + path: /health + port: 3001 + resources: + limits: + memory: "20Mi" + cpu: "5m" + requests: + memory: "6Mi" + cpu: "1m" +service: + ports: + http: + port: 3001 + targetPort: 3001 +resources: + orders-queue: + type: amqp + id: orders-queue + orders-database: + type: mongodb \ No newline at end of file diff --git a/samples/aks-store-demo/order/score.yaml b/samples/aks-store-demo/order/score.yaml new file mode 100644 index 0000000..066e2dd --- /dev/null +++ b/samples/aks-store-demo/order/score.yaml @@ -0,0 +1,39 @@ +apiVersion: score.dev/v1b1 +metadata: + name: order-service + annotations: + tags: "javascript,backend" +containers: + order-service: + image: ghcr.io/azure-samples/aks-store-demo/order-service:2.1.0 + variables: + ORDER_QUEUE_HOSTNAME: "${resources.orders-queue.host}" + ORDER_QUEUE_PORT: "${resources.orders-queue.port}" + ORDER_QUEUE_USERNAME: "${resources.orders-queue.username}" + ORDER_QUEUE_PASSWORD: "${resources.orders-queue.password}" + ORDER_QUEUE_NAME: "orders" + FASTIFY_ADDRESS: "0.0.0.0" + livenessProbe: + httpGet: + path: /health + port: 3000 + readinessProbe: + httpGet: + path: /health + port: 3000 + resources: + limits: + memory: "128Mi" + cpu: "75m" + requests: + memory: "50Mi" + cpu: "1m" +service: + ports: + http: + port: 3000 + targetPort: 3000 +resources: + orders-queue: + type: amqp + id: orders-queue \ No newline at end of file diff --git a/samples/aks-store-demo/product/score.yaml b/samples/aks-store-demo/product/score.yaml new file mode 100644 index 0000000..3619ab4 --- /dev/null +++ b/samples/aks-store-demo/product/score.yaml @@ -0,0 +1,28 @@ +apiVersion: score.dev/v1b1 +metadata: + name: product-service + annotations: + tags: "rust,backend" +containers: + product-service: + image: ghcr.io/azure-samples/aks-store-demo/product-service:2.1.0 + livenessProbe: + httpGet: + path: /health + port: 3002 + readinessProbe: + httpGet: + path: /health + port: 3002 + resources: + limits: + memory: "10Mi" + cpu: "2m" + requests: + memory: "1Mi" + cpu: "1m" +service: + ports: + http: + port: 3002 + targetPort: 3002 \ No newline at end of file diff --git a/samples/aks-store-demo/score-compose.md b/samples/aks-store-demo/score-compose.md new file mode 100644 index 0000000..8c01980 --- /dev/null +++ b/samples/aks-store-demo/score-compose.md @@ -0,0 +1,21 @@ +```bash +score-compose init --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-compose/10-service.provisioners.yaml +``` + +```bash +score-compose generate \ + order/score.yaml \ + product/score.yaml \ + store-front/score.yaml \ + store-admin/score.yaml \ + makeline/score.yaml +``` + +```bash +docker compose up --build -d --remove-orphans +``` + +```bash +curl $(score-compose resources get-outputs dns.default#store-front.dns --format '{{ .host }}:8080') +``` \ No newline at end of file diff --git a/samples/aks-store-demo/score-k8s.md b/samples/aks-store-demo/score-k8s.md new file mode 100644 index 0000000..a38983b --- /dev/null +++ b/samples/aks-store-demo/score-k8s.md @@ -0,0 +1,21 @@ +```bash +score-k8s init --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml +``` + +```bash +score-k8s generate \ + order/score.yaml \ + product/score.yaml \ + store-front/score.yaml \ + store-admin/score.yaml \ + makeline/score.yaml +``` + +```bash +kubectl apply -f manifests.yaml +``` + +```bash +curl $(score-k8s resources get-outputs dns.default#store-front.dns --format '{{ .host }}:80') +``` \ No newline at end of file diff --git a/samples/aks-store-demo/store-admin/score.yaml b/samples/aks-store-demo/store-admin/score.yaml new file mode 100644 index 0000000..0cefa69 --- /dev/null +++ b/samples/aks-store-demo/store-admin/score.yaml @@ -0,0 +1,41 @@ +apiVersion: score.dev/v1b1 +metadata: + name: store-admin + annotations: + tags: "javascript,website" +containers: + store-admin: + image: ghcr.io/azure-samples/aks-store-demo/store-admin:2.1.0 + livenessProbe: + httpGet: + path: /health + port: 8081 + readinessProbe: + httpGet: + path: /health + port: 8081 + resources: + limits: + memory: "512Mi" + cpu: "1000m" + requests: + memory: "200Mi" + cpu: "1m" +service: + ports: + http: + port: 8081 + targetPort: 8081 +resources: + dns: + type: dns + route: + type: route + params: + host: ${resources.dns.host} + path: / + port: 8081 + makeline-service: + type: service + product-service: + type: service \ No newline at end of file diff --git a/samples/aks-store-demo/store-front/score.yaml b/samples/aks-store-demo/store-front/score.yaml new file mode 100644 index 0000000..c0b07a1 --- /dev/null +++ b/samples/aks-store-demo/store-front/score.yaml @@ -0,0 +1,41 @@ +apiVersion: score.dev/v1b1 +metadata: + name: store-front + annotations: + tags: "javascript,website" +containers: + store-front: + image: ghcr.io/azure-samples/aks-store-demo/store-front:2.1.0 + livenessProbe: + httpGet: + path: /health + port: 8080 + readinessProbe: + httpGet: + path: /health + port: 8080 + resources: + limits: + memory: "512Mi" + cpu: "1000m" + requests: + memory: "200Mi" + cpu: "1m" +service: + ports: + http: + port: 8080 + targetPort: 8080 +resources: + dns: + type: dns + route: + type: route + params: + host: ${resources.dns.host} + path: / + port: 8080 + order-service: + type: service + product-service: + type: service \ No newline at end of file diff --git a/samples/onlineboutique/Makefile b/samples/onlineboutique/Makefile index 83f62b3..03c3a4f 100644 --- a/samples/onlineboutique/Makefile +++ b/samples/onlineboutique/Makefile @@ -99,6 +99,8 @@ k8s-up: manifests.yaml -l app.kubernetes.io/name=frontend \ --for condition=Ready \ --timeout=90s + sleep 5 + kubectl get pods -n ${NAMESPACE} ## Test the expose frontend app .PHONY: k8s-test @@ -110,4 +112,5 @@ k8s-test: k8s-up k8s-down: kubectl delete \ -f manifests.yaml \ - -n ${NAMESPACE} \ No newline at end of file + -n ${NAMESPACE} + sleep 5 \ No newline at end of file diff --git a/samples/onlineboutique/README.md b/samples/onlineboutique/README.md index 864e45d..af07171 100644 --- a/samples/onlineboutique/README.md +++ b/samples/onlineboutique/README.md @@ -1,27 +1,28 @@ -```bash -score-compose init --no-sample \ - --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-compose/10-service.provisioners.yaml -``` +# OnlineBoutique -```bash -score-compose generate \ - ad/score.yaml \ - cart/score.yaml \ - currency/score.yaml \ - email/score.yaml \ - payment/score.yaml \ - productcatalog/score.yaml \ - recommendation/score.yaml \ - shipping/score.yaml \ - checkout/score.yaml \ - frontend/score.yaml \ - loadgenerator/score.yaml +```mermaid +flowchart TD + dns[DNS] --> frontend(frontend) + subgraph Workloads + loadgenerator(loadgenerator)-->frontend + frontend-->recommendation(recommendation) + frontend-->ad(ad) + frontend-->shipping(shipping) + frontend-->currency(currency) + frontend-->checkout(checkout) + frontend-->cart(cart) + checkout-->cart + checkout-->payment(payment) + checkout-->email(email) + checkout-->currency + checkout-->productcatalog(productcatalog) + recommendation-->productcatalog + frontend-->productcatalog + end + cart-->redis[(Redis)] ``` -```bash -docker compose up --build -d --remove-orphans -``` +Deploy the [GoogleCloudPlatform/microservices-demo](https://github.com/GoogleCloudPlatform/microservices-demo) with Score: -```bash -curl $$(score-compose resources get-outputs dns.default#frontend.dns --format '{{ .host }}:8080') -``` \ No newline at end of file +- [`score-compose`](./score-compose.md) +- [`score-k8s`](./score-k8s.md) \ No newline at end of file diff --git a/samples/onlineboutique/score-compose.md b/samples/onlineboutique/score-compose.md new file mode 100644 index 0000000..30cf734 --- /dev/null +++ b/samples/onlineboutique/score-compose.md @@ -0,0 +1,27 @@ +```bash +score-compose init --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-compose/10-service.provisioners.yaml +``` + +```bash +score-compose generate \ + ad/score.yaml \ + cart/score.yaml \ + currency/score.yaml \ + email/score.yaml \ + payment/score.yaml \ + productcatalog/score.yaml \ + recommendation/score.yaml \ + shipping/score.yaml \ + checkout/score.yaml \ + frontend/score.yaml \ + loadgenerator/score.yaml +``` + +```bash +docker compose up --build -d --remove-orphans +``` + +```bash +curl $(score-compose resources get-outputs dns.default#frontend.dns --format '{{ .host }}:8080') +``` \ No newline at end of file diff --git a/samples/onlineboutique/score-k8s.md b/samples/onlineboutique/score-k8s.md new file mode 100644 index 0000000..43c4633 --- /dev/null +++ b/samples/onlineboutique/score-k8s.md @@ -0,0 +1,27 @@ +```bash +score-k8s init --no-sample \ + --provisioners https://raw.githubusercontent.com/score-spec/community-provisioners/refs/heads/main/service/score-k8s/10-service.provisioners.yaml +``` + +```bash +score-k8s generate \ + ad/score.yaml \ + cart/score.yaml \ + currency/score.yaml \ + email/score.yaml \ + payment/score.yaml \ + productcatalog/score.yaml \ + recommendation/score.yaml \ + shipping/score.yaml \ + checkout/score.yaml \ + frontend/score.yaml \ + loadgenerator/score.yaml +``` + +```bash +kubectl apply -f manifests.yaml +``` + +```bash +curl $(score-k8s resources get-outputs dns.default#frontend.dns --format '{{ .host }}:80') +``` \ No newline at end of file