From 0a925f5b7196b33de2a155247f4ad557e7c51a67 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Fri, 1 Dec 2023 11:46:07 -0800 Subject: [PATCH 1/9] feat: optimize store containers --- README.md | 12 +- aks-store-all-in-one.yaml | 9 +- aks-store-quickstart.yaml | 5 +- azure.yaml | 6 +- .../aks-store-demo/templates/ai-service.yaml | 2 +- .../templates/makeline-service.yaml | 2 +- .../templates/order-service.yaml | 2 +- .../templates/product-service.yaml | 5 +- .../aks-store-demo/templates/store-admin.yaml | 6 +- .../aks-store-demo/templates/store-front.yaml | 4 +- .../templates/virtual-customer.yaml | 2 +- .../templates/virtual-worker.yaml | 2 +- charts/aks-store-demo/values.yaml | 34 ++ docker-compose-quickstart.yml | 26 +- docker-compose.yml | 69 ++- infra/azd-hooks/postprovision.sh | 29 - infra/azd-hooks/predeploy.sh | 43 ++ infra/kubernetes.tf | 14 + infra/outputs.tf | 8 + src/makeline-service/README.md | 2 +- src/makeline-service/docker-compose.yml | 14 +- src/product-service/Cargo.lock | 544 +++++++++++++++++- src/product-service/Cargo.toml | 1 + src/product-service/src/main.rs | 79 ++- src/product-service/test-product-service.http | 17 +- src/store-admin/Dockerfile | 35 +- src/store-admin/README.md | 3 +- src/store-admin/docker-compose.yml | 32 +- src/store-admin/nginx.conf | 96 +++- src/store-admin/vue.config.js | 5 +- src/store-front/Dockerfile | 35 +- src/store-front/docker-compose.yml | 12 +- src/store-front/nginx.conf | 52 +- src/virtual-customer/docker-compose.yml | 6 +- src/virtual-worker/docker-compose.yml | 20 +- 35 files changed, 973 insertions(+), 260 deletions(-) delete mode 100755 infra/azd-hooks/postprovision.sh create mode 100755 infra/azd-hooks/predeploy.sh diff --git a/README.md b/README.md index 05497cc4..014b7b8d 100644 --- a/README.md +++ b/README.md @@ -66,12 +66,12 @@ git clone https://github.com/Azure-Samples/aks-store-demo.git cd aks-store-demo ``` -Configure your Azure OpenAI or OpenAI API keys in [`docker-compose.yml`](./docker-compose.yml) using the environment variables in the `aiservice` section: +Configure your Azure OpenAI or OpenAI API keys in [`docker-compose.yml`](./docker-compose.yml) using the environment variables in the `ai-service` section: ```yaml - aiservice: + ai-service: build: src/ai-service - container_name: 'aiservice' + container_name: 'ai-service' ... environment: - USE_AZURE_OPENAI=True # set to False if you are not using Azure OpenAI @@ -82,12 +82,12 @@ Configure your Azure OpenAI or OpenAI API keys in [`docker-compose.yml`](./docke ... ``` -Alternatively, if you do not have access to Azure OpenAI or OpenAI API keys, you can run the app without the `ai-service` by commenting out the `aiservice` section in [`docker-compose.yml`](./docker-compose.yml). For example: +Alternatively, if you do not have access to Azure OpenAI or OpenAI API keys, you can run the app without the `ai-service` by commenting out the `ai-service` section in [`docker-compose.yml`](./docker-compose.yml). For example: ```yaml -# aiservice: +# ai-service: # build: src/ai-service -# container_name: 'aiservice' +# container_name: 'ai-service' ... # networks: # - backend_services diff --git a/aks-store-all-in-one.yaml b/aks-store-all-in-one.yaml index 25eed65c..d48bfd1f 100644 --- a/aks-store-all-in-one.yaml +++ b/aks-store-all-in-one.yaml @@ -300,6 +300,9 @@ spec: image: ghcr.io/azure-samples/aks-store-demo/product-service:latest ports: - containerPort: 3002 + env: + - name: AI_SERVICE_URL + value: "http://ai-service:5001/" resources: requests: cpu: 1m @@ -374,7 +377,7 @@ spec: path: /health port: 8080 failureThreshold: 3 - initialDelaySeconds: 15 + initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: @@ -430,8 +433,6 @@ spec: value: "http://product-service:3002/" - name: VUE_APP_MAKELINE_SERVICE_URL value: "http://makeline-service:3001/" - - name: VUE_APP_AI_SERVICE_URL - value: "http://ai-service:5001/" resources: requests: cpu: 1m @@ -444,7 +445,7 @@ spec: path: /health port: 8081 failureThreshold: 3 - initialDelaySeconds: 15 + initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: diff --git a/aks-store-quickstart.yaml b/aks-store-quickstart.yaml index 0cfdd4a7..f19dfe16 100644 --- a/aks-store-quickstart.yaml +++ b/aks-store-quickstart.yaml @@ -179,6 +179,9 @@ spec: image: ghcr.io/azure-samples/aks-store-demo/product-service:latest ports: - containerPort: 3002 + env: + - name: AI_SERVICE_URL + value: "http://ai-service:5001/" resources: requests: cpu: 1m @@ -253,7 +256,7 @@ spec: path: /health port: 8080 failureThreshold: 3 - initialDelaySeconds: 15 + initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: diff --git a/azure.yaml b/azure.yaml index dcb4c483..a4555290 100644 --- a/azure.yaml +++ b/azure.yaml @@ -2,17 +2,17 @@ name: aks-store-demo metadata: - template: aks-store-dmeo@1.0.0 + template: aks-store-demo@1.0.0 hooks: preprovision: shell: sh continueOnError: false interactive: false run: infra/azd-hooks/preprovision.sh - postprovision: + predeploy: shell: sh continueOnError: false interactive: false - run: infra/azd-hooks/postprovision.sh + run: infra/azd-hooks/predeploy.sh infra: provider: terraform \ No newline at end of file diff --git a/charts/aks-store-demo/templates/ai-service.yaml b/charts/aks-store-demo/templates/ai-service.yaml index 0784fd46..697df893 100644 --- a/charts/aks-store-demo/templates/ai-service.yaml +++ b/charts/aks-store-demo/templates/ai-service.yaml @@ -54,7 +54,7 @@ spec: "kubernetes.io/os": linux containers: - name: order-service - image: ghcr.io/azure-samples/aks-store-demo/ai-service:1.0.0 + image: {{ .Values.aiService.image.repository }}:{{ .Values.aiService.image.tag }} ports: - containerPort: 5001 envFrom: diff --git a/charts/aks-store-demo/templates/makeline-service.yaml b/charts/aks-store-demo/templates/makeline-service.yaml index 857df1cb..ad1f1f8d 100644 --- a/charts/aks-store-demo/templates/makeline-service.yaml +++ b/charts/aks-store-demo/templates/makeline-service.yaml @@ -39,7 +39,7 @@ spec: "kubernetes.io/os": linux containers: - name: makeline-service - image: ghcr.io/azure-samples/aks-store-demo/makeline-service:1.0.0 + image: {{ .Values.makelineService.image.repository }}:{{ .Values.makelineService.image.tag }} ports: - containerPort: 3001 envFrom: diff --git a/charts/aks-store-demo/templates/order-service.yaml b/charts/aks-store-demo/templates/order-service.yaml index b2b25d67..d834e1a7 100644 --- a/charts/aks-store-demo/templates/order-service.yaml +++ b/charts/aks-store-demo/templates/order-service.yaml @@ -37,7 +37,7 @@ spec: "kubernetes.io/os": linux containers: - name: order-service - image: ghcr.io/azure-samples/aks-store-demo/order-service:1.0.0 + image: {{ .Values.orderService.image.repository }}:{{ .Values.orderService.image.tag }} ports: - containerPort: 3000 envFrom: diff --git a/charts/aks-store-demo/templates/product-service.yaml b/charts/aks-store-demo/templates/product-service.yaml index 1653cc62..33618249 100644 --- a/charts/aks-store-demo/templates/product-service.yaml +++ b/charts/aks-store-demo/templates/product-service.yaml @@ -16,9 +16,12 @@ spec: "kubernetes.io/os": linux containers: - name: product-service - image: ghcr.io/azure-samples/aks-store-demo/product-service:1.0.0 + image: {{ .Values.productService.image.repository }}:{{ .Values.productService.image.tag }} ports: - containerPort: 3002 + env: + - name: AI_SERVICE_URL + value: "http://ai-service:5001/" resources: requests: cpu: 1m diff --git a/charts/aks-store-demo/templates/store-admin.yaml b/charts/aks-store-demo/templates/store-admin.yaml index c96823fb..f019f2dd 100644 --- a/charts/aks-store-demo/templates/store-admin.yaml +++ b/charts/aks-store-demo/templates/store-admin.yaml @@ -16,7 +16,7 @@ spec: "kubernetes.io/os": linux containers: - name: store-admin - image: ghcr.io/azure-samples/aks-store-demo/store-admin:1.0.0 + image: {{ .Values.storeAdmin.image.repository }}:{{ .Values.storeAdmin.image.tag }} ports: - containerPort: 8081 name: store-admin @@ -25,8 +25,6 @@ spec: value: "http://product-service:3002/" - name: VUE_APP_MAKELINE_SERVICE_URL value: "http://makeline-service:3001/" - - name: VUE_APP_AI_SERVICE_URL - value: "http://ai-service:5001/" resources: requests: cpu: 1m @@ -39,7 +37,7 @@ spec: path: /health port: 8081 failureThreshold: 3 - initialDelaySeconds: 15 + initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: diff --git a/charts/aks-store-demo/templates/store-front.yaml b/charts/aks-store-demo/templates/store-front.yaml index 2a78a1f6..e82abdd8 100644 --- a/charts/aks-store-demo/templates/store-front.yaml +++ b/charts/aks-store-demo/templates/store-front.yaml @@ -16,7 +16,7 @@ spec: "kubernetes.io/os": linux containers: - name: store-front - image: ghcr.io/azure-samples/aks-store-demo/store-front:1.0.0 + image: {{ .Values.storeFront.image.repository }}:{{ .Values.storeFront.image.tag }} ports: - containerPort: 8080 name: store-front @@ -37,7 +37,7 @@ spec: path: /health port: 8080 failureThreshold: 3 - initialDelaySeconds: 15 + initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: diff --git a/charts/aks-store-demo/templates/virtual-customer.yaml b/charts/aks-store-demo/templates/virtual-customer.yaml index 80388502..cd11855f 100644 --- a/charts/aks-store-demo/templates/virtual-customer.yaml +++ b/charts/aks-store-demo/templates/virtual-customer.yaml @@ -16,7 +16,7 @@ spec: "kubernetes.io/os": linux containers: - name: virtual-customer - image: ghcr.io/azure-samples/aks-store-demo/virtual-customer:1.0.0 + image: {{ .Values.virtualCustomer.image.repository }}:{{ .Values.virtualCustomer.image.tag }} env: - name: ORDER_SERVICE_URL value: http://order-service:3000/ diff --git a/charts/aks-store-demo/templates/virtual-worker.yaml b/charts/aks-store-demo/templates/virtual-worker.yaml index f5d929e1..3a667bc5 100644 --- a/charts/aks-store-demo/templates/virtual-worker.yaml +++ b/charts/aks-store-demo/templates/virtual-worker.yaml @@ -16,7 +16,7 @@ spec: "kubernetes.io/os": linux containers: - name: virtual-worker - image: ghcr.io/azure-samples/aks-store-demo/virtual-worker:1.0.0 + image: {{ .Values.virtualWorker.image.repository }}:{{ .Values.virtualWorker.image.tag }} env: - name: MAKELINE_SERVICE_URL value: http://makeline-service:3001 diff --git a/charts/aks-store-demo/values.yaml b/charts/aks-store-demo/values.yaml index 11d8efa6..90b42c6b 100644 --- a/charts/aks-store-demo/values.yaml +++ b/charts/aks-store-demo/values.yaml @@ -16,6 +16,9 @@ aiService: managedIdentityClientId: "" useAzureOpenAi: true useAzureAd: true + image: + repository: "ghcr.io/azure-samples/aks-store-demo/ai-service" + tag: "latest" orderService: useAzureServiceBus: false # when false, local rabbitmq will be used @@ -25,6 +28,9 @@ orderService: queuePassword: "password" queueName: "orders" queueTransport: "" + image: + repository: "ghcr.io/azure-samples/aks-store-demo/order-service" + tag: "latest" makelineService: useAzureCosmosDB: false # when false, local mongodb will be used @@ -37,6 +43,34 @@ makelineService: orderDBCollectionName: "orders" orderDBUsername: "" orderDBPassword: "" + image: + repository: "ghcr.io/azure-samples/aks-store-demo/makeline-service" + tag: "latest" + +productService: + image: + repository: "ghcr.io/azure-samples/aks-store-demo/product-service" + tag: "latest" + +storeAdmin: + image: + repository: "ghcr.io/azure-samples/aks-store-demo/store-admin" + tag: "latest" + +storeFront: + image: + repository: "ghcr.io/azure-samples/aks-store-demo/store-front" + tag: "latest" + +virtualCustomer: + image: + repository: "ghcr.io/azure-samples/aks-store-demo/virtual-customer" + tag: "latest" + +virtualWorker: + image: + repository: "ghcr.io/azure-samples/aks-store-demo/virtual-worker" + tag: "latest" storeFront: serviceType: LoadBalancer diff --git a/docker-compose-quickstart.yml b/docker-compose-quickstart.yml index 622fd3a0..d0bdfcb6 100644 --- a/docker-compose-quickstart.yml +++ b/docker-compose-quickstart.yml @@ -19,14 +19,14 @@ services: - ./rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: src/order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -42,38 +42,38 @@ services: depends_on: rabbitmq: condition: service_healthy - productservice: + product-service: build: src/product-service - container_name: 'productservice' + container_name: 'product-service' restart: always ports: - 3002:3002 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://productservice:3002/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://product-service:3002/health"] interval: 30s timeout: 10s retries: 5 networks: - backend_services - storefront: + store-front: build: src/store-front - container_name: 'storefront' + container_name: 'store-front' restart: always ports: - 8080:8080 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://storefront:80/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://store-front:80/health"] interval: 30s timeout: 10s retries: 5 environment: - - VUE_APP_PRODUCT_SERVICE_URL=http://productservice:3002/ - - VUE_APP_ORDER_SERVICE_URL=http://orderservice:3000/ + - VUE_APP_PRODUCT_SERVICE_URL=http://product-service:3002/ + - VUE_APP_ORDER_SERVICE_URL=http://order-service:3000/ networks: - backend_services depends_on: - - productservice - - orderservice + - product-service + - order-service networks: backend_services: driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 1296330a..062e963a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,14 +32,14 @@ services: - ./rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: src/order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -55,14 +55,14 @@ services: depends_on: rabbitmq: condition: service_healthy - makelineservice: + makeline-service: build: src/makeline-service - container_name: 'makelineservice' + container_name: 'makeline-service' restart: always ports: - 3001:3001 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makelineservice:3001/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makeline-service:3001/health"] interval: 30s timeout: 10s retries: 5 @@ -81,90 +81,89 @@ services: condition: service_healthy mongodb: condition: service_healthy - productservice: + product-service: build: src/product-service - container_name: 'productservice' + container_name: 'product-service' restart: always ports: - 3002:3002 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://productservice:3002/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://product-service:3002/health"] interval: 30s timeout: 10s retries: 5 networks: - backend_services - storefront: + store-front: build: src/store-front - container_name: 'storefront' + container_name: 'store-front' restart: always ports: - 8080:8080 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://storefront:80/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://store-front:80/health"] interval: 30s timeout: 10s retries: 5 environment: - - VUE_APP_PRODUCT_SERVICE_URL=http://productservice:3002/ - - VUE_APP_ORDER_SERVICE_URL=http://orderservice:3000/ + - VUE_APP_PRODUCT_SERVICE_URL=http://product-service:3002/ + - VUE_APP_ORDER_SERVICE_URL=http://order-service:3000/ networks: - backend_services depends_on: - - productservice - - orderservice - storeadmin: + - product-service + - order-service + store-admin: build: src/store-admin - container_name: 'storeadmin' + container_name: 'store-admin' restart: always ports: - 8081:8081 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://storeadmin:80/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://store-admin:80/health"] interval: 30s timeout: 10s retries: 5 environment: - - VUE_APP_PRODUCT_SERVICE_URL=http://productservice:3002/ - - VUE_APP_MAKELINE_SERVICE_URL=http://makelineservice:3001/ - - VUE_APP_AI_SERVICE_URL=http://aiservice:5001/ + - VUE_APP_PRODUCT_SERVICE_URL=http://product-service:3002/ + - VUE_APP_MAKELINE_SERVICE_URL=http://makeline-service:3001/ networks: - backend_services depends_on: - - productservice - - makelineservice - virtualcustomer: + - product-service + - makeline-service + virtual-customer: build: src/virtual-customer - container_name: 'virtualcustomer' + container_name: 'virtual-customer' restart: always environment: - - ORDER_SERVICE_URL=http://orderservice:3000/ + - ORDER_SERVICE_URL=http://order-service:3000/ - ORDERS_PER_HOUR=500 networks: - backend_services depends_on: - orderservice: + order-service: condition: service_healthy - virtualworker: + virtual-worker: build: src/virtual-worker - container_name: 'virtualworker' + container_name: 'virtual-worker' restart: always environment: - - MAKELINE_SERVICE_URL=http://makelineservice:3001 + - MAKELINE_SERVICE_URL=http://makeline-service:3001 - ORDERS_PER_HOUR=400 networks: - backend_services depends_on: - makelineservice: + makeline-service: condition: service_healthy - aiservice: + ai-service: build: src/ai-service - container_name: 'aiservice' + container_name: 'ai-service' restart: always ports: - 5001:5001 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://aiservice:5001/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://ai-service:5001/health"] interval: 30s timeout: 10s retries: 5 diff --git a/infra/azd-hooks/postprovision.sh b/infra/azd-hooks/postprovision.sh deleted file mode 100755 index f1fd3ca5..00000000 --- a/infra/azd-hooks/postprovision.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -echo "Retrieving cluster credentials" -az aks get-credentials --resource-group ${rg_name} --name ${aks_name} - -# echo "Deploy the manifests" -# kubectl apply -f manifests/ - -echo "Deploy Helm chart" -helm upgrade aks-store-demo ./charts/aks-store-demo \ - --install \ - --set aiService.create=true \ - --set aiService.modelDeploymentName=${ai_model_name} \ - --set aiService.openAiEndpoint=${ai_endpoint} \ - --set aiService.managedIdentityClientId=${ai_managed_identity_client_id} \ - --set orderService.useAzureServiceBus=true \ - --set orderService.queueHost=${sb_namespace_host} \ - --set orderService.queuePort=5671 \ - --set orderService.queueUsername=${sb_sender_username} \ - --set orderService.queuePassword=${sb_sender_key} \ - --set orderService.queueTransport=tls \ - --set makelineService.useAzureCosmosDB=true \ - --set makelineService.orderQueueUri=${sb_namespace_uri} \ - --set makelineService.orderQueueUsername=${sb_listener_username} \ - --set makelineService.orderQueuePassword=${sb_listener_key} \ - --set makelineService.orderDBUri=${db_uri} \ - --set makelineService.orderDBUsername=${db_account_name} \ - --set makelineService.orderDBPassword=${db_key} \ - \ No newline at end of file diff --git a/infra/azd-hooks/predeploy.sh b/infra/azd-hooks/predeploy.sh new file mode 100755 index 00000000..709d7bb8 --- /dev/null +++ b/infra/azd-hooks/predeploy.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +echo "Build container images" +az acr build --registry ${registry_name} --image aks-store-demo/ai-service:latest ./src/ai-service/ +az acr build --registry ${registry_name} --image aks-store-demo/makeline-service:latest ./src/makeline-service/ +az acr build --registry ${registry_name} --image aks-store-demo/order-service:latest ./src/order-service/ +az acr build --registry ${registry_name} --image aks-store-demo/product-service:latest ./src/product-service/ +az acr build --registry ${registry_name} --image aks-store-demo/store-admin:latest ./src/store-admin/ +az acr build --registry ${registry_name} --image aks-store-demo/store-front:latest ./src/store-front/ +az acr build --registry ${registry_name} --image aks-store-demo/virtual-customer:latest ./src/virtual-customer/ +az acr build --registry ${registry_name} --image aks-store-demo/virtual-worker:latest ./src/virtual-worker/ + +echo "Retrieving cluster credentials" +az aks get-credentials --resource-group ${rg_name} --name ${aks_name} + +echo "Deploy Helm chart" +helm upgrade aks-store-demo ./charts/aks-store-demo \ + --install \ + --set aiService.create=true \ + --set aiService.modelDeploymentName=${ai_model_name} \ + --set aiService.openAiEndpoint=${ai_endpoint} \ + --set aiService.managedIdentityClientId=${ai_managed_identity_client_id} \ + --set aiService.image.repository=${registry_uri}/aks-store-demo/ai-service \ + --set orderService.useAzureServiceBus=true \ + --set orderService.queueHost=${sb_namespace_host} \ + --set orderService.queuePort=5671 \ + --set orderService.queueUsername=${sb_sender_username} \ + --set orderService.queuePassword=${sb_sender_key} \ + --set orderService.queueTransport=tls \ + --set orderService.image.repository=${registry_uri}/aks-store-demo/order-service \ + --set makelineService.useAzureCosmosDB=true \ + --set makelineService.orderQueueUri=${sb_namespace_uri} \ + --set makelineService.orderQueueUsername=${sb_listener_username} \ + --set makelineService.orderQueuePassword=${sb_listener_key} \ + --set makelineService.orderDBUri=${db_uri} \ + --set makelineService.orderDBUsername=${db_account_name} \ + --set makelineService.orderDBPassword=${db_key} \ + --set makelineService.image.repository=${registry_uri}/aks-store-demo/makeline-service \ + --set productService.image.repository=${registry_uri}/aks-store-demo/product-service \ + --set storeAdmin.image.repository=${registry_uri}/aks-store-demo/store-admin \ + --set storeFront.image.repository=${registry_uri}/aks-store-demo/store-front \ + --set virtualCustomer.image.repository=${registry_uri}/aks-store-demo/virtual-customer \ + --set virtualWorker.image.repository=${registry_uri}/aks-store-demo/virtual-worker diff --git a/infra/kubernetes.tf b/infra/kubernetes.tf index 47255a3c..e232f680 100644 --- a/infra/kubernetes.tf +++ b/infra/kubernetes.tf @@ -1,3 +1,10 @@ +resource "azurerm_container_registry" "example" { + name = "acr${local.name}" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Premium" +} + resource "azurerm_kubernetes_cluster" "example" { name = "aks-${local.name}" location = azurerm_resource_group.example.location @@ -24,4 +31,11 @@ resource "azurerm_kubernetes_cluster" "example" { microsoft_defender ] } +} + +resource "azurerm_role_assignment" "example" { + principal_id = azurerm_kubernetes_cluster.example.kubelet_identity[0].object_id + role_definition_name = "AcrPull" + scope = azurerm_container_registry.example.id + skip_service_principal_aad_check = true } \ No newline at end of file diff --git a/infra/outputs.tf b/infra/outputs.tf index 52ed2216..83d387ca 100644 --- a/infra/outputs.tf +++ b/infra/outputs.tf @@ -65,4 +65,12 @@ output "db_key" { output "k8s_namespace" { value = var.k8s_namespace +} + +output "registry_name" { + value = azurerm_container_registry.example.name +} + +output "registry_uri" { + value = azurerm_container_registry.example.login_server } \ No newline at end of file diff --git a/src/makeline-service/README.md b/src/makeline-service/README.md index 032d2f89..9ab8cf18 100644 --- a/src/makeline-service/README.md +++ b/src/makeline-service/README.md @@ -65,7 +65,7 @@ export ORDER_QUEUE_PASSWORD=$PASSWORD export ORDER_QUEUE_NAME=orders ``` -> NOTE: If you are using Azure Service Bus, you will want your `order-service` to write orders to it instead of RabbitMQ. If that is the case, then you'll need to update the [`docker-compose.yml`](./docker-compose.yml) and modify the environment variables for the `orderservice` to include the proper connection info to connect to Azure Service Bus. Also you will need to add the `ORDER_QUEUE_TRANSPORT=tls` configuration to connect over TLS. +> NOTE: If you are using Azure Service Bus, you will want your `order-service` to write orders to it instead of RabbitMQ. If that is the case, then you'll need to update the [`docker-compose.yml`](./docker-compose.yml) and modify the environment variables for the `order-service` to include the proper connection info to connect to Azure Service Bus. Also you will need to add the `ORDER_QUEUE_TRANSPORT=tls` configuration to connect over TLS. ## Database options diff --git a/src/makeline-service/docker-compose.yml b/src/makeline-service/docker-compose.yml index d72589a9..5a92881b 100644 --- a/src/makeline-service/docker-compose.yml +++ b/src/makeline-service/docker-compose.yml @@ -32,14 +32,14 @@ services: - ../../rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: ../order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -55,17 +55,17 @@ services: depends_on: rabbitmq: condition: service_healthy - virtualcustomer: + virtual-customer: build: ../virtual-customer - container_name: 'virtualcustomer' + container_name: 'virtual-customer' restart: always environment: - - ORDER_SERVICE_URL=http://orderservice:3000/ + - ORDER_SERVICE_URL=http://order-service:3000/ - ORDERS_PER_HOUR=60 networks: - backend_services depends_on: - orderservice: + order-service: condition: service_healthy networks: backend_services: diff --git a/src/product-service/Cargo.lock b/src/product-service/Cargo.lock index de9bb6b2..60bbc79a 100644 --- a/src/product-service/Cargo.lock +++ b/src/product-service/Cargo.lock @@ -8,7 +8,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-sink", @@ -46,7 +46,7 @@ dependencies = [ "actix-utils", "ahash 0.8.3", "base64", - "bitflags", + "bitflags 1.3.2", "brotli", "bytes", "bytestring", @@ -269,6 +269,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "block-buffer" version = "0.10.4" @@ -299,6 +305,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "bytes" version = "1.4.0" @@ -346,6 +358,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.7" @@ -433,7 +461,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -446,6 +474,12 @@ dependencies = [ "libc", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "flate2" version = "1.0.26" @@ -462,6 +496,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -471,6 +520,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.28" @@ -586,6 +644,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -604,6 +673,43 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "idna" version = "0.4.0" @@ -632,9 +738,15 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.7" @@ -643,8 +755,8 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix", - "windows-sys", + "rustix 0.37.25", + "windows-sys 0.48.0", ] [[package]] @@ -662,12 +774,27 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "language-tags" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.146" @@ -680,6 +807,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "local-channel" version = "0.1.3" @@ -744,7 +877,25 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -763,6 +914,50 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -783,7 +978,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -839,6 +1034,7 @@ dependencies = [ "actix-web", "env_logger", "futures-util", + "reqwest", "serde", "serde_json", ] @@ -888,7 +1084,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -908,6 +1104,44 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rustc_version" version = "0.4.0" @@ -923,12 +1157,25 @@ version = "0.37.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.48.0", ] [[package]] @@ -937,12 +1184,44 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.17" @@ -1059,6 +1338,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix 0.38.3", + "windows-sys 0.48.0", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -1124,7 +1437,17 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ] [[package]] @@ -1141,6 +1464,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -1162,6 +1491,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.16.0" @@ -1200,18 +1535,109 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1249,7 +1675,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -1258,13 +1693,28 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1273,42 +1723,94 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "zstd" version = "0.12.3+zstd.1.5.2" diff --git a/src/product-service/Cargo.toml b/src/product-service/Cargo.toml index 482ecd2a..1cb1e8f5 100644 --- a/src/product-service/Cargo.toml +++ b/src/product-service/Cargo.toml @@ -10,5 +10,6 @@ actix-cors = "0.6.4" actix-web = "4.3.1" env_logger = "0.10.0" futures-util = "0.3.28" +reqwest = { version = "0.11.23", features = ["json"] } serde = { version = "1.0.164", features = ["derive"] } serde_json = "1.0.96" diff --git a/src/product-service/src/main.rs b/src/product-service/src/main.rs index d00577db..9b59b4e0 100644 --- a/src/product-service/src/main.rs +++ b/src/product-service/src/main.rs @@ -1,10 +1,14 @@ use actix_cors::Cors; use actix_web::middleware::Logger; -use actix_web::{error, middleware, web, App, Error, HttpResponse, HttpServer}; +use actix_web::{ + error, error::ResponseError, middleware, web, App, Error, HttpResponse, HttpServer, +}; use env_logger::Env; use futures_util::StreamExt; use serde::{Deserialize, Serialize}; use serde_json::json; +use std::collections::HashMap; +use std::fmt; use std::sync::Mutex; const MAX_SIZE: usize = 262_144; // max payload size is 256k @@ -110,6 +114,73 @@ async fn delete_product( Ok(HttpResponse::Ok().body("")) } +////////////////////////// +// Proxy for AI service +////////////////////////// + +#[derive(Debug)] +struct ProxyError(reqwest::Error); + +impl fmt::Display for ProxyError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl ResponseError for ProxyError { + fn error_response(&self) -> HttpResponse { + HttpResponse::InternalServerError().json(self.0.to_string()) + } +} + +impl From for ProxyError { + fn from(err: reqwest::Error) -> ProxyError { + ProxyError(err) + } +} + +fn get_ai_service_url() -> String { + let ai_service_url = std::env::var("AI_SERVICE_URL").unwrap_or_else(|_| "http://127.0.0.1:5001".to_string()); + ai_service_url.trim_end_matches('/').to_string() +} + +async fn ai_health() -> Result { + let client = reqwest::Client::new(); + let resp = client.get(get_ai_service_url() + "/health").send().await.unwrap(); + let status = resp.status(); + if status.is_success() { + let body: HashMap = resp.json().await.map_err(ProxyError::from)?; + let body_json = serde_json::to_string(&body).unwrap(); + Ok(HttpResponse::Ok().body(body_json)) + } else { + Ok(HttpResponse::build(actix_web::http::StatusCode::NOT_FOUND).body("")) + } +} + +async fn ai_generate_description(mut payload: web::Payload) -> Result { + let mut body = web::BytesMut::new(); + while let Some(chunk) = payload.next().await { + let chunk = chunk?; + body.extend_from_slice(&chunk); + } + let client = reqwest::Client::new(); + let resp = client + .post(get_ai_service_url() + "/generate/description") + .body(body.to_vec()) + .send() + .await + .unwrap(); + + let status = resp.status(); + let body: HashMap = resp.json().await.map_err(ProxyError::from)?; + let body_json = serde_json::to_string(&body).unwrap(); + if status.is_success() { + Ok(HttpResponse::Ok().body(body_json)) + } else { + Ok(HttpResponse::build(actix_web::http::StatusCode::INTERNAL_SERVER_ERROR).body(body_json)) + } +} + #[actix_web::main] async fn main() -> std::io::Result<()> { let products = vec![ @@ -209,6 +280,12 @@ async fn main() -> std::io::Result<()> { .route("/", web::post().to(add_product)) .route("/", web::put().to(update_product)) .route("/{product_id}", web::delete().to(delete_product)) + .route("/ai/health", web::get().to(ai_health)) + .route("/ai/health", web::head().to(ai_health)) + .route( + "/ai/generate/description", + web::post().to(ai_generate_description), + ) }) .bind(("0.0.0.0", 3002))? .run() diff --git a/src/product-service/test-product-service.http b/src/product-service/test-product-service.http index 5f0a540d..d842f5f5 100644 --- a/src/product-service/test-product-service.http +++ b/src/product-service/test-product-service.http @@ -38,4 +38,19 @@ Host: localhost:3002 ### Delete product by id DELETE /11 -Host: localhost:3002 \ No newline at end of file +Host: localhost:3002 + +### Get ai service health +GET /ai/health +Host: localhost:3002 + +### Get product description from ai service +POST /ai/generate/description +Host: localhost:3002 +Content-Type: application/json + +{ + "name": "Seafarer's Tug Rope", + "tags": ["toy","dog"] +} + diff --git a/src/store-admin/Dockerfile b/src/store-admin/Dockerfile index 6f52b8d9..1d7cb718 100644 --- a/src/store-admin/Dockerfile +++ b/src/store-admin/Dockerfile @@ -3,9 +3,6 @@ FROM node:18.16.0-alpine as builder WORKDIR /app -# Set the build argument for the app version number -ARG APP_VERSION=0.1.0 - # Copy package.json and package-lock.json to the container COPY package*.json ./ @@ -15,24 +12,26 @@ RUN npm install # Copy the rest of the app source code to the container COPY . . -# Expose the port the app listens on -EXPOSE 80 +# Build the app +RUN npm run build -# Set the environment variable for the app version number -ENV APP_VERSION=$APP_VERSION +# Run the app on nginx +FROM nginx:stable-alpine as runner -# Start the app -CMD [ "npm", "run", "serve" ] +# Copy the build output to replace the default nginx contents +COPY --from=builder /app/dist /usr/share/nginx/html -# # Build the app -# RUN npm run build --mode production +# Expose the port the app listens on +EXPOSE 8081 -# # Run the app on nginx -# FROM nginx:stable-alpine as runner -# WORKDIR /app +# Set the build argument for the app version number +ARG APP_VERSION=0.1.0 -# # Copy the build output to replace the default nginx contents -# COPY --from=builder /app/dist /app +# Set the environment variable for the app version number +ENV APP_VERSION=$APP_VERSION + +# Copy the nginx configuration template to the container +COPY nginx.conf /etc/nginx/conf.d/nginx.conf.template -# # Copy the nginx configuration -# COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file +# Start the app +CMD ["sh", "-c", "envsubst '${APP_VERSION}' < /etc/nginx/conf.d/nginx.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"] diff --git a/src/store-admin/README.md b/src/store-admin/README.md index cc60b1e8..3307426b 100644 --- a/src/store-admin/README.md +++ b/src/store-admin/README.md @@ -18,7 +18,7 @@ The app relies on the [product-service](../product-service), [makeline-service]( To run the necessary services, clone the repo, open a terminal, and navigate to the `store-admin` directory. -If you have access to OpenAI or Azure OpenAI, open the `docker-compose.yml` file, uncomment the `aiservices` block, and add your OpenAI or Azure OpenAI credentials. +If you have access to OpenAI or Azure OpenAI, open the `docker-compose.yml` file, uncomment the `ai-services` block, and add your OpenAI or Azure OpenAI credentials. > IMPORTANT: When filling in the values, do not put the value in double-quotes. @@ -42,7 +42,6 @@ With the services running, open a new terminal and navigate to the `store-admin` ```bash export VUE_APP_PRODUCT_SERVICE_URL=http://localhost:3002/ export VUE_APP_MAKELINE_SERVICE_URL=http://localhost:3001/ -export VUE_APP_AI_SERVICE_URL=http://localhost:5001/ npm install npm run serve diff --git a/src/store-admin/docker-compose.yml b/src/store-admin/docker-compose.yml index 0bd33fec..a0fbe347 100644 --- a/src/store-admin/docker-compose.yml +++ b/src/store-admin/docker-compose.yml @@ -32,14 +32,14 @@ services: - ../../rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: ../order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -55,14 +55,14 @@ services: depends_on: rabbitmq: condition: service_healthy - makelineservice: + makeline-service: build: ../makeline-service - container_name: 'makelineservice' + container_name: 'makeline-service' restart: always ports: - 3001:3001 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makelineservice:3001/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makeline-service:3001/health"] interval: 30s timeout: 10s retries: 5 @@ -81,39 +81,39 @@ services: condition: service_healthy mongodb: condition: service_healthy - productservice: + product-service: build: ../product-service - container_name: 'productservice' + container_name: 'product-service' restart: always ports: - 3002:3002 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://productservice:3002/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://product-service:3002/health"] interval: 30s timeout: 10s retries: 5 networks: - backend_services - virtualcustomer: + virtual-customer: build: ../virtual-customer - container_name: 'virtualcustomer' + container_name: 'virtual-customer' restart: always environment: - - ORDER_SERVICE_URL=http://orderservice:3000/ + - ORDER_SERVICE_URL=http://order-service:3000/ - ORDERS_PER_HOUR=3600 networks: - backend_services depends_on: - orderservice: + order-service: condition: service_healthy - # aiservice: + # ai-service: # build: ../ai-service - # container_name: 'aiservice' + # container_name: 'ai-service' # restart: always # ports: # - 5001:5001 # healthcheck: - # test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://aiservice:5001/health"] + # test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://ai-service:5001/health"] # interval: 30s # timeout: 10s # retries: 5 diff --git a/src/store-admin/nginx.conf b/src/store-admin/nginx.conf index 57e735ad..51bb45d5 100644 --- a/src/store-admin/nginx.conf +++ b/src/store-admin/nginx.conf @@ -1,32 +1,78 @@ -# Ref: https://cli.vuejs.org/guide/deployment.html#docker-nginx - -user nginx; -worker_processes 1; -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; -events { - worker_connections 1024; -} -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - sendfile on; - keepalive_timeout 65; - server { - listen 80; +server { + listen 8081; + listen [::]:8081; server_name localhost; + + #access_log /var/log/nginx/host.access.log main; + location / { - root /app; - index index.html; - try_files $uri $uri/ /index.html; + root /usr/share/nginx/html; + index index.html index.htm; } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # error_page 500 502 503 504 /50x.html; location = /50x.html { - root /usr/share/nginx/html; + root /usr/share/nginx/html; + } + + location /health { + default_type application/json; + return 200 '{"status":"ok","version":"${APP_VERSION}"}'; + } + + location ~ ^/makeline/order/(?\w+) { + proxy_pass http://makeline-service:3001/order/$id; + } + + location /makeline/order { + proxy_pass http://makeline-service:3001/order; + } + + location /makeline/order/fetch { + proxy_pass http://makeline-service:3001/order/fetch; + } + + location /order { + proxy_pass http://order-service:3000/; + } + + location /products/ { + proxy_pass http://product-service:3002/; + } + + location /products { + proxy_pass http://product-service:3002/; + } + + # location ~* ^/products { + # proxy_pass http://product-service:3002/; + # } + + location ~ ^/product/(?\w+) { + proxy_pass http://product-service:3002/$id; + } + + # location ~* ^/product { + # proxy_pass http://product-service:3002/; + # } + + location /product { + proxy_pass http://product-service:3002/; + } + + location /product/ { + proxy_pass http://product-service:3002/; + } + + location /ai/health { + proxy_pass http://product-service:3002/ai/health; + } + + location /ai/generate/description { + proxy_pass http://product-service:3002/ai/generate/description; } - } } \ No newline at end of file diff --git a/src/store-admin/vue.config.js b/src/store-admin/vue.config.js index 0fe86299..9d67e20d 100644 --- a/src/store-admin/vue.config.js +++ b/src/store-admin/vue.config.js @@ -4,7 +4,6 @@ const bodyParser = require('body-parser') const PRODUCT_SERVICE_URL = (process.env.VUE_APP_PRODUCT_SERVICE_URL || "http://172.19.0.2:3002/") const MAKELINE_SERVICE_URL = (process.env.VUE_APP_MAKELINE_SERVICE_URL || "http://172.19.0.6:3001/") -const AI_SERVICE_URL = (process.env.VUE_APP_AI_SERVICE_URL || "http://172.19.0.6:5001/") module.exports = defineConfig({ transpileDependencies: true, @@ -141,7 +140,7 @@ module.exports = defineConfig({ // Get AI service health devServer.app.get('/ai/health', (_, res) => { - fetch(`${AI_SERVICE_URL}health`) + fetch(`${PRODUCT_SERVICE_URL}/ai/health`) .then(response => { if (response.status === 200) { res.send(response.json()); @@ -161,7 +160,7 @@ module.exports = defineConfig({ const product = req.body console.log(product) - fetch(`${AI_SERVICE_URL}generate/description`, { + fetch(`${PRODUCT_SERVICE_URL}/ai/generate/description`, { method: 'POST', body: JSON.stringify(product), headers: { 'Content-Type': 'application/json' } diff --git a/src/store-front/Dockerfile b/src/store-front/Dockerfile index 6f52b8d9..76208391 100644 --- a/src/store-front/Dockerfile +++ b/src/store-front/Dockerfile @@ -3,9 +3,6 @@ FROM node:18.16.0-alpine as builder WORKDIR /app -# Set the build argument for the app version number -ARG APP_VERSION=0.1.0 - # Copy package.json and package-lock.json to the container COPY package*.json ./ @@ -15,24 +12,26 @@ RUN npm install # Copy the rest of the app source code to the container COPY . . -# Expose the port the app listens on -EXPOSE 80 +# Build the app +RUN npm run build -# Set the environment variable for the app version number -ENV APP_VERSION=$APP_VERSION +# Run the app on nginx +FROM nginx:stable-alpine as runner -# Start the app -CMD [ "npm", "run", "serve" ] +# Copy the build output to replace the default nginx contents +COPY --from=builder /app/dist /usr/share/nginx/html -# # Build the app -# RUN npm run build --mode production +# Expose the port the app listens on +EXPOSE 8080 -# # Run the app on nginx -# FROM nginx:stable-alpine as runner -# WORKDIR /app +# Set the build argument for the app version number +ARG APP_VERSION=0.1.0 -# # Copy the build output to replace the default nginx contents -# COPY --from=builder /app/dist /app +# Set the environment variable for the app version number +ENV APP_VERSION=$APP_VERSION + +# Copy the nginx configuration template to the container +COPY nginx.conf /etc/nginx/conf.d/nginx.conf.template -# # Copy the nginx configuration -# COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file +# Start the app +CMD ["sh", "-c", "envsubst '${APP_VERSION}' < /etc/nginx/conf.d/nginx.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"] diff --git a/src/store-front/docker-compose.yml b/src/store-front/docker-compose.yml index 5e3cb214..b5dd1769 100644 --- a/src/store-front/docker-compose.yml +++ b/src/store-front/docker-compose.yml @@ -19,14 +19,14 @@ services: - ../../rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: ../order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -42,14 +42,14 @@ services: depends_on: rabbitmq: condition: service_healthy - productservice: + product-service: build: ../product-service - container_name: 'productservice' + container_name: 'product-service' restart: always ports: - 3002:3002 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://productservice:3002/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://product-service:3002/health"] interval: 30s timeout: 10s retries: 5 diff --git a/src/store-front/nginx.conf b/src/store-front/nginx.conf index 57e735ad..2a823203 100644 --- a/src/store-front/nginx.conf +++ b/src/store-front/nginx.conf @@ -1,32 +1,34 @@ -# Ref: https://cli.vuejs.org/guide/deployment.html#docker-nginx - -user nginx; -worker_processes 1; -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; -events { - worker_connections 1024; -} -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - sendfile on; - keepalive_timeout 65; - server { - listen 80; +server { + listen 8080; + listen [::]:8080; server_name localhost; + + #access_log /var/log/nginx/host.access.log main; + location / { - root /app; - index index.html; - try_files $uri $uri/ /index.html; + root /usr/share/nginx/html; + index index.html index.htm; } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # error_page 500 502 503 504 /50x.html; location = /50x.html { - root /usr/share/nginx/html; + root /usr/share/nginx/html; + } + + location /health { + default_type application/json; + return 200 '{"status":"ok","version":"${APP_VERSION}"}'; + } + + location /order { + proxy_pass http://order-service:3000/; + } + + location /products { + proxy_pass http://product-service:3002/; } - } } \ No newline at end of file diff --git a/src/virtual-customer/docker-compose.yml b/src/virtual-customer/docker-compose.yml index 2f43a5fa..e686f79c 100644 --- a/src/virtual-customer/docker-compose.yml +++ b/src/virtual-customer/docker-compose.yml @@ -19,14 +19,14 @@ services: - ../../rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: ../order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 diff --git a/src/virtual-worker/docker-compose.yml b/src/virtual-worker/docker-compose.yml index 61fb6734..d16db15f 100644 --- a/src/virtual-worker/docker-compose.yml +++ b/src/virtual-worker/docker-compose.yml @@ -32,14 +32,14 @@ services: - ../../rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins networks: - backend_services - orderservice: + order-service: build: ../order-service - container_name: 'orderservice' + container_name: 'order-service' restart: always ports: - 3000:3000 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://order-service:3000/health"] interval: 30s timeout: 10s retries: 5 @@ -55,14 +55,14 @@ services: depends_on: rabbitmq: condition: service_healthy - makelineservice: + makeline-service: build: ../makeline-service - container_name: 'makelineservice' + container_name: 'makeline-service' restart: always ports: - 3001:3001 healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makelineservice:3001/health"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://makeline-service:3001/health"] interval: 30s timeout: 10s retries: 5 @@ -81,17 +81,17 @@ services: condition: service_healthy mongodb: condition: service_healthy - virtualcustomer: + virtual-customer: build: ../virtual-customer - container_name: 'virtualcustomer' + container_name: 'virtual-customer' restart: always environment: - - ORDER_SERVICE_URL=http://orderservice:3000/ + - ORDER_SERVICE_URL=http://order-service:3000/ - ORDERS_PER_HOUR=3600 networks: - backend_services depends_on: - orderservice: + order-service: condition: service_healthy networks: backend_services: From c01d524c3141592b75541d7c1c7467c3dd1712d2 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Wed, 6 Dec 2023 18:29:06 -0800 Subject: [PATCH 2/9] feat: add support for cosmosdb sql api --- README.md | 6 +++ azure.yaml | 5 +++ .../templates/makeline-service.yaml | 7 +++ charts/aks-store-demo/values.yaml | 2 + infra/azd-hooks/postprovision.sh | 11 +++++ infra/azd-hooks/predeploy.sh | 13 +----- infra/cosmosdb.tf | 44 ++++++++++++------- infra/main.tf | 2 + infra/main.tfvars.json | 3 +- infra/outputs.tf | 6 ++- infra/variables.tf | 14 +++++- 11 files changed, 83 insertions(+), 30 deletions(-) create mode 100755 infra/azd-hooks/postprovision.sh diff --git a/README.md b/README.md index 014b7b8d..a3e41bc0 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,12 @@ azd auth login az login ``` +The `makeline-service` supports both MongoDB and SQL API for accessing data in Azure CosmosDB. The default API is MongoDB, but you can use SQL API. To use the SQL API for Azure CosmosDB, you must provision the service using the `GlobalDocumentDB` account kind. You can set the Azure CosmosDB account kind by running the following command prior to running `azd up`: + +```bash +azd env set AZURE_COSMOSDB_ACCOUNT_KIND GlobalDocumentDB +``` + Deploy the app with a single command. ```bash diff --git a/azure.yaml b/azure.yaml index a4555290..2c7fd43b 100644 --- a/azure.yaml +++ b/azure.yaml @@ -9,6 +9,11 @@ hooks: continueOnError: false interactive: false run: infra/azd-hooks/preprovision.sh + postprovision: + shell: sh + continueOnError: false + interactive: false + run: infra/azd-hooks/postprovision.sh predeploy: shell: sh continueOnError: false diff --git a/charts/aks-store-demo/templates/makeline-service.yaml b/charts/aks-store-demo/templates/makeline-service.yaml index ad1f1f8d..79ce503f 100644 --- a/charts/aks-store-demo/templates/makeline-service.yaml +++ b/charts/aks-store-demo/templates/makeline-service.yaml @@ -9,7 +9,14 @@ data: ORDER_QUEUE_NAME: "{{ .Values.makelineService.orderQueueName }}" ORDER_DB_URI: "{{ .Values.makelineService.orderDBUri }}" ORDER_DB_NAME: "{{ .Values.makelineService.orderDBName }}" + {{- if eq .Values.makelineService.useSqlApi true }} + ORDER_DB_API: cosmosdbsql + ORDER_DB_CONTAINER_NAME: "{{ .Values.makelineService.orderDBContainerName }}" + ORDER_DB_PARTITION_KEY: "storeId" + ORDER_DB_PARTITION_VALUE: "pets" + {{- else }} ORDER_DB_COLLECTION_NAME: "{{ .Values.makelineService.orderDBCollectionName }}" + {{- end }} --- {{- if and .Values.makelineService.orderDBUsername .Values.makelineService.orderDBPassword }} apiVersion: v1 diff --git a/charts/aks-store-demo/values.yaml b/charts/aks-store-demo/values.yaml index 90b42c6b..0f8e65f3 100644 --- a/charts/aks-store-demo/values.yaml +++ b/charts/aks-store-demo/values.yaml @@ -34,6 +34,7 @@ orderService: makelineService: useAzureCosmosDB: false # when false, local mongodb will be used + useSqlApi: false # when false, mongodb api for azure cosmosdb will be used orderQueueUri: "amqp://rabbitmq:5672" orderQueueUsername: "username" orderQueuePassword: "password" @@ -41,6 +42,7 @@ makelineService: orderDBUri: "mongodb://mongodb:27017" orderDBName: "orderdb" orderDBCollectionName: "orders" + orderDBContainerName: "orders" orderDBUsername: "" orderDBPassword: "" image: diff --git a/infra/azd-hooks/postprovision.sh b/infra/azd-hooks/postprovision.sh new file mode 100755 index 00000000..76a4a266 --- /dev/null +++ b/infra/azd-hooks/postprovision.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "Build container images" +az acr build --registry ${registry_name} --image aks-store-demo/ai-service:latest ./src/ai-service/ +az acr build --registry ${registry_name} --image aks-store-demo/makeline-service:latest ./src/makeline-service/ +az acr build --registry ${registry_name} --image aks-store-demo/order-service:latest ./src/order-service/ +az acr build --registry ${registry_name} --image aks-store-demo/product-service:latest ./src/product-service/ +az acr build --registry ${registry_name} --image aks-store-demo/store-admin:latest ./src/store-admin/ +az acr build --registry ${registry_name} --image aks-store-demo/store-front:latest ./src/store-front/ +az acr build --registry ${registry_name} --image aks-store-demo/virtual-customer:latest ./src/virtual-customer/ +az acr build --registry ${registry_name} --image aks-store-demo/virtual-worker:latest ./src/virtual-worker/ diff --git a/infra/azd-hooks/predeploy.sh b/infra/azd-hooks/predeploy.sh index 709d7bb8..600e485b 100755 --- a/infra/azd-hooks/predeploy.sh +++ b/infra/azd-hooks/predeploy.sh @@ -1,15 +1,5 @@ #!/bin/bash -echo "Build container images" -az acr build --registry ${registry_name} --image aks-store-demo/ai-service:latest ./src/ai-service/ -az acr build --registry ${registry_name} --image aks-store-demo/makeline-service:latest ./src/makeline-service/ -az acr build --registry ${registry_name} --image aks-store-demo/order-service:latest ./src/order-service/ -az acr build --registry ${registry_name} --image aks-store-demo/product-service:latest ./src/product-service/ -az acr build --registry ${registry_name} --image aks-store-demo/store-admin:latest ./src/store-admin/ -az acr build --registry ${registry_name} --image aks-store-demo/store-front:latest ./src/store-front/ -az acr build --registry ${registry_name} --image aks-store-demo/virtual-customer:latest ./src/virtual-customer/ -az acr build --registry ${registry_name} --image aks-store-demo/virtual-worker:latest ./src/virtual-worker/ - echo "Retrieving cluster credentials" az aks get-credentials --resource-group ${rg_name} --name ${aks_name} @@ -40,4 +30,5 @@ helm upgrade aks-store-demo ./charts/aks-store-demo \ --set storeAdmin.image.repository=${registry_uri}/aks-store-demo/store-admin \ --set storeFront.image.repository=${registry_uri}/aks-store-demo/store-front \ --set virtualCustomer.image.repository=${registry_uri}/aks-store-demo/virtual-customer \ - --set virtualWorker.image.repository=${registry_uri}/aks-store-demo/virtual-worker + --set virtualWorker.image.repository=${registry_uri}/aks-store-demo/virtual-worker \ + $(if [ "${db_api}" == "cosmosdbsql" ]; then echo "--set makelineService.useSqlApi=true"; fi) diff --git a/infra/cosmosdb.tf b/infra/cosmosdb.tf index e7839b92..dac324ef 100644 --- a/infra/cosmosdb.tf +++ b/infra/cosmosdb.tf @@ -3,24 +3,15 @@ resource "azurerm_cosmosdb_account" "example" { location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name offer_type = "Standard" - kind = "MongoDB" + kind = local.cosmosdb_account_kind enable_automatic_failover = false - capabilities { - name = "EnableAggregationPipeline" - } - - capabilities { - name = "mongoEnableDocLevelTTL" - } - - capabilities { - name = "MongoDBv3.4" - } - - capabilities { - name = "EnableMongo" + dynamic "capabilities" { + for_each = var.cosmosdb_account_kind == "MongoDB" ? ["EnableAggregationPipeline", "mongoEnableDocLevelTTL", "MongoDBv3.4", "EnableMongo"] : ["EnableAggregationPipeline"] + content { + name = "${capabilities.value}" + } } consistency_policy { @@ -41,6 +32,7 @@ resource "azurerm_cosmosdb_account" "example" { } resource "azurerm_cosmosdb_mongo_database" "example" { + count = var.cosmosdb_account_kind == "MongoDB" ? 1 : 0 name = "orderdb" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name @@ -48,14 +40,34 @@ resource "azurerm_cosmosdb_mongo_database" "example" { } resource "azurerm_cosmosdb_mongo_collection" "example" { + count = var.cosmosdb_account_kind == "MongoDB" ? 1 : 0 name = "orders" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name - database_name = azurerm_cosmosdb_mongo_database.example.name + database_name = azurerm_cosmosdb_mongo_database.example[0].name throughput = 400 index { keys = ["_id"] unique = true } +} + +resource "azurerm_cosmosdb_sql_database" "example" { + count = var.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 + name = "orderdb" + resource_group_name = azurerm_cosmosdb_account.example.resource_group_name + account_name = azurerm_cosmosdb_account.example.name + throughput = 400 +} + +resource "azurerm_cosmosdb_sql_container" "example" { + count = var.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 + name = "orders" + resource_group_name = azurerm_cosmosdb_account.example.resource_group_name + account_name = azurerm_cosmosdb_account.example.name + database_name = azurerm_cosmosdb_sql_database.example[0].name + partition_key_path = "/storeId" + partition_key_version = 1 + throughput = 400 } \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf index b2f27ae3..5d1ed0d0 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -45,6 +45,8 @@ resource "random_pet" "example" { locals { name = "${random_pet.example.id}${random_integer.example.result}" location = var.location + default_cosmosdb_account_kind = "MongoDB" + cosmosdb_account_kind = var.cosmosdb_account_kind != "" ? var.cosmosdb_account_kind : local.default_cosmosdb_account_kind } data "azurerm_subscription" "current" {} diff --git a/infra/main.tfvars.json b/infra/main.tfvars.json index 9618150e..0cc267be 100644 --- a/infra/main.tfvars.json +++ b/infra/main.tfvars.json @@ -1,4 +1,5 @@ { "location": "${AZURE_LOCATION}", - "ai_location": "${AZURE_LOCATION}" + "ai_location": "${AZURE_LOCATION}", + "cosmosdb_account_kind": "${AZURE_COSMOSDB_ACCOUNT_KIND}" } \ No newline at end of file diff --git a/infra/outputs.tf b/infra/outputs.tf index 83d387ca..1a053c51 100644 --- a/infra/outputs.tf +++ b/infra/outputs.tf @@ -54,8 +54,12 @@ output "db_account_name" { value = azurerm_cosmosdb_account.example.name } +output "db_api" { + value = var.cosmosdb_account_kind == "MongoDB" ? "mongodb" : "cosmosdbsql" +} + output "db_uri" { - value = "mongodb://${azurerm_cosmosdb_account.example.name}.mongo.cosmos.azure.com:10255/?retryWrites=false" + value = var.cosmosdb_account_kind == "MongoDB" ? "mongodb://${azurerm_cosmosdb_account.example.name}.mongo.cosmos.azure.com:10255/?retryWrites=false" : "https://${azurerm_cosmosdb_account.example.name}.documents.azure.com:443/" } output "db_key" { diff --git a/infra/variables.tf b/infra/variables.tf index f9d5e04b..67501425 100644 --- a/infra/variables.tf +++ b/infra/variables.tf @@ -28,4 +28,16 @@ variable "k8s_namespace" { description = "value of kubernetes namespace" type = string default = "default" -} \ No newline at end of file +} + +variable "cosmosdb_account_kind" { + description = "value of cosmosdb account kind" + type = string + default = "MongoDB" + + validation { + condition = contains(["MongoDB", "GlobalDocumentDB"], var.cosmosdb_account_kind) + error_message = "Valid values for var: cosmosdb_account_kind are (MongoDB, GlobalDocumentDB)." + } +} + From a47ad4c3850698ff2af892ce2a6f46f4f75a017d Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Mon, 22 Jan 2024 09:26:14 -0800 Subject: [PATCH 3/9] fix: consolidating helm values map keys for store apps --- charts/aks-store-demo/values.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/charts/aks-store-demo/values.yaml b/charts/aks-store-demo/values.yaml index 0f8e65f3..90bc469b 100644 --- a/charts/aks-store-demo/values.yaml +++ b/charts/aks-store-demo/values.yaml @@ -58,11 +58,13 @@ storeAdmin: image: repository: "ghcr.io/azure-samples/aks-store-demo/store-admin" tag: "latest" + serviceType: LoadBalancer storeFront: image: repository: "ghcr.io/azure-samples/aks-store-demo/store-front" tag: "latest" + serviceType: LoadBalancer virtualCustomer: image: @@ -74,12 +76,6 @@ virtualWorker: repository: "ghcr.io/azure-samples/aks-store-demo/virtual-worker" tag: "latest" -storeFront: - serviceType: LoadBalancer - -storeAdmin: - serviceType: LoadBalancer - podAnnotations: {} podSecurityContext: {} From 3cad7d26de8977096dc3a667f97f025e4f0af78d Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Mon, 22 Jan 2024 13:18:39 -0800 Subject: [PATCH 4/9] feat: adding option to build or import containers into acr --- README.md | 15 +++++++++------ infra/azd-hooks/postprovision.sh | 24 +++++++++++++++--------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a3e41bc0..40e4a3c0 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,15 @@ The `makeline-service` supports both MongoDB and SQL API for accessing data in A azd env set AZURE_COSMOSDB_ACCOUNT_KIND GlobalDocumentDB ``` -Deploy the app with a single command. +The `azd up` command will provision all Azure infrastructure using Terraform and import containers from GitHub Container Registry into your Azure Container Registry. If you want to build containers from source you can set the `BUILD_CONTAINERS` environment variable to "true" and the `azd` post-provision process will build containers using the `az acr build` task to build each container from source. + +To build containers from source, run the following command. Otherwise, you can skip this command and containers will be imported instead. + +```bash +azd env set BUILD_CONTAINERS true +``` + +Provision and deploy the app with a single command. ```bash azd up @@ -137,11 +145,6 @@ Once the deployment is complete, you can verify all the services are running and - In the Azure portal, navigate to your Azure Service Bus resource and use Azure Service Bus explorer to check for order messages - In the Azure portal, navigate to your Azure Cosmos DB resource and use the database explorer to check for order records -- Port-forward the store-admin service (using the command below) then open http://localhost:8081 in your browser and ensure you can add product descriptions using the AI service - - ```bash - kubectl port-forward svc/store-admin 8081:80 - ``` ## Additional Resources diff --git a/infra/azd-hooks/postprovision.sh b/infra/azd-hooks/postprovision.sh index 76a4a266..79478f42 100755 --- a/infra/azd-hooks/postprovision.sh +++ b/infra/azd-hooks/postprovision.sh @@ -1,11 +1,17 @@ #!/bin/bash -echo "Build container images" -az acr build --registry ${registry_name} --image aks-store-demo/ai-service:latest ./src/ai-service/ -az acr build --registry ${registry_name} --image aks-store-demo/makeline-service:latest ./src/makeline-service/ -az acr build --registry ${registry_name} --image aks-store-demo/order-service:latest ./src/order-service/ -az acr build --registry ${registry_name} --image aks-store-demo/product-service:latest ./src/product-service/ -az acr build --registry ${registry_name} --image aks-store-demo/store-admin:latest ./src/store-admin/ -az acr build --registry ${registry_name} --image aks-store-demo/store-front:latest ./src/store-front/ -az acr build --registry ${registry_name} --image aks-store-demo/virtual-customer:latest ./src/virtual-customer/ -az acr build --registry ${registry_name} --image aks-store-demo/virtual-worker:latest ./src/virtual-worker/ +services=("ai-service" "makeline-service" "order-service" "product-service" "store-admin" "store-front" "virtual-customer" "virtual-worker") + +if [ -n "$BUILD_CONTAINERS" ] && [ "$BUILD_CONTAINERS" == "true" ]; then + echo "Build container images" + for service in "${services[@]}"; do + echo "Building aks-store-demo/${service}:latest" + az acr build --registry ${registry_name} --image aks-store-demo/${service}:latest ./src/${service}/ + done +else + echo "Import container images" + for service in "${services[@]}"; do + echo "Importing aks-store-demo/${service}:latest" + az acr import --name ${registry_name} --source ghcr.io/azure-samples/aks-store-demo/${service}:latest --image aks-store-demo/${service}:latest + done +fi \ No newline at end of file From f319340d6b56b9b487547795baf75a87958ef6e6 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Mon, 22 Jan 2024 20:06:47 -0800 Subject: [PATCH 5/9] feat: make acr deployment optional --- .gitignore | 1 + README.md | 12 ++++++++++-- infra/azd-hooks/postprovision.sh | 6 ++++-- infra/cosmosdb.tf | 2 +- infra/kubernetes.tf | 4 +++- infra/main.tf | 7 ++++--- infra/main.tfvars.json | 3 ++- infra/outputs.tf | 4 ++-- infra/variables.tf | 5 +++++ 9 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 8a748bd5..62204235 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,4 @@ __pycache__/ .vscode **/.vscode .azure +.terraform \ No newline at end of file diff --git a/README.md b/README.md index 40e4a3c0..92827202 100644 --- a/README.md +++ b/README.md @@ -125,9 +125,17 @@ The `makeline-service` supports both MongoDB and SQL API for accessing data in A azd env set AZURE_COSMOSDB_ACCOUNT_KIND GlobalDocumentDB ``` -The `azd up` command will provision all Azure infrastructure using Terraform and import containers from GitHub Container Registry into your Azure Container Registry. If you want to build containers from source you can set the `BUILD_CONTAINERS` environment variable to "true" and the `azd` post-provision process will build containers using the `az acr build` task to build each container from source. +By default, all application containers will be sourced from the [GitHub Container Registry](https://github.com/orgs/Azure-Samples/packages?repo_name=aks-store-demo). If you want to deploy apps from an Azure Container registry instead, you can do so by setting the following environment variable. -To build containers from source, run the following command. Otherwise, you can skip this command and containers will be imported instead. +```bash +azd env set DEPLOY_AZURE_CONTAINER_REGISTRY true +``` + +This will instruct the Terraform templates to provision an Azure Container Registry and enable authentication from the AKS cluster. + +When you choose to deploy containers from Azure Container Registry, you will have the option to import containers from GitHub Container Registry using the `az acr import` command or build containers from source using the `az acr build` command. + +To build containers from source, run the following command. ```bash azd env set BUILD_CONTAINERS true diff --git a/infra/azd-hooks/postprovision.sh b/infra/azd-hooks/postprovision.sh index 79478f42..c6837321 100755 --- a/infra/azd-hooks/postprovision.sh +++ b/infra/azd-hooks/postprovision.sh @@ -2,16 +2,18 @@ services=("ai-service" "makeline-service" "order-service" "product-service" "store-admin" "store-front" "virtual-customer" "virtual-worker") -if [ -n "$BUILD_CONTAINERS" ] && [ "$BUILD_CONTAINERS" == "true" ]; then +if [ -n "$DEPLOY_AZURE_CONTAINER_REGISTRY" ] && [ "$BUILD_CONTAINERS" == "true" ]; then echo "Build container images" for service in "${services[@]}"; do echo "Building aks-store-demo/${service}:latest" az acr build --registry ${registry_name} --image aks-store-demo/${service}:latest ./src/${service}/ done -else +elif [ -n "$DEPLOY_AZURE_CONTAINER_REGISTRY" ] && ([ -z "$BUILD_CONTAINERS" ] || [ "$BUILD_CONTAINERS" == "false" ]); then echo "Import container images" for service in "${services[@]}"; do echo "Importing aks-store-demo/${service}:latest" az acr import --name ${registry_name} --source ghcr.io/azure-samples/aks-store-demo/${service}:latest --image aks-store-demo/${service}:latest done +else + echo "No BUILD_CONTAINERS variable set, skipping container build/import" fi \ No newline at end of file diff --git a/infra/cosmosdb.tf b/infra/cosmosdb.tf index dac324ef..771ee7a6 100644 --- a/infra/cosmosdb.tf +++ b/infra/cosmosdb.tf @@ -10,7 +10,7 @@ resource "azurerm_cosmosdb_account" "example" { dynamic "capabilities" { for_each = var.cosmosdb_account_kind == "MongoDB" ? ["EnableAggregationPipeline", "mongoEnableDocLevelTTL", "MongoDBv3.4", "EnableMongo"] : ["EnableAggregationPipeline"] content { - name = "${capabilities.value}" + name = capabilities.value } } diff --git a/infra/kubernetes.tf b/infra/kubernetes.tf index e232f680..6c8cd30b 100644 --- a/infra/kubernetes.tf +++ b/infra/kubernetes.tf @@ -1,4 +1,5 @@ resource "azurerm_container_registry" "example" { + count = local.deploy_acr ? 1 : 0 name = "acr${local.name}" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location @@ -34,8 +35,9 @@ resource "azurerm_kubernetes_cluster" "example" { } resource "azurerm_role_assignment" "example" { + count = local.deploy_acr ? 1 : 0 principal_id = azurerm_kubernetes_cluster.example.kubelet_identity[0].object_id role_definition_name = "AcrPull" - scope = azurerm_container_registry.example.id + scope = azurerm_container_registry.example[0].id skip_service_principal_aad_check = true } \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf index 5d1ed0d0..53f12e57 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -43,10 +43,11 @@ resource "random_pet" "example" { } locals { - name = "${random_pet.example.id}${random_integer.example.result}" - location = var.location + name = "${random_pet.example.id}${random_integer.example.result}" + location = var.location default_cosmosdb_account_kind = "MongoDB" - cosmosdb_account_kind = var.cosmosdb_account_kind != "" ? var.cosmosdb_account_kind : local.default_cosmosdb_account_kind + cosmosdb_account_kind = var.cosmosdb_account_kind != "" ? var.cosmosdb_account_kind : local.default_cosmosdb_account_kind + deploy_acr = var.deploy_acr == "true" ? true : false } data "azurerm_subscription" "current" {} diff --git a/infra/main.tfvars.json b/infra/main.tfvars.json index 0cc267be..f1a7f544 100644 --- a/infra/main.tfvars.json +++ b/infra/main.tfvars.json @@ -1,5 +1,6 @@ { "location": "${AZURE_LOCATION}", "ai_location": "${AZURE_LOCATION}", - "cosmosdb_account_kind": "${AZURE_COSMOSDB_ACCOUNT_KIND}" + "cosmosdb_account_kind": "${AZURE_COSMOSDB_ACCOUNT_KIND}", + "deploy_acr": "${DEPLOY_AZURE_CONTAINER_REGISTRY}" } \ No newline at end of file diff --git a/infra/outputs.tf b/infra/outputs.tf index 1a053c51..fc183192 100644 --- a/infra/outputs.tf +++ b/infra/outputs.tf @@ -72,9 +72,9 @@ output "k8s_namespace" { } output "registry_name" { - value = azurerm_container_registry.example.name + value = local.deploy_acr ? azurerm_container_registry.example[0].name : "" } output "registry_uri" { - value = azurerm_container_registry.example.login_server + value = local.deploy_acr ? azurerm_container_registry.example[0].login_server : "ghcr.io/azure-samples" } \ No newline at end of file diff --git a/infra/variables.tf b/infra/variables.tf index 67501425..449428ef 100644 --- a/infra/variables.tf +++ b/infra/variables.tf @@ -41,3 +41,8 @@ variable "cosmosdb_account_kind" { } } +variable "deploy_acr" { + description = "value of deploy acr. this string value will be used to set the local variable" + type = string + default = "false" +} From a81cce9e621facba561a4dbde7ea1a40bad4c34f Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Tue, 23 Jan 2024 14:02:06 -0800 Subject: [PATCH 6/9] fix: increase mem limit to resolve #97 --- aks-store-all-in-one.yaml | 4 ++-- aks-store-quickstart.yaml | 4 ++-- charts/aks-store-demo/templates/product-service.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aks-store-all-in-one.yaml b/aks-store-all-in-one.yaml index d48bfd1f..c3f72cd2 100644 --- a/aks-store-all-in-one.yaml +++ b/aks-store-all-in-one.yaml @@ -308,8 +308,8 @@ spec: cpu: 1m memory: 1Mi limits: - cpu: 1m - memory: 7Mi + cpu: 2m + memory: 10Mi readinessProbe: httpGet: path: /health diff --git a/aks-store-quickstart.yaml b/aks-store-quickstart.yaml index f19dfe16..eeda0c9a 100644 --- a/aks-store-quickstart.yaml +++ b/aks-store-quickstart.yaml @@ -187,8 +187,8 @@ spec: cpu: 1m memory: 1Mi limits: - cpu: 1m - memory: 7Mi + cpu: 2m + memory: 10Mi readinessProbe: httpGet: path: /health diff --git a/charts/aks-store-demo/templates/product-service.yaml b/charts/aks-store-demo/templates/product-service.yaml index 33618249..d242d663 100644 --- a/charts/aks-store-demo/templates/product-service.yaml +++ b/charts/aks-store-demo/templates/product-service.yaml @@ -27,8 +27,8 @@ spec: cpu: 1m memory: 1Mi limits: - cpu: 1m - memory: 6Mi + cpu: 2m + memory: 10Mi readinessProbe: httpGet: path: /health From 325588d051893bc73466c353db8b4d681611758c Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Tue, 23 Jan 2024 17:57:30 -0800 Subject: [PATCH 7/9] fix: cosmosdb default to mongo --- README.md | 2 +- infra/cosmosdb.tf | 10 +++++----- infra/locals.tf | 7 +++++++ infra/main.tf | 8 -------- infra/outputs.tf | 4 ++-- infra/variables.tf | 10 +++++----- 6 files changed, 20 insertions(+), 21 deletions(-) create mode 100644 infra/locals.tf diff --git a/README.md b/README.md index 92827202..0376a980 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ azd auth login az login ``` -The `makeline-service` supports both MongoDB and SQL API for accessing data in Azure CosmosDB. The default API is MongoDB, but you can use SQL API. To use the SQL API for Azure CosmosDB, you must provision the service using the `GlobalDocumentDB` account kind. You can set the Azure CosmosDB account kind by running the following command prior to running `azd up`: +The `makeline-service` supports both MongoDB and SQL API for accessing data in Azure CosmosDB. The default API is `MongoDB`, but you can use SQL API. To use the SQL API for Azure CosmosDB, you must provision the service using the `GlobalDocumentDB` account kind. You can set the Azure CosmosDB account kind by running the following command prior to running `azd up`: ```bash azd env set AZURE_COSMOSDB_ACCOUNT_KIND GlobalDocumentDB diff --git a/infra/cosmosdb.tf b/infra/cosmosdb.tf index 771ee7a6..f21af43d 100644 --- a/infra/cosmosdb.tf +++ b/infra/cosmosdb.tf @@ -8,7 +8,7 @@ resource "azurerm_cosmosdb_account" "example" { enable_automatic_failover = false dynamic "capabilities" { - for_each = var.cosmosdb_account_kind == "MongoDB" ? ["EnableAggregationPipeline", "mongoEnableDocLevelTTL", "MongoDBv3.4", "EnableMongo"] : ["EnableAggregationPipeline"] + for_each = local.cosmosdb_account_kind == "MongoDB" ? ["EnableAggregationPipeline", "mongoEnableDocLevelTTL", "MongoDBv3.4", "EnableMongo"] : ["EnableAggregationPipeline"] content { name = capabilities.value } @@ -32,7 +32,7 @@ resource "azurerm_cosmosdb_account" "example" { } resource "azurerm_cosmosdb_mongo_database" "example" { - count = var.cosmosdb_account_kind == "MongoDB" ? 1 : 0 + count = local.cosmosdb_account_kind == "MongoDB" ? 1 : 0 name = "orderdb" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name @@ -40,7 +40,7 @@ resource "azurerm_cosmosdb_mongo_database" "example" { } resource "azurerm_cosmosdb_mongo_collection" "example" { - count = var.cosmosdb_account_kind == "MongoDB" ? 1 : 0 + count = local.cosmosdb_account_kind == "MongoDB" ? 1 : 0 name = "orders" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name @@ -54,7 +54,7 @@ resource "azurerm_cosmosdb_mongo_collection" "example" { } resource "azurerm_cosmosdb_sql_database" "example" { - count = var.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 + count = local.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 name = "orderdb" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name @@ -62,7 +62,7 @@ resource "azurerm_cosmosdb_sql_database" "example" { } resource "azurerm_cosmosdb_sql_container" "example" { - count = var.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 + count = local.cosmosdb_account_kind == "GlobalDocumentDB" ? 1 : 0 name = "orders" resource_group_name = azurerm_cosmosdb_account.example.resource_group_name account_name = azurerm_cosmosdb_account.example.name diff --git a/infra/locals.tf b/infra/locals.tf new file mode 100644 index 00000000..c8caf81b --- /dev/null +++ b/infra/locals.tf @@ -0,0 +1,7 @@ +locals { + name = "${random_pet.example.id}${random_integer.example.result}" + location = var.location + default_cosmosdb_account_kind = "MongoDB" + cosmosdb_account_kind = var.cosmosdb_account_kind != "" ? var.cosmosdb_account_kind : local.default_cosmosdb_account_kind + deploy_acr = var.deploy_acr == "true" ? true : false +} \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf index 53f12e57..83e75dd8 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -42,14 +42,6 @@ resource "random_pet" "example" { } } -locals { - name = "${random_pet.example.id}${random_integer.example.result}" - location = var.location - default_cosmosdb_account_kind = "MongoDB" - cosmosdb_account_kind = var.cosmosdb_account_kind != "" ? var.cosmosdb_account_kind : local.default_cosmosdb_account_kind - deploy_acr = var.deploy_acr == "true" ? true : false -} - data "azurerm_subscription" "current" {} data "azurerm_client_config" "current" {} diff --git a/infra/outputs.tf b/infra/outputs.tf index fc183192..3c67d098 100644 --- a/infra/outputs.tf +++ b/infra/outputs.tf @@ -55,11 +55,11 @@ output "db_account_name" { } output "db_api" { - value = var.cosmosdb_account_kind == "MongoDB" ? "mongodb" : "cosmosdbsql" + value = local.cosmosdb_account_kind == "MongoDB" ? "mongodb" : "cosmosdbsql" } output "db_uri" { - value = var.cosmosdb_account_kind == "MongoDB" ? "mongodb://${azurerm_cosmosdb_account.example.name}.mongo.cosmos.azure.com:10255/?retryWrites=false" : "https://${azurerm_cosmosdb_account.example.name}.documents.azure.com:443/" + value = local.cosmosdb_account_kind == "MongoDB" ? "mongodb://${azurerm_cosmosdb_account.example.name}.mongo.cosmos.azure.com:10255/?retryWrites=false" : "https://${azurerm_cosmosdb_account.example.name}.documents.azure.com:443/" } output "db_key" { diff --git a/infra/variables.tf b/infra/variables.tf index 449428ef..b540e38f 100644 --- a/infra/variables.tf +++ b/infra/variables.tf @@ -31,14 +31,14 @@ variable "k8s_namespace" { } variable "cosmosdb_account_kind" { - description = "value of cosmosdb account kind" + description = "value of cosmosdb account kind. this string value will be used to set the local variable" type = string default = "MongoDB" - validation { - condition = contains(["MongoDB", "GlobalDocumentDB"], var.cosmosdb_account_kind) - error_message = "Valid values for var: cosmosdb_account_kind are (MongoDB, GlobalDocumentDB)." - } + # validation { + # condition = contains(["MongoDB", "GlobalDocumentDB"], local.cosmosdb_account_kind) + # error_message = "Valid values for var: cosmosdb_account_kind are (MongoDB, GlobalDocumentDB)." + # } } variable "deploy_acr" { From f2850a8ffd8c2148f66cf319e2c165d7e0adf2ca Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Wed, 24 Jan 2024 11:47:51 -0800 Subject: [PATCH 8/9] fix: continue support for store-admin <=1.1.0 --- charts/aks-store-demo/templates/store-admin.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/aks-store-demo/templates/store-admin.yaml b/charts/aks-store-demo/templates/store-admin.yaml index f019f2dd..ebd1249f 100644 --- a/charts/aks-store-demo/templates/store-admin.yaml +++ b/charts/aks-store-demo/templates/store-admin.yaml @@ -25,6 +25,8 @@ spec: value: "http://product-service:3002/" - name: VUE_APP_MAKELINE_SERVICE_URL value: "http://makeline-service:3001/" + - name: VUE_APP_AI_SERVICE_URL # this key/value pair is to support previous versions of store-admin <= 1.1.0 + value: "http://ai-service:5001/" # container images hosted on ghcr.io and will be removed in future releases resources: requests: cpu: 1m From 3331b6900fd38e3547b7bc801da7ea3c6c872072 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Wed, 24 Jan 2024 13:16:26 -0800 Subject: [PATCH 9/9] fix: adding ai-service url to product-service --- docker-compose-quickstart.yml | 2 ++ docker-compose.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docker-compose-quickstart.yml b/docker-compose-quickstart.yml index d0bdfcb6..193818f3 100644 --- a/docker-compose-quickstart.yml +++ b/docker-compose-quickstart.yml @@ -53,6 +53,8 @@ services: interval: 30s timeout: 10s retries: 5 + environment: + - AI_SERVICE_URL=http://ai-service:5001/ networks: - backend_services store-front: diff --git a/docker-compose.yml b/docker-compose.yml index 062e963a..13b33c05 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -92,6 +92,8 @@ services: interval: 30s timeout: 10s retries: 5 + environment: + - AI_SERVICE_URL=http://ai-service:5001/ networks: - backend_services store-front: