Skip to content

Commit

Permalink
Merge pull request #81 from Azure-Samples/azd
Browse files Browse the repository at this point in the history
feat: azd with terraform and helm to resolve #58
  • Loading branch information
chzbrgr71 authored Nov 27, 2023
2 parents 7113876 + a42e77b commit bf526a0
Show file tree
Hide file tree
Showing 29 changed files with 1,274 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"extensions": "aks-preview",
"installBicep": true
},
"ghcr.io/azure/azure-dev/azd:latest": {},
"ghcr.io/devcontainers/features/common-utils:2": {
"configureZshAsDefaultShell": true
},
Expand All @@ -19,7 +20,8 @@
},
"ghcr.io/devcontainers/features/python:1": {},
"ghcr.io/devcontainers/features/rust:1": {},
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {},
"ghcr.io/devcontainers/features/terraform:1": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/devcontainers/features/common-utils"
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,5 @@ __pycache__/
.DS_Store
**/.DS_Store
.vscode
**/.vscode
**/.vscode
.azure
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,38 @@ To stop the app, you can hit the `CTRL+C` key combination in the terminal window

This repo also includes [DevContainer configuration](./.devcontainer/devcontainer.json), so you can open the repo using [GitHub Codespaces](https://docs.github.com/en/codespaces/overview). This will allow you to run the app in a container in the cloud, without having to install Docker on your local machine. When the Codespace is created, you can run the app using the same instructions as above.

## Run the app with Azure Service Bus and Azure Cosmos DB using Azure Developer CLI

This repo also includes an alternate deployment type that uses Azure Service Bus and Azure Cosmos DB instead of RabbitMQ and MongoDB. To deploy this version of the app, you can use the [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/overview) with a GitHub Codespace or DevContainer which has all the tools (e.g., `azure-cli`, `azd`, `terraform`, `kubectl`, and `helm`) pre-installed. This deployment will use Terraform to provision the Azure resources then retrieve output variables and pass them to Helm to deploy the app.

To get started, authenticate to Azure using the Azure Developer CLI and Azure CLI.

```bash
# authenticate to Azure Developer CLI
azd auth login

# authenticate to Azure CLI
az login
```

Deploy the app with a single command.

```bash
azd up
```

> Note: When selecting an Azure region, make sure to choose one that supports all the services used in this app including Azure OpenAI, Azure Kubernetes Service, Azure Service Bus, and Azure Cosmos DB.
Once the deployment is complete, you can verify all the services are running and the app is working by following these steps:

- 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

- AKS Documentation. https://learn.microsoft.com/azure/aks
Expand Down
18 changes: 18 additions & 0 deletions azure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: aks-store-demo
metadata:
template: [email protected]
hooks:
preprovision:
shell: sh
continueOnError: false
interactive: false
run: infra/azd-hooks/preprovision.sh
postprovision:
shell: sh
continueOnError: false
interactive: false
run: infra/azd-hooks/postprovision.sh
infra:
provider: terraform
1 change: 1 addition & 0 deletions charts/aks-store-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aks-store-demo-chart-*.tgz
23 changes: 23 additions & 0 deletions charts/aks-store-demo/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
24 changes: 24 additions & 0 deletions charts/aks-store-demo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: aks-store-demo-chart
description: A Helm chart for deploying the aks-store-demo app to Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
111 changes: 111 additions & 0 deletions charts/aks-store-demo/templates/ai-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{{- if .Values.aiService.create }}
apiVersion: v1
kind: ConfigMap
metadata:
name: ai-service-configmap
data:
AZURE_OPENAI_DEPLOYMENT_NAME: "{{ .Values.aiService.modelDeploymentName }}"
AZURE_OPENAI_ENDPOINT: "{{ .Values.aiService.openAiEndpoint }}"
{{- if .Values.aiService.useAzureOpenAi }}
USE_AZURE_OPENAI: "True"
{{- else }}
USE_AZURE_OPENAI: "False"
OPENAI_ORG_ID: "{{ .Values.aiService.openAiOrgId }}"
{{- end }}
{{- if .Values.aiService.useAzureAd }}
USE_AZURE_AD: "True"
{{- else }}
USE_AZURE_AD: "False"
{{- end }}
---
{{- if eq .Values.aiService.useAzureAd false }}
apiVersion: v1
kind: Secret
metadata:
name: ai-service-secrets
data:
OPENAI_API_KEY: "{{ .Values.aiService.openAiKey | b64enc }}"
---
{{- end }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: ai-service-account
annotations:
azure.workload.identity/client-id: "{{ .Values.aiService.managedIdentityClientId }}"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-service
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: ai-service
template:
metadata:
labels:
app: ai-service
azure.workload.identity/use: "true"
spec:
serviceAccount: ai-service-account
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: order-service
image: ghcr.io/azure-samples/aks-store-demo/ai-service:1.0.0
ports:
- containerPort: 5001
envFrom:
- configMapRef:
name: ai-service-configmap
{{- if eq .Values.aiService.useAzureAd false }}
- secretRef:
name: ai-service-secrets
{{- end }}
resources:
requests:
cpu: 20m
memory: 50Mi
limits:
cpu: 30m
memory: 65Mi
startupProbe:
httpGet:
path: /health
port: 5001
initialDelaySeconds: 60
failureThreshold: 3
timeoutSeconds: 3
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 5001
initialDelaySeconds: 3
failureThreshold: 3
timeoutSeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 5001
failureThreshold: 3
initialDelaySeconds: 3
timeoutSeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: ai-service
spec:
type: ClusterIP
ports:
- name: http
port: 5001
targetPort: 5001
selector:
app: ai-service
{{- end }}
85 changes: 85 additions & 0 deletions charts/aks-store-demo/templates/makeline-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: makeline-service-configmap
data:
ORDER_QUEUE_URI: "{{ .Values.makelineService.orderQueueUri }}"
ORDER_QUEUE_USERNAME: "{{ .Values.makelineService.orderQueueUsername }}"
ORDER_QUEUE_PASSWORD: "{{ .Values.makelineService.orderQueuePassword }}"
ORDER_QUEUE_NAME: "{{ .Values.makelineService.orderQueueName }}"
ORDER_DB_URI: "{{ .Values.makelineService.orderDBUri }}"
ORDER_DB_NAME: "{{ .Values.makelineService.orderDBName }}"
ORDER_DB_COLLECTION_NAME: "{{ .Values.makelineService.orderDBCollectionName }}"
---
{{- if and .Values.makelineService.orderDBUsername .Values.makelineService.orderDBPassword }}
apiVersion: v1
kind: Secret
metadata:
name: makeline-service-secrets
data:
ORDER_DB_USERNAME: "{{ .Values.makelineService.orderDBUsername | b64enc }}"
ORDER_DB_PASSWORD: "{{ .Values.makelineService.orderDBPassword | b64enc }}"
---
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: makeline-service
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: makeline-service
template:
metadata:
labels:
app: makeline-service
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: makeline-service
image: ghcr.io/azure-samples/aks-store-demo/makeline-service:1.0.0
ports:
- containerPort: 3001
envFrom:
- configMapRef:
name: makeline-service-configmap
{{- if and .Values.makelineService.orderDBUsername .Values.makelineService.orderDBPassword }}
- secretRef:
name: makeline-service-secrets
{{- end }}
resources:
requests:
cpu: 1m
memory: 6Mi
limits:
cpu: 5m
memory: 20Mi
readinessProbe:
httpGet:
path: /health
port: 3001
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 3001
failureThreshold: 5
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: makeline-service
spec:
type: ClusterIP
ports:
- name: http
port: 3001
targetPort: 3001
selector:
app: makeline-service
51 changes: 51 additions & 0 deletions charts/aks-store-demo/templates/mongodb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{- if eq .Values.makelineService.useAzureCosmosDB false }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
nodeSelector:
"kubernetes.io/os": linux
containers:
- name: mongodb
image: mcr.microsoft.com/mirror/docker/library/mongo:4.2
ports:
- containerPort: 27017
name: mongodb
resources:
requests:
cpu: 5m
memory: 75Mi
limits:
cpu: 25m
memory: 1024Mi
livenessProbe:
exec:
command:
- mongosh
- --eval
- db.runCommand('ping').ok
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
ports:
- port: 27017
selector:
app: mongodb
type: ClusterIP
{{- end }}
Loading

0 comments on commit bf526a0

Please sign in to comment.