Skip to content

contoso-traders-cloud-testing #8

contoso-traders-cloud-testing

contoso-traders-cloud-testing #8

name: contoso-traders-cloud-testing
on:
workflow_dispatch:
# push:
# branches: ["main"]
# paths-ignore: ["docs/**", "demo-scripts/**"]
env:
ACR_NAME: contosotradersacr
AKS_CLUSTER_NAME: contoso-traders-aks
AKS_CPU_LIMIT: 250m
AKS_DNS_LABEL: contoso-traders-products
AKS_MEMORY_LIMIT: 256Mi
AKS_NODES_RESOURCE_GROUP_NAME: contoso-traders-aks-nodes-rg
AKS_REPLICAS: "1"
AKS_SECRET_NAME_ACR_PASSWORD: contoso-traders-acr-password
AKS_SECRET_NAME_KV_ENDPOINT: contoso-traders-kv-endpoint
AKS_SECRET_NAME_MI_CLIENTID: contoso-traders-mi-clientid
AZURE_AD_APP_NAME: contoso-traders-cloud-testing-app
CARTS_ACA_NAME: contoso-traders-carts
CARTS_ACR_REPOSITORY_NAME: contosotradersapicarts
CARTS_INTERNAL_ACA_NAME: contoso-traders-intcarts
CDN_PROFILE_NAME: contoso-traders-cdn
CHAOS_AKS_EXPERIMENT_NAME: contoso-traders-chaos-aks-experiment
KV_NAME: contosotraderskv
LOAD_TEST_SERVICE_NAME: contoso-traders-loadtest
MSGRAPH_API_ID: 00000003-0000-0000-c000-000000000000
MSGRAPH_API_PERMISSION_EMAIL: 64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0=Scope
MSGRAPH_API_PERMISSION_USER_READ: e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope
PRODUCTS_ACR_REPOSITORY_NAME: contosotradersapiproducts
PRODUCTS_DB_NAME: productsdb
PRODUCTS_DB_SERVER_NAME: contoso-traders-products
PRODUCTS_DB_USER_NAME: localadmin
PRODUCT_DETAILS_CONTAINER_NAME: product-details
PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME: contosotradersimg
PRODUCT_LIST_CONTAINER_NAME: product-list
PRODUCTS_CDN_ENDPOINT_NAME: contoso-traders-images
RESOURCE_GROUP_NAME: contoso-traders-rg
STORAGE_ACCOUNT_NAME: contosotradersimg
UI_CDN_ENDPOINT_NAME: contoso-traders-ui2
UI_STORAGE_ACCOUNT_NAME: contosotradersui2
USER_ASSIGNED_MANAGED_IDENTITY_NAME: contoso-traders-mi-kv-access
permissions:
id-token: write
contents: read
jobs:
provision:
runs-on: ubuntu-22.04
env:
AADUSERNAME: ${{ secrets.AADUSERNAME }}
AADPASSWORD: ${{ secrets.AADPASSWORD }}
outputs:
azureAdAppClientId: ${{ steps.get-azureAdAppClientId.outputs.azureAdAppClientId }}
azureAdAppObjId: ${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }}
cartsApiEndpoint: ${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }}
productsApiEndpoint: ${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }}
uiCdnEndpoint: ${{ steps.get-uiCdnEndpoint.outputs.uiCdnEndpoint }}
concurrency:
group: provision
cancel-in-progress: true
steps:
- name: checkout code
uses: actions/checkout@v4
- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# section #0: optional configuration of the Azure AD app.
# create the Azure AD application (and update it if it already exists).
# note: This is an idempotent operation.
# - name: create/update azure active directory app
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: az ad app create --display-name ${{ env.AZURE_AD_APP_NAME}}${{ vars.SUFFIX }} --sign-in-audience AzureADandPersonalMicrosoftAccount
# - name: get azure ad app's object id
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# id: get-azureAdAppObjId
# with:
# inlineScript: echo "azureAdAppObjId"="$(az ad app list --display-name ${{ env.AZURE_AD_APP_NAME }}${{ vars.SUFFIX }} --query [].id -o tsv)" >> $GITHUB_OUTPUT
# - name: get azure ad app's client id
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# id: get-azureAdAppClientId
# with:
# inlineScript: echo "azureAdAppClientId"="$(az ad app list --display-name ${{ env.AZURE_AD_APP_NAME }}${{ vars.SUFFIX }} --query [].appId -o tsv)" >> $GITHUB_OUTPUT
# - name: register app as a spa
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: |
# az rest \
# --method PATCH \
# --uri https://graph.microsoft.com/v1.0/applications/${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} \
# --headers 'Content-Type=application/json' \
# --body '{"spa":{"redirectUris":["https://localhost:3000/authcallback","http://localhost:3000/authcallback","https://production.contosotraders.com/authcallback","https://cloudtesting.contosotraders.com/authcallback"]}}'
# - name: enable issuance of id, access tokens
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: az ad app update --id ${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} --enable-access-token-issuance true --enable-id-token-issuance true
# - name: enable email claim in access token
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: az ad app update --id ${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} --optional-claims "{\"accessToken\":[{\"name\":\"email\",\"essential\":false}]}"
# # note: requesting MS Graph permissions in Azure AD app unfortunately isn't idempotent.
# # Even, if you have already requested the permissions, it'll keep adding to the list of requested permissions until you hit limit on max permissions requested.
# # Details: https://github.com/Azure/azure-cli/issues/24512
# - name: delete any requested Microsoft Graph permissions
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: |
# az ad app permission delete \
# --id ${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} \
# --api ${{ env.MSGRAPH_API_ID }}
# - name: request Microsoft Graph permissions
# uses: azure/CLI@v1
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# with:
# inlineScript: |
# az ad app permission add \
# --id ${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} \
# --api ${{ env.MSGRAPH_API_ID }} \
# --api-permissions ${{ env.MSGRAPH_API_PERMISSION_USER_READ }} ${{ env.MSGRAPH_API_PERMISSION_EMAIL }}
#
# section #1: provisioning the resources on Azure using bicep templates
#
# The first step is to create the resource group: `contoso-traders-rg`.
# The below step can also be manually executed as follows:
# az deployment sub create --location {LOCATION} --template-file .\createResourceGroup.bicep
# Note: You can specify any location for `{LOCATION}`. It's the region where the deployment metadata will be stored, and not
# where the resource groups will be deployed.
- name: create resource group
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(30000);
# uses: Azure/arm-deploy@v1
# with:
# scope: subscription
# region: ${{ vars.DEPLOYMENTREGION }}
# template: ./iac/createResourceGroup.bicep
# parameters: rgName=${{ env.RESOURCE_GROUP_NAME }} suffix=${{ vars.SUFFIX }} rgLocation=${{ vars.DEPLOYMENTREGION }}
# Next step is to deploy the Azure resources to the resource group `contoso-traders-rg` created above. The deployed resources
# include storage accounts, function apps, app services cosmos db, and service bus etc.
# The below step can also be manually executed as follows:
# az deployment group create -g contoso-traders-rg --template-file .\createResources.bicep --parameters .\createResources.parameters.json
# Note: The `createResources.parameters.json` file contains the parameters for the deployment; specifically the environment name.
# You can modify the parameters to customize the deployment.
# Note: The bicep template outputs are not shown in the logs. You can extract the outputs as shown here:
# https://github.com/Azure/arm-deploy#another-example-on-how-to-use-this-action-to-get-the-output-of-arm-template
- name: create resources
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(1820);
# uses: Azure/arm-deploy@v1
# with:
# scope: resourcegroup
# region: ${{ vars.DEPLOYMENTREGION }}
# resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }}
# template: ./iac/createResources.bicep
# parameters: ./iac/createResources.parameters.json suffix=${{ vars.SUFFIX }} sqlPassword=${{ secrets.SQLPASSWORD }} deployPrivateEndpoints=${{ vars.DEPLOYPRIVATEENDPOINTS }}
# Add the logged-in service principal to the key vault access policy
- name: add service principal to kv access policy
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(620);
# uses: azure/CLI@v1
# with:
# inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ vars.SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --secret-permissions get list set --object-id $(az ad sp show --id $(az account show --query "user.name" -o tsv) --query "id" -o tsv)
# The AKS agent pool needs to be assigned the user-assigned managed identity created (which has kv access)
- name: assign user-assigned managed-identity to aks agentpool
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(1600);
# uses: azure/CLI@v1
# with:
# inlineScript: |
# az vmss identity assign \
# --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ vars.SUFFIX }} --query "id" -o tsv) \
# --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --query "[0].id" -o tsv) \
# Seed the DBs and storage accounts
- name: seed products db
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(4220);
# uses: azure/[email protected]
# with:
# connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ vars.SUFFIX }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQLPASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
# path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql
- name: seed product image (product details)
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(9020);
# uses: azure/CLI@v1
# with:
# inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ vars.SUFFIX }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details'
- name: seed product image (product list)
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(1020);
# uses: azure/CLI@v1
# with:
# inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ vars.SUFFIX }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list'
- name: purge product images cdn endpoint
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(6020);
# uses: azure/CLI@v1
# with:
# inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ vars.SUFFIX }}' -g '${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ vars.SUFFIX }}'
- name: extract acr password
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(4020);
# uses: azure/CLI@v1
# id: extract-acr-password
# with:
# inlineScript: |
# acrPassword=$(az acr credential show -n ${{ env.ACR_NAME }}${{ vars.SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --query "passwords[0].value" --output tsv)
# echo "::add-mask::$acrPassword"
# echo acrPassword=$acrPassword >> $GITHUB_OUTPUT
- name: azure container registry login
uses: actions/github-script@v6
with:
script: |
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(480);
# uses: azure/docker-login@v1
# with:
# login-server: ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io
# username: ${{ env.ACR_NAME }}${{ vars.SUFFIX }}
# password: ${{ steps.extract-acr-password.outputs.acrPassword }}
- name: set aks context
run: sleep 20s
shell: bash
# uses: azure/aks-set-context@v3
# with:
# resource-group: ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }}
# cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ vars.SUFFIX }}
#
# section #2: deploy the carts api
#
- name: docker build
run: sleep 38s
shell: bash
# run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }}
- name: docker push (to acr)
run: sleep 50s
shell: bash
# run: docker push --all-tags ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}
- name: deploy to aca
run: sleep 45s
shell: bash
# uses: azure/CLI@v1
# with:
# inlineScript: |
# az config set extension.use_dynamic_install=yes_without_prompt
# az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ vars.SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --image ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }}
- name: deploy to aca (internal)
run: sleep 20s
shell: bash
# if: ${{ vars.DEPLOYPRIVATEENDPOINTS == 'true' }}
# uses: azure/CLI@v1
# with:
# inlineScript: |
# az config set extension.use_dynamic_install=yes_without_prompt
# az containerapp update -n ${{ env.CARTS_INTERNAL_ACA_NAME }}${{ vars.SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --image ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }}
- name: get carts api endpoint
run: sleep 19s
shell: bash
# uses: azure/CLI@v1
# id: get-cartsApiEndpoint
# with:
# inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ vars.SUFFIX }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT
#
# section #3: deploy the products api
#
- name: install helm
run: sleep 30s
shell: bash
# uses: Azure/setup-helm@v3
# id: install-helm
# with:
# version: v3.9.0
- name: docker build
run: sleep 17s
shell: bash
# run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }}
- name: docker push (to acr)
run: sleep 36s
shell: bash
# run: docker push --all-tags ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}
- name: setup kubectl
run: sleep 14s
shell: bash
# uses: azure/setup-kubectl@v3
- name: create kubernetes secret (acr password)
run: sleep 13s
shell: bash
# uses: Azure/k8s-create-secret@v4
# with:
# secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }}
# container-registry-url: ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io
# container-registry-username: ${{ env.ACR_NAME }}${{ vars.SUFFIX }}
# container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }}
- name: get managedIdentityClientId
run: sleep 23s
shell: bash
# uses: azure/CLI@v1
# id: get-managedIdentityClientId
# with:
# inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ vars.SUFFIX }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT
- name: create kubernetes secret (kv endpoint)
run: sleep 24s
shell: bash
# uses: Azure/k8s-create-secret@v4
# with:
# secret-type: "generic"
# secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}
# string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ vars.SUFFIX }}.vault.azure.net/" }'
- name: create kubernetes secret (managed identity client id)
run: sleep 24s
shell: bash
# uses: Azure/k8s-create-secret@v4
# with:
# secret-type: "generic"
# secret-name: ${{ env.AKS_SECRET_NAME_MI_CLIENTID }}
# string-data: '{ "${{ env.AKS_SECRET_NAME_MI_CLIENTID }}" : "${{ steps.get-managedIdentityClientId.outputs.managedIdentityClientId }}" }'
- name: substitute tokens in deployment manifest
run: sleep 30s
shell: bash
# uses: cschleiden/[email protected]
# with:
# tokenPrefix: "{"
# tokenSuffix: "}"
# files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml
# env:
# SUFFIX: ${{ vars.SUFFIX }}
# AKS_REPLICAS: ${{ env.AKS_REPLICAS }}
# AKS_CPU_LIMIT: ${{ env.AKS_CPU_LIMIT }}
# AKS_MEMORY_LIMIT: ${{ env.AKS_MEMORY_LIMIT }}
- name: lint deployment manifest
run: sleep 20s
shell: bash
# uses: azure/[email protected]
# with:
# manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml
- name: apply deployment manifest
run: sleep 18s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml
# images: ${{ env.ACR_NAME }}${{ vars.SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }}
# imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }}
# force: true
- name: apply service manifest
run: sleep 32s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/Service.yaml
# force: true
# setup chaos mesh
- name: apply namespace manifest (chaos-testing)
run: sleep 66s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/NamespaceChaosTesting.yaml
# force: true
- name: setup chaos mesh
run: sleep 28s
shell: bash
# run: |
# az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --name ${{ env.AKS_CLUSTER_NAME }}${{ vars.SUFFIX }}
# ${{ steps.install-helm.outputs.helm-path }} repo add chaos-mesh https://charts.chaos-mesh.org
# ${{ steps.install-helm.outputs.helm-path }} repo update
# ${{ steps.install-helm.outputs.helm-path }} upgrade --install chaos-mesh chaos-mesh/chaos-mesh --namespace=chaos-testing --set chaosDaemon.runtime=containerd --set chaosDaemon.socketPath=/run/containerd/containerd.sock
# create the ingress controller
- name: create ingress controller
run: sleep 30s
shell: bash
# run: |
# az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --name ${{ env.AKS_CLUSTER_NAME }}${{ vars.SUFFIX }}
# ${{ steps.install-helm.outputs.helm-path }} repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# ${{ steps.install-helm.outputs.helm-path }} repo update
# ${{ steps.install-helm.outputs.helm-path }} upgrade --install --wait --timeout=1h nginx-ingress ingress-nginx/ingress-nginx \
# --set controller.replicaCount=1 \
# --set controller.nodeSelector."kubernetes\.io/os"=linux \
# --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
# --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
# --set controller.service.externalTrafficPolicy=Local
- name: set dns label on public ip
run: sleep 11s
shell: bash
# uses: azure/CLI@v1
# with:
# inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ vars.SUFFIX }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }})
# hack: extract the full fqdn / dns label of the aks app's public IP address
- name: get aks-fqdn
run: sleep 30s
shell: bash
# uses: azure/CLI@v1
# id: get-aks-fqdn
# with:
# # note: There should be a whitespace between ')' and ']'. More details: https://stackoverflow.com/a/59154958
# inlineScript: echo "aksFqdn"="$(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].dnsSettings.fqdn" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }})" >> $GITHUB_OUTPUT
# install cert-manager
- name: apply namespace manifest (cert-manager)
run: sleep 30s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/NamespaceCertManager.yaml
# force: true
- name: install cert-manager
run: sleep 25s
shell: bash
# run: |
# az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --name ${{ env.AKS_CLUSTER_NAME }}${{ vars.SUFFIX }}
# kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
- name: sleep for 30 seconds
run: sleep 30s
shell: bash
- name: apply clusterIssuer manifest
run: sleep 20s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterIssuer.yaml
# force: true
- name: substitute tokens in certificate manifest
run: sleep 30s
shell: bash
# uses: cschleiden/[email protected]
# with:
# tokenPrefix: "{"
# tokenSuffix: "}"
# files: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml
# env:
# AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }}
- name: apply certificate manifest
run: sleep 40s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml
# force: true
- name: substitute tokens in ingress manifest
run: sleep 16s
shell: bash
# uses: cschleiden/[email protected]
# with:
# tokenPrefix: "{"
# tokenSuffix: "}"
# files: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml
# env:
# AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }}
- name: apply ingress manifest
run: sleep 14s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml
# force: true
- name: apply clusterRole manifest
run: sleep 60s
shell: bash
# uses: Azure/k8s-deploy@v4
# with:
# pull-images: false
# manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterRole.yaml
# force: true
- name: set productsApiEndpoint in kv
run: sleep 10s
shell: bash
# uses: azure/CLI@v1
# with:
# inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ vars.SUFFIX }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api"
- name: get products api endpoint
run: sleep 10s
shell: bash
# uses: azure/CLI@v1
# id: get-productsApiEndpoint
# with:
# inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ vars.SUFFIX }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT
#
# section #4: deploy the ui
#
- name: set REACT_APP_APIURLSHOPPINGCART
run: sleep 10s
shell: bash
# run: echo "REACT_APP_APIURLSHOPPINGCART"="https://${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }}/v1" >> $GITHUB_ENV
- name: set REACT_APP_APIURL
run: sleep 10s
shell: bash
# run: echo "REACT_APP_APIURL"="https://${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }}/v1" >> $GITHUB_ENV
- name: set REACT_APP_B2CCLIENTID
run: sleep 10s
shell: bash
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# run: echo "REACT_APP_B2CCLIENTID"="${{ steps.get-azureAdAppClientId.outputs.azureAdAppClientId }}" >> $GITHUB_ENV
# - uses: actions/setup-node@v3
# with:
# node-version: 18
# cache: npm
# cache-dependency-path: src/ContosoTraders.Ui.Website/package-lock.json
- name: npm ci
run: sleep 10s
shell: bash
# run: npm ci
# working-directory: src/ContosoTraders.Ui.Website
- name: npm run build
run: sleep 10s
shell: bash
# run: npm run build
# env:
# REACT_APP_BINGMAPSKEY: ${{ secrets.BINGMAPSKEY }}
# working-directory: src/ContosoTraders.Ui.Website
- name: deploy ui to storage
run: sleep 10s
shell: bash
# uses: azure/CLI@v1
# with:
# inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ vars.SUFFIX }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build'
- name: purge ui cdn endpoint
run: sleep 10s
shell: bash
# uses: azure/CLI@v1
# with:
# inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ vars.SUFFIX }}' -g '${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ vars.SUFFIX }}'
- name: get ui cdn endpoint'
run: sleep 10s
shell: bash
# uses: azure/CLI@v1
# id: get-uiCdnEndpoint
# with:
# inlineScript: echo "uiCdnEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ vars.SUFFIX }} --name uiCdnEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT
- name: register auth callback (UI CDN)
run: sleep 10s
shell: bash
# if: ${{ env.AADUSERNAME != '' && env.AADPASSWORD != '' }}
# uses: azure/CLI@v1
# with:
# inlineScript: |
# az rest \
# --method PATCH \
# --uri https://graph.microsoft.com/v1.0/applications/${{ steps.get-azureAdAppObjId.outputs.azureAdAppObjId }} \
# --headers 'Content-Type=application/json' \
# --body '{"spa":{"redirectUris":["https://localhost:3000/authcallback","http://localhost:3000/authcallback","https://staging.contosotraders.com/authcallback","https://production.contosotraders.com/authcallback","https://cloudtesting.contosotraders.com/authcallback","https://${{ steps.get-uiCdnEndpoint.outputs.uiCdnEndpoint }}/authcallback"]}}'
- name: display ui cdn endpoint
uses: azure/CLI@v1
with:
inlineScript: echo UI CDN endpoint accessible at https://contoso-traders-ui2altig.azureedge.net/
# uses: azure/CLI@v1
# with:
# inlineScript: echo UI CDN endpoint accessible at https://$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ vars.SUFFIX }} --name uiCdnEndpoint --query value -o tsv)
playwright-tests-ui:
needs: [provision]
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Login to Azure with AzPowershell (enableAzPSSession true)
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
- name: Install dependencies
working-directory: demo-scripts/mpt-samples/
run: npm ci
- name: Run Playwright tests
working-directory: demo-scripts/mpt-samples/
env:
# Regional endpoint for Microsoft Playwright Testing
PLAYWRIGHT_SERVICE_URL: ${{ secrets.PLAYWRIGHT_SERVICE_URL }}
PLAYWRIGHT_SERVICE_RUN_ID: ${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }}
run: npx playwright test -c playwright.service.config.ts --workers=20
- name: Upload Playwright report
uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: demo-scripts/mpt-samples/get-started/playwright-report/
retention-days: 10
load-test-products:
needs: [provision, playwright-tests-ui]
runs-on: ubuntu-22.04
concurrency:
group: load-test-products
cancel-in-progress: true
steps:
- name: checkout code
uses: actions/checkout@v4
- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: load test (products)
uses: Azure/load-testing@v1
with:
# Path of the YAML file. Should be fully qualified path or relative to the default working directory
loadtestConfigFile: demo-scripts/azure-load-testing/config.yaml
loadtestResource: IgniteDemoALT
resourceGroup: nikita-rg
chaos-aks-with-load:
needs: [provision, playwright-tests-ui, load-test-products]
runs-on: ubuntu-latest
concurrency:
group: chaos-aks-with-load
cancel-in-progress: true
steps:
- name: checkout code
uses: actions/checkout@v4
- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# - name: get chaos experiment resource id
# uses: azure/CLI@v1
# id: get-chaosAksExperimentResourceId
# with:
# inlineScript: echo "chaosAksExperimentResourceId"="$(az resource show --resource-group ${{ env.RESOURCE_GROUP_NAME }}${{ vars.SUFFIX }} --namespace Microsoft.Chaos --resource-type Experiments --name ${{ env.CHAOS_AKS_EXPERIMENT_NAME }}${{ vars.SUFFIX }} --query "id" -o tsv)" >> $GITHUB_OUTPUT
- name: start chaos experiment (CPU stress)
uses: azure/CLI@v1
with:
inlineScript: az rest --method post --uri https://management.azure.com/subscriptions/4cf0c5fc-07e7-4715-b1f5-1e7543272251/resourceGroups/contoso-traders-rgaltig/providers/Microsoft.Chaos/experiments/contoso-traders-chaos-aks-experimentaltig/start?api-version=2021-09-15-preview