From 63d660f42972e84154bf6867122579d12fb22e9b Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 16:44:13 +0530 Subject: [PATCH 01/23] enable environments --- .github/workflows/contoso-traders-provisioning-deployment.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 45041f2..bb36b80 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -45,6 +45,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest + environment: TEST steps: - name: checkout code uses: actions/checkout@v3 @@ -112,6 +113,7 @@ jobs: deploy-carts-api: runs-on: ubuntu-latest + environment: TEST needs: provision-infrastructure steps: - name: checkout code @@ -144,6 +146,7 @@ jobs: deploy-products-api: runs-on: ubuntu-latest + environment: TEST needs: provision-infrastructure steps: - name: checkout code @@ -301,6 +304,7 @@ jobs: deploy-ui: runs-on: ubuntu-latest + environment: TEST needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] steps: - name: checkout code From 31f03540b9edf85273b28c0351aea6ac5059d77a Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:08:38 +0530 Subject: [PATCH 02/23] testing --- ...ontoso-traders-provisioning-deployment.yml | 653 +++++++++--------- .github/workflows/templates/template.yml | 341 +++++++++ 2 files changed, 670 insertions(+), 324 deletions(-) create mode 100644 .github/workflows/templates/template.yml diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index bb36b80..92a65b0 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -13,336 +13,341 @@ on: "src/ContosoTraders.Ui.Website/**", ] -env: - # You can specify any location for `SUB_DEPLOYMENT_REGION`. It's the region where the deployment - # metadata will be stored, and not where the resource groups will be deployed. - ACR_NAME: contosotradersacr - AKS_CLUSTER_NAME: contoso-traders-aks - AKS_DNS_LABEL: contoso-traders-products - AKS_NODES_RESOURCE_GROUP_NAME: contoso-traders-aks-nodes-rg - 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 - CARTS_ACA_NAME: contoso-traders-carts - CARTS_ACR_REPOSITORY_NAME: contosotradersapicarts - CDN_PROFILE_NAME: contoso-traders-cdn - SUB_DEPLOYMENT_REGION: eastus2 - KV_NAME: contosotraderskv - 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 +# env: +# # You can specify any location for `SUB_DEPLOYMENT_REGION`. It's the region where the deployment +# # metadata will be stored, and not where the resource groups will be deployed. +# ACR_NAME: contosotradersacr +# AKS_CLUSTER_NAME: contoso-traders-aks +# AKS_DNS_LABEL: contoso-traders-products +# AKS_NODES_RESOURCE_GROUP_NAME: contoso-traders-aks-nodes-rg +# 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 +# CARTS_ACA_NAME: contoso-traders-carts +# CARTS_ACR_REPOSITORY_NAME: contosotradersapicarts +# CDN_PROFILE_NAME: contoso-traders-cdn +# SUB_DEPLOYMENT_REGION: eastus2 +# KV_NAME: contosotraderskv +# 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 jobs: - provision-infrastructure: + a-job: + strategy: + matrix: + environment: [test, prod] runs-on: ubuntu-latest - environment: TEST steps: - name: checkout code uses: actions/checkout@v3 - - name: azure login - uses: azure/login@v1 - with: - creds: ${{ secrets.SERVICEPRINCIPAL }} - # 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: Azure/arm-deploy@v1 - with: - scope: subscription - region: ${{ env.SUB_DEPLOYMENT_REGION }} - template: ./iac/createResourceGroup.bicep - # 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. - - name: create resources - uses: Azure/arm-deploy@v1 - with: - scope: resourcegroup - region: ${{ env.SUB_DEPLOYMENT_REGION }} - resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} - template: ./iac/createResources.bicep - parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} - failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. - # Add the logged-in service principal to the key vault access policy - - name: add service principal to kv access policy - uses: azure/CLI@v1 - with: - inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --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: azure/CLI@v1 - with: - inlineScript: | - az vmss identity assign \ - --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "id" -o tsv) \ - --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ - # Seed the DBs and storage accounts - - name: seed products db - uses: azure/sql-action@v2 - with: - connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; - path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql - - name: seed product image (product details) - uses: azure/CLI@v1 - with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' - - name: seed product image (product list) - uses: azure/CLI@v1 - with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' - - name: purge CDN endpoint - uses: azure/CLI@v1 - with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' - deploy-carts-api: - runs-on: ubuntu-latest - environment: TEST - needs: provision-infrastructure - steps: - - name: checkout code - uses: actions/checkout@v3 - - name: azure login - uses: azure/login@v1 - with: - creds: ${{ secrets.SERVICEPRINCIPAL }} - - name: extract acr password - uses: azure/CLI@v1 - id: extract-acr-password - with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - - name: azure container registry login - uses: azure/docker-login@v1 - with: - login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - password: ${{ steps.extract-acr-password.outputs.acrPassword }} - - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} - - name: deploy to aca - uses: azure/CLI@v1 - with: - inlineScript: | - az config set extension.use_dynamic_install=yes_without_prompt - az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + # provision-infrastructure: + # runs-on: ubuntu-latest + # steps: + # - name: checkout code + # uses: actions/checkout@v3 + # - name: azure login + # uses: azure/login@v1 + # with: + # creds: ${{ secrets.SERVICEPRINCIPAL }} + # # 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: Azure/arm-deploy@v1 + # with: + # scope: subscription + # region: ${{ env.SUB_DEPLOYMENT_REGION }} + # template: ./iac/createResourceGroup.bicep + # # 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. + # - name: create resources + # uses: Azure/arm-deploy@v1 + # with: + # scope: resourcegroup + # region: ${{ env.SUB_DEPLOYMENT_REGION }} + # resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} + # template: ./iac/createResources.bicep + # parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} + # failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. + # # Add the logged-in service principal to the key vault access policy + # - name: add service principal to kv access policy + # uses: azure/CLI@v1 + # with: + # inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --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: azure/CLI@v1 + # with: + # inlineScript: | + # az vmss identity assign \ + # --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "id" -o tsv) \ + # --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ + # # Seed the DBs and storage accounts + # - name: seed products db + # uses: azure/sql-action@v2 + # with: + # connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; + # path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql + # - name: seed product image (product details) + # uses: azure/CLI@v1 + # with: + # inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' + # - name: seed product image (product list) + # uses: azure/CLI@v1 + # with: + # inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' + # - name: purge CDN endpoint + # uses: azure/CLI@v1 + # with: + # inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' - deploy-products-api: - runs-on: ubuntu-latest - environment: TEST - needs: provision-infrastructure - steps: - - name: checkout code - uses: actions/checkout@v3 - - name: azure login - uses: azure/login@v1 - with: - creds: ${{ secrets.SERVICEPRINCIPAL }} - - name: install helm - uses: Azure/setup-helm@v3 - id: install-helm - - name: extract acr password - uses: azure/CLI@v1 - id: extract-acr-password - with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - - name: azure container registry login - uses: azure/docker-login@v1 - with: - login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - password: ${{ steps.extract-acr-password.outputs.acrPassword }} - - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} - - name: set aks context - uses: azure/aks-set-context@v3 - with: - resource-group: ${{ env.RESOURCE_GROUP_NAME }} - cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - - name: setup kubectl - uses: azure/setup-kubectl@v3 - - name: create kubernetes secret (acr password) - uses: Azure/k8s-create-secret@v3.0 - with: - secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} - - name: get managedIdentityClientId - uses: azure/CLI@v1 - id: get-managedIdentityClientId - with: - inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT - - name: create kubernetes secret (kv endpoint) - uses: Azure/k8s-create-secret@v3.0 - with: - secret-type: "generic" - secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} - string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }}.vault.azure.net/" }' - - name: create kubernetes secret (managed identity client id) - uses: Azure/k8s-create-secret@v3.0 - 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 - uses: cschleiden/replace-tokens@v1.2 - with: - tokenPrefix: "{" - tokenSuffix: "}" - files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - - name: lint deployment manifest - uses: azure/k8s-lint@v1 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - - name: apply deployment manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - force: true - - name: apply service manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Service.yaml - force: true - # create the ingress controller - - name: create ingress controller - run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - ${{ 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 nginx-ingress ingress-nginx/ingress-nginx \ - --set controller.replicaCount=1 \ - --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \ - --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \ - --set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux \ - --set controller.service.externalTrafficPolicy=Local - - name: set dns label on public ip - uses: azure/CLI@v1 - with: - inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) - # hack: extract the full fqdn / dns label of the aks app's public IP address - - name: get aks-fqdn - 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 }})" >> $GITHUB_OUTPUT - # install cert-manager - - name: apply namespace manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Namespace.yaml - force: true - - name: install cert-manager - run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml - - name: apply clusterIssuer manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterIssuer.yaml - force: true - - name: substitute tokens in certificate manifest - uses: cschleiden/replace-tokens@v1.2 - with: - tokenPrefix: "{" - tokenSuffix: "}" - files: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml - env: - AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} - - name: apply certificate manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml - force: true - - name: substitute tokens in ingress manifest - uses: cschleiden/replace-tokens@v1.2 - with: - tokenPrefix: "{" - tokenSuffix: "}" - files: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml - env: - AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} - - name: apply ingress manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml - force: true - - name: apply clusterRole manifest - uses: Azure/k8s-deploy@v4 - with: - manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterRole.yaml - force: true - - name: set productsApiEndpoint in kv - uses: azure/CLI@v1 - with: - inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" + # deploy-carts-api: + # runs-on: ubuntu-latest + # needs: provision-infrastructure + # steps: + # - name: checkout code + # uses: actions/checkout@v3 + # - name: azure login + # uses: azure/login@v1 + # with: + # creds: ${{ secrets.SERVICEPRINCIPAL }} + # - name: extract acr password + # uses: azure/CLI@v1 + # id: extract-acr-password + # with: + # inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + # - name: azure container registry login + # uses: azure/docker-login@v1 + # with: + # login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + # username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + # password: ${{ steps.extract-acr-password.outputs.acrPassword }} + # - name: docker build + # run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + # - name: docker push (to acr) + # run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} + # - name: deploy to aca + # uses: azure/CLI@v1 + # with: + # inlineScript: | + # az config set extension.use_dynamic_install=yes_without_prompt + # az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - deploy-ui: - runs-on: ubuntu-latest - environment: TEST - needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] - steps: - - name: checkout code - uses: actions/checkout@v3 - - name: azure login - uses: azure/login@v1 - with: - creds: ${{ secrets.SERVICEPRINCIPAL }} - - name: get carts api endpoint - uses: azure/CLI@v1 - id: get-cartsApiEndpoint - with: - inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - - name: get products api endpoint - uses: azure/CLI@v1 - id: get-productsApiEndpoint - with: - inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - - name: substitute tokens in ui configuration - uses: cschleiden/replace-tokens@v1.2 - with: - tokenPrefix: "{{" - tokenSuffix: "}}" - files: ./src/ContosoTraders.Ui.Website/.env - env: - CARTS_API_ENDPOINT: ${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }} - PRODUCTS_API_ENDPOINT: ${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }} - - name: npm install - run: npm install - working-directory: src/ContosoTraders.Ui.Website - - name: npm run build - run: npm run build - working-directory: src/ContosoTraders.Ui.Website - - name: deploy to storage - uses: azure/CLI@v1 - with: - inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' - - name: purge CDN endpoint - uses: azure/CLI@v1 - with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' + # deploy-products-api: + # runs-on: ubuntu-latest + # needs: provision-infrastructure + # steps: + # - name: checkout code + # uses: actions/checkout@v3 + # - name: azure login + # uses: azure/login@v1 + # with: + # creds: ${{ secrets.SERVICEPRINCIPAL }} + # - name: install helm + # uses: Azure/setup-helm@v3 + # id: install-helm + # - name: extract acr password + # uses: azure/CLI@v1 + # id: extract-acr-password + # with: + # inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + # - name: azure container registry login + # uses: azure/docker-login@v1 + # with: + # login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + # username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + # password: ${{ steps.extract-acr-password.outputs.acrPassword }} + # - name: docker build + # run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + # - name: docker push (to acr) + # run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} + # - name: set aks context + # uses: azure/aks-set-context@v3 + # with: + # resource-group: ${{ env.RESOURCE_GROUP_NAME }} + # cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + # - name: setup kubectl + # uses: azure/setup-kubectl@v3 + # - name: create kubernetes secret (acr password) + # uses: Azure/k8s-create-secret@v3.0 + # with: + # secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} + # container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + # container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + # container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} + # - name: get managedIdentityClientId + # uses: azure/CLI@v1 + # id: get-managedIdentityClientId + # with: + # inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT + # - name: create kubernetes secret (kv endpoint) + # uses: Azure/k8s-create-secret@v3.0 + # with: + # secret-type: "generic" + # secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} + # string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }}.vault.azure.net/" }' + # - name: create kubernetes secret (managed identity client id) + # uses: Azure/k8s-create-secret@v3.0 + # 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 + # uses: cschleiden/replace-tokens@v1.2 + # with: + # tokenPrefix: "{" + # tokenSuffix: "}" + # files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + # env: + # ENVIRONMENT: ${{ secrets.ENVIRONMENT }} + # - name: lint deployment manifest + # uses: azure/k8s-lint@v1 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + # - name: apply deployment manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + # images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + # imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} + # force: true + # - name: apply service manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Service.yaml + # force: true + # # create the ingress controller + # - name: create ingress controller + # run: | + # az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + # ${{ 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 nginx-ingress ingress-nginx/ingress-nginx \ + # --set controller.replicaCount=1 \ + # --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \ + # --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \ + # --set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux \ + # --set controller.service.externalTrafficPolicy=Local + # - name: set dns label on public ip + # uses: azure/CLI@v1 + # with: + # inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) + # # hack: extract the full fqdn / dns label of the aks app's public IP address + # - name: get aks-fqdn + # 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 }})" >> $GITHUB_OUTPUT + # # install cert-manager + # - name: apply namespace manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Namespace.yaml + # force: true + # - name: install cert-manager + # run: | + # az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + # kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml + # - name: apply clusterIssuer manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterIssuer.yaml + # force: true + # - name: substitute tokens in certificate manifest + # uses: cschleiden/replace-tokens@v1.2 + # with: + # tokenPrefix: "{" + # tokenSuffix: "}" + # files: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml + # env: + # AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} + # - name: apply certificate manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml + # force: true + # - name: substitute tokens in ingress manifest + # uses: cschleiden/replace-tokens@v1.2 + # with: + # tokenPrefix: "{" + # tokenSuffix: "}" + # files: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml + # env: + # AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} + # - name: apply ingress manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml + # force: true + # - name: apply clusterRole manifest + # uses: Azure/k8s-deploy@v4 + # with: + # manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterRole.yaml + # force: true + # - name: set productsApiEndpoint in kv + # uses: azure/CLI@v1 + # with: + # inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" + + # deploy-ui: + # runs-on: ubuntu-latest + # needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] + # steps: + # - name: checkout code + # uses: actions/checkout@v3 + # - name: azure login + # uses: azure/login@v1 + # with: + # creds: ${{ secrets.SERVICEPRINCIPAL }} + # - name: get carts api endpoint + # uses: azure/CLI@v1 + # id: get-cartsApiEndpoint + # with: + # inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + # - name: get products api endpoint + # uses: azure/CLI@v1 + # id: get-productsApiEndpoint + # with: + # inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + # - name: substitute tokens in ui configuration + # uses: cschleiden/replace-tokens@v1.2 + # with: + # tokenPrefix: "{{" + # tokenSuffix: "}}" + # files: ./src/ContosoTraders.Ui.Website/.env + # env: + # CARTS_API_ENDPOINT: ${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }} + # PRODUCTS_API_ENDPOINT: ${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }} + # - name: npm install + # run: npm install + # working-directory: src/ContosoTraders.Ui.Website + # - name: npm run build + # run: npm run build + # working-directory: src/ContosoTraders.Ui.Website + # - name: deploy to storage + # uses: azure/CLI@v1 + # with: + # inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' + # - name: purge CDN endpoint + # uses: azure/CLI@v1 + # with: + # inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' diff --git a/.github/workflows/templates/template.yml b/.github/workflows/templates/template.yml new file mode 100644 index 0000000..79255ae --- /dev/null +++ b/.github/workflows/templates/template.yml @@ -0,0 +1,341 @@ +name: template + +on: + workflow_call: + secrets: + ENVIRONMENT: + required: true + +env: + # You can specify any location for `SUB_DEPLOYMENT_REGION`. It's the region where the deployment + # metadata will be stored, and not where the resource groups will be deployed. + ACR_NAME: contosotradersacr + AKS_CLUSTER_NAME: contoso-traders-aks + AKS_DNS_LABEL: contoso-traders-products + AKS_NODES_RESOURCE_GROUP_NAME: contoso-traders-aks-nodes-rg + 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 + CARTS_ACA_NAME: contoso-traders-carts + CARTS_ACR_REPOSITORY_NAME: contosotradersapicarts + CDN_PROFILE_NAME: contoso-traders-cdn + SUB_DEPLOYMENT_REGION: eastus2 + KV_NAME: contosotraderskv + 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 + +jobs: + provision-infrastructure: + runs-on: ubuntu-latest + environment: ${{ secrets.ENVIRONMENT }} + steps: + - name: checkout code + uses: actions/checkout@v3 + - name: azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.SERVICEPRINCIPAL }} + # 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: Azure/arm-deploy@v1 + with: + scope: subscription + region: ${{ env.SUB_DEPLOYMENT_REGION }} + template: ./iac/createResourceGroup.bicep + # 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. + - name: create resources + uses: Azure/arm-deploy@v1 + with: + scope: resourcegroup + region: ${{ env.SUB_DEPLOYMENT_REGION }} + resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} + template: ./iac/createResources.bicep + parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} + failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. + # Add the logged-in service principal to the key vault access policy + - name: add service principal to kv access policy + uses: azure/CLI@v1 + with: + inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --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: azure/CLI@v1 + with: + inlineScript: | + az vmss identity assign \ + --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "id" -o tsv) \ + --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ + # Seed the DBs and storage accounts + - name: seed products db + uses: azure/sql-action@v2 + with: + connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; + path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql + - name: seed product image (product details) + uses: azure/CLI@v1 + with: + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' + - name: seed product image (product list) + uses: azure/CLI@v1 + with: + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' + - name: purge CDN endpoint + uses: azure/CLI@v1 + with: + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' + + deploy-carts-api: + runs-on: ubuntu-latest + environment: ${{ secrets.ENVIRONMENT }} + needs: provision-infrastructure + steps: + - name: checkout code + uses: actions/checkout@v3 + - name: azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.SERVICEPRINCIPAL }} + - name: extract acr password + uses: azure/CLI@v1 + id: extract-acr-password + with: + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + - name: azure container registry login + uses: azure/docker-login@v1 + with: + login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + password: ${{ steps.extract-acr-password.outputs.acrPassword }} + - name: docker build + run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + - name: docker push (to acr) + run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} + - name: deploy to aca + uses: azure/CLI@v1 + with: + inlineScript: | + az config set extension.use_dynamic_install=yes_without_prompt + az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + + deploy-products-api: + runs-on: ubuntu-latest + environment: ${{ secrets.ENVIRONMENT }} + needs: provision-infrastructure + steps: + - name: checkout code + uses: actions/checkout@v3 + - name: azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.SERVICEPRINCIPAL }} + - name: install helm + uses: Azure/setup-helm@v3 + id: install-helm + - name: extract acr password + uses: azure/CLI@v1 + id: extract-acr-password + with: + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + - name: azure container registry login + uses: azure/docker-login@v1 + with: + login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + password: ${{ steps.extract-acr-password.outputs.acrPassword }} + - name: docker build + run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + - name: docker push (to acr) + run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} + - name: set aks context + uses: azure/aks-set-context@v3 + with: + resource-group: ${{ env.RESOURCE_GROUP_NAME }} + cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + - name: setup kubectl + uses: azure/setup-kubectl@v3 + - name: create kubernetes secret (acr password) + uses: Azure/k8s-create-secret@v3.0 + with: + secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} + container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io + container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} + - name: get managedIdentityClientId + uses: azure/CLI@v1 + id: get-managedIdentityClientId + with: + inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT + - name: create kubernetes secret (kv endpoint) + uses: Azure/k8s-create-secret@v3.0 + with: + secret-type: "generic" + secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} + string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }}.vault.azure.net/" }' + - name: create kubernetes secret (managed identity client id) + uses: Azure/k8s-create-secret@v3.0 + 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 + uses: cschleiden/replace-tokens@v1.2 + with: + tokenPrefix: "{" + tokenSuffix: "}" + files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + env: + ENVIRONMENT: ${{ secrets.ENVIRONMENT }} + - name: lint deployment manifest + uses: azure/k8s-lint@v1 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + - name: apply deployment manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml + images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} + force: true + - name: apply service manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Service.yaml + force: true + # create the ingress controller + - name: create ingress controller + run: | + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + ${{ 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 nginx-ingress ingress-nginx/ingress-nginx \ + --set controller.replicaCount=1 \ + --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \ + --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \ + --set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux \ + --set controller.service.externalTrafficPolicy=Local + - name: set dns label on public ip + uses: azure/CLI@v1 + with: + inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) + # hack: extract the full fqdn / dns label of the aks app's public IP address + - name: get aks-fqdn + 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 }})" >> $GITHUB_OUTPUT + # install cert-manager + - name: apply namespace manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Namespace.yaml + force: true + - name: install cert-manager + run: | + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml + - name: apply clusterIssuer manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterIssuer.yaml + force: true + - name: substitute tokens in certificate manifest + uses: cschleiden/replace-tokens@v1.2 + with: + tokenPrefix: "{" + tokenSuffix: "}" + files: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml + env: + AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} + - name: apply certificate manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml + force: true + - name: substitute tokens in ingress manifest + uses: cschleiden/replace-tokens@v1.2 + with: + tokenPrefix: "{" + tokenSuffix: "}" + files: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml + env: + AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} + - name: apply ingress manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml + force: true + - name: apply clusterRole manifest + uses: Azure/k8s-deploy@v4 + with: + manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterRole.yaml + force: true + - name: set productsApiEndpoint in kv + uses: azure/CLI@v1 + with: + inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" + + deploy-ui: + runs-on: ubuntu-latest + environment: ${{ secrets.ENVIRONMENT }} + needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] + steps: + - name: checkout code + uses: actions/checkout@v3 + - name: azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.SERVICEPRINCIPAL }} + - name: get carts api endpoint + uses: azure/CLI@v1 + id: get-cartsApiEndpoint + with: + inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + - name: get products api endpoint + uses: azure/CLI@v1 + id: get-productsApiEndpoint + with: + inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + - name: substitute tokens in ui configuration + uses: cschleiden/replace-tokens@v1.2 + with: + tokenPrefix: "{{" + tokenSuffix: "}}" + files: ./src/ContosoTraders.Ui.Website/.env + env: + CARTS_API_ENDPOINT: ${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }} + PRODUCTS_API_ENDPOINT: ${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }} + - name: npm install + run: npm install + working-directory: src/ContosoTraders.Ui.Website + - name: npm run build + run: npm run build + working-directory: src/ContosoTraders.Ui.Website + - name: deploy to storage + uses: azure/CLI@v1 + with: + inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' + - name: purge CDN endpoint + uses: azure/CLI@v1 + with: + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' From 055a1016d52a2f3266124af51c8b37b2c921fae2 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:09:46 +0530 Subject: [PATCH 03/23] change env names --- .github/workflows/contoso-traders-provisioning-deployment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 92a65b0..0d03062 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -46,7 +46,7 @@ jobs: a-job: strategy: matrix: - environment: [test, prod] + environment: [TEST, PROD] runs-on: ubuntu-latest steps: - name: checkout code From 06edb6c78ea759e3a0c3efbcd65134853530f901 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:10:44 +0530 Subject: [PATCH 04/23] update --- .github/workflows/contoso-traders-provisioning-deployment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 0d03062..d4da920 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -48,6 +48,7 @@ jobs: matrix: environment: [TEST, PROD] runs-on: ubuntu-latest + environment: ${{ matrix.environment }} steps: - name: checkout code uses: actions/checkout@v3 From 44012bb047f28a2dfb455646135042370a4adea3 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:33:10 +0530 Subject: [PATCH 05/23] update --- .../contoso-traders-provisioning-deployment.yml | 10 ++++------ .github/workflows/templates/template2.yml | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/templates/template2.yml diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index d4da920..f08b7da 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -43,15 +43,13 @@ on: # USER_ASSIGNED_MANAGED_IDENTITY_NAME: contoso-traders-mi-kv-access jobs: - a-job: + provision-and-deploy: strategy: matrix: environment: [TEST, PROD] - runs-on: ubuntu-latest - environment: ${{ matrix.environment }} - steps: - - name: checkout code - uses: actions/checkout@v3 + uses: ./templates/template.yml + with: + environment: ${{ matrix.environment }} # provision-infrastructure: # runs-on: ubuntu-latest diff --git a/.github/workflows/templates/template2.yml b/.github/workflows/templates/template2.yml new file mode 100644 index 0000000..dd308ba --- /dev/null +++ b/.github/workflows/templates/template2.yml @@ -0,0 +1,15 @@ +name: template2 + +on: + workflow_call: + secrets: + ENVIRONMENT: + required: true + +jobs: + provision-infrastructure: + runs-on: ubuntu-latest + environment: ${{ inputs.ENVIRONMENT }} + steps: + - name: checkout code + uses: actions/checkout@v3 From ab01ebb3eac4d3e0e3ff4ebe070f8fe907ef6678 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:34:20 +0530 Subject: [PATCH 06/23] update --- .github/workflows/contoso-traders-provisioning-deployment.yml | 4 ++-- .github/workflows/templates/template2.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index f08b7da..f795e4d 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -46,10 +46,10 @@ jobs: provision-and-deploy: strategy: matrix: - environment: [TEST, PROD] + ENVIRONMENT: [TEST, PROD] uses: ./templates/template.yml with: - environment: ${{ matrix.environment }} + ENVIRONMENT: ${{ matrix.environment }} # provision-infrastructure: # runs-on: ubuntu-latest diff --git a/.github/workflows/templates/template2.yml b/.github/workflows/templates/template2.yml index dd308ba..2c2d7d2 100644 --- a/.github/workflows/templates/template2.yml +++ b/.github/workflows/templates/template2.yml @@ -2,9 +2,10 @@ name: template2 on: workflow_call: - secrets: + inputs: ENVIRONMENT: required: true + type: string jobs: provision-infrastructure: From e153ee297abce45d41edbea040432c0013c79a8a Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:38:43 +0530 Subject: [PATCH 07/23] updated path --- .github/workflows/contoso-traders-provisioning-deployment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index f795e4d..1ffdb9b 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -47,7 +47,7 @@ jobs: strategy: matrix: ENVIRONMENT: [TEST, PROD] - uses: ./templates/template.yml + uses: ./.github/workflows/templates/template.yml with: ENVIRONMENT: ${{ matrix.environment }} From 84b5857b483612ebe53c01ca567c67ec23327ff1 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:40:07 +0530 Subject: [PATCH 08/23] top level reusable workflow --- .github/workflows/contoso-traders-provisioning-deployment.yml | 2 +- .github/workflows/{templates => }/template2.yml | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{templates => }/template2.yml (100%) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 1ffdb9b..2d5bf0c 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -47,7 +47,7 @@ jobs: strategy: matrix: ENVIRONMENT: [TEST, PROD] - uses: ./.github/workflows/templates/template.yml + uses: ./.github/workflows/template2.yml with: ENVIRONMENT: ${{ matrix.environment }} diff --git a/.github/workflows/templates/template2.yml b/.github/workflows/template2.yml similarity index 100% rename from .github/workflows/templates/template2.yml rename to .github/workflows/template2.yml From 0dadb14f90d2e84e4ebf424fd782c515099ecf1c Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:43:43 +0530 Subject: [PATCH 09/23] adjust reusable template --- .../contoso-traders-provisioning-deployment.yml | 2 +- .github/workflows/{templates => }/template.yml | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) rename .github/workflows/{templates => }/template.yml (98%) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 2d5bf0c..ead8d28 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -47,7 +47,7 @@ jobs: strategy: matrix: ENVIRONMENT: [TEST, PROD] - uses: ./.github/workflows/template2.yml + uses: ./.github/workflows/template.yml with: ENVIRONMENT: ${{ matrix.environment }} diff --git a/.github/workflows/templates/template.yml b/.github/workflows/template.yml similarity index 98% rename from .github/workflows/templates/template.yml rename to .github/workflows/template.yml index 79255ae..41aded3 100644 --- a/.github/workflows/templates/template.yml +++ b/.github/workflows/template.yml @@ -2,9 +2,10 @@ name: template on: workflow_call: - secrets: + inputs: ENVIRONMENT: required: true + type: string env: # You can specify any location for `SUB_DEPLOYMENT_REGION`. It's the region where the deployment @@ -38,7 +39,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: ${{ secrets.ENVIRONMENT }} + environment: ${{ inputs.ENVIRONMENT }} steps: - name: checkout code uses: actions/checkout@v3 @@ -106,7 +107,7 @@ jobs: deploy-carts-api: runs-on: ubuntu-latest - environment: ${{ secrets.ENVIRONMENT }} + environment: ${{ inputs.ENVIRONMENT }} needs: provision-infrastructure steps: - name: checkout code @@ -139,7 +140,7 @@ jobs: deploy-products-api: runs-on: ubuntu-latest - environment: ${{ secrets.ENVIRONMENT }} + environment: ${{ inputs.ENVIRONMENT }} needs: provision-infrastructure steps: - name: checkout code @@ -297,7 +298,7 @@ jobs: deploy-ui: runs-on: ubuntu-latest - environment: ${{ secrets.ENVIRONMENT }} + environment: ${{ inputs.ENVIRONMENT }} needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] steps: - name: checkout code From a401d1d95c4508101be85939e0957d36c76be610 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:52:40 +0530 Subject: [PATCH 10/23] echo env name --- .github/workflows/template.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml index 41aded3..a8f73ac 100644 --- a/.github/workflows/template.yml +++ b/.github/workflows/template.yml @@ -41,6 +41,7 @@ jobs: runs-on: ubuntu-latest environment: ${{ inputs.ENVIRONMENT }} steps: + - run: echo ${{ inputs.ENVIRONMENT }} - name: checkout code uses: actions/checkout@v3 - name: azure login From ccb030a57bc2ee8773a1207b05e281f6b9bc7ee8 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 18:57:15 +0530 Subject: [PATCH 11/23] test --- .github/workflows/template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml index a8f73ac..f6d87e1 100644 --- a/.github/workflows/template.yml +++ b/.github/workflows/template.yml @@ -39,7 +39,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: TEST #${{ inputs.ENVIRONMENT }} steps: - run: echo ${{ inputs.ENVIRONMENT }} - name: checkout code From 75c4ec7923a6875062204a231ae4f76543cb0bd8 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:01:37 +0530 Subject: [PATCH 12/23] update --- .github/workflows/template.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml index f6d87e1..14d7cd7 100644 --- a/.github/workflows/template.yml +++ b/.github/workflows/template.yml @@ -39,7 +39,8 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: TEST #${{ inputs.ENVIRONMENT }} + environment: + name: ${{ inputs.ENVIRONMENT }} steps: - run: echo ${{ inputs.ENVIRONMENT }} - name: checkout code From 42d6b2294016fc81110e7ee00adbac1d0dc21b0e Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:12:01 +0530 Subject: [PATCH 13/23] inherit secrets --- .github/workflows/contoso-traders-provisioning-deployment.yml | 1 + .github/workflows/template.yml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index ead8d28..87e42c5 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -48,6 +48,7 @@ jobs: matrix: ENVIRONMENT: [TEST, PROD] uses: ./.github/workflows/template.yml + secrets: inherit with: ENVIRONMENT: ${{ matrix.environment }} diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml index 14d7cd7..a8f73ac 100644 --- a/.github/workflows/template.yml +++ b/.github/workflows/template.yml @@ -39,8 +39,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: - name: ${{ inputs.ENVIRONMENT }} + environment: ${{ inputs.ENVIRONMENT }} steps: - run: echo ${{ inputs.ENVIRONMENT }} - name: checkout code From b55a8c2f907aaaf71dc33a0e0656d09560c0ec24 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:17:01 +0530 Subject: [PATCH 14/23] update template name --- ...ders-provisioning-deployment-template.yml} | 0 ...ontoso-traders-provisioning-deployment.yml | 331 +----------------- .github/workflows/template2.yml | 16 - 3 files changed, 1 insertion(+), 346 deletions(-) rename .github/workflows/{template.yml => contoso-traders-provisioning-deployment-template.yml} (100%) delete mode 100644 .github/workflows/template2.yml diff --git a/.github/workflows/template.yml b/.github/workflows/contoso-traders-provisioning-deployment-template.yml similarity index 100% rename from .github/workflows/template.yml rename to .github/workflows/contoso-traders-provisioning-deployment-template.yml diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 87e42c5..3e192c6 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -13,341 +13,12 @@ on: "src/ContosoTraders.Ui.Website/**", ] -# env: -# # You can specify any location for `SUB_DEPLOYMENT_REGION`. It's the region where the deployment -# # metadata will be stored, and not where the resource groups will be deployed. -# ACR_NAME: contosotradersacr -# AKS_CLUSTER_NAME: contoso-traders-aks -# AKS_DNS_LABEL: contoso-traders-products -# AKS_NODES_RESOURCE_GROUP_NAME: contoso-traders-aks-nodes-rg -# 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 -# CARTS_ACA_NAME: contoso-traders-carts -# CARTS_ACR_REPOSITORY_NAME: contosotradersapicarts -# CDN_PROFILE_NAME: contoso-traders-cdn -# SUB_DEPLOYMENT_REGION: eastus2 -# KV_NAME: contosotraderskv -# 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 - jobs: provision-and-deploy: strategy: matrix: ENVIRONMENT: [TEST, PROD] - uses: ./.github/workflows/template.yml + uses: ./.github/workflows/contoso-traders-provisioning-deployment-template.yml secrets: inherit with: ENVIRONMENT: ${{ matrix.environment }} - - # provision-infrastructure: - # runs-on: ubuntu-latest - # steps: - # - name: checkout code - # uses: actions/checkout@v3 - # - name: azure login - # uses: azure/login@v1 - # with: - # creds: ${{ secrets.SERVICEPRINCIPAL }} - # # 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: Azure/arm-deploy@v1 - # with: - # scope: subscription - # region: ${{ env.SUB_DEPLOYMENT_REGION }} - # template: ./iac/createResourceGroup.bicep - # # 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. - # - name: create resources - # uses: Azure/arm-deploy@v1 - # with: - # scope: resourcegroup - # region: ${{ env.SUB_DEPLOYMENT_REGION }} - # resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} - # template: ./iac/createResources.bicep - # parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} - # failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. - # # Add the logged-in service principal to the key vault access policy - # - name: add service principal to kv access policy - # uses: azure/CLI@v1 - # with: - # inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --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: azure/CLI@v1 - # with: - # inlineScript: | - # az vmss identity assign \ - # --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "id" -o tsv) \ - # --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ - # # Seed the DBs and storage accounts - # - name: seed products db - # uses: azure/sql-action@v2 - # with: - # connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; - # path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql - # - name: seed product image (product details) - # uses: azure/CLI@v1 - # with: - # inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' - # - name: seed product image (product list) - # uses: azure/CLI@v1 - # with: - # inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' - # - name: purge CDN endpoint - # uses: azure/CLI@v1 - # with: - # inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' - - # deploy-carts-api: - # runs-on: ubuntu-latest - # needs: provision-infrastructure - # steps: - # - name: checkout code - # uses: actions/checkout@v3 - # - name: azure login - # uses: azure/login@v1 - # with: - # creds: ${{ secrets.SERVICEPRINCIPAL }} - # - name: extract acr password - # uses: azure/CLI@v1 - # id: extract-acr-password - # with: - # inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - # - name: azure container registry login - # uses: azure/docker-login@v1 - # with: - # login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - # username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - # password: ${{ steps.extract-acr-password.outputs.acrPassword }} - # - name: docker build - # run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - # - name: docker push (to acr) - # run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} - # - name: deploy to aca - # uses: azure/CLI@v1 - # with: - # inlineScript: | - # az config set extension.use_dynamic_install=yes_without_prompt - # az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - - # deploy-products-api: - # runs-on: ubuntu-latest - # needs: provision-infrastructure - # steps: - # - name: checkout code - # uses: actions/checkout@v3 - # - name: azure login - # uses: azure/login@v1 - # with: - # creds: ${{ secrets.SERVICEPRINCIPAL }} - # - name: install helm - # uses: Azure/setup-helm@v3 - # id: install-helm - # - name: extract acr password - # uses: azure/CLI@v1 - # id: extract-acr-password - # with: - # inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - # - name: azure container registry login - # uses: azure/docker-login@v1 - # with: - # login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - # username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - # password: ${{ steps.extract-acr-password.outputs.acrPassword }} - # - name: docker build - # run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - # - name: docker push (to acr) - # run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} - # - name: set aks context - # uses: azure/aks-set-context@v3 - # with: - # resource-group: ${{ env.RESOURCE_GROUP_NAME }} - # cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - # - name: setup kubectl - # uses: azure/setup-kubectl@v3 - # - name: create kubernetes secret (acr password) - # uses: Azure/k8s-create-secret@v3.0 - # with: - # secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - # container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - # container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} - # container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} - # - name: get managedIdentityClientId - # uses: azure/CLI@v1 - # id: get-managedIdentityClientId - # with: - # inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT - # - name: create kubernetes secret (kv endpoint) - # uses: Azure/k8s-create-secret@v3.0 - # with: - # secret-type: "generic" - # secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} - # string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }}.vault.azure.net/" }' - # - name: create kubernetes secret (managed identity client id) - # uses: Azure/k8s-create-secret@v3.0 - # 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 - # uses: cschleiden/replace-tokens@v1.2 - # with: - # tokenPrefix: "{" - # tokenSuffix: "}" - # files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - # env: - # ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - # - name: lint deployment manifest - # uses: azure/k8s-lint@v1 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - # - name: apply deployment manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - # images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - # imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - # force: true - # - name: apply service manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Service.yaml - # force: true - # # create the ingress controller - # - name: create ingress controller - # run: | - # az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - # ${{ 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 nginx-ingress ingress-nginx/ingress-nginx \ - # --set controller.replicaCount=1 \ - # --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \ - # --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \ - # --set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux \ - # --set controller.service.externalTrafficPolicy=Local - # - name: set dns label on public ip - # uses: azure/CLI@v1 - # with: - # inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) - # # hack: extract the full fqdn / dns label of the aks app's public IP address - # - name: get aks-fqdn - # 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 }})" >> $GITHUB_OUTPUT - # # install cert-manager - # - name: apply namespace manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Namespace.yaml - # force: true - # - name: install cert-manager - # run: | - # az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} - # kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml - # - name: apply clusterIssuer manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterIssuer.yaml - # force: true - # - name: substitute tokens in certificate manifest - # uses: cschleiden/replace-tokens@v1.2 - # with: - # tokenPrefix: "{" - # tokenSuffix: "}" - # files: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml - # env: - # AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} - # - name: apply certificate manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Certificate.yaml - # force: true - # - name: substitute tokens in ingress manifest - # uses: cschleiden/replace-tokens@v1.2 - # with: - # tokenPrefix: "{" - # tokenSuffix: "}" - # files: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml - # env: - # AKS_FQDN: ${{ steps.get-aks-fqdn.outputs.aksFqdn }} - # - name: apply ingress manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/Ingress.yaml - # force: true - # - name: apply clusterRole manifest - # uses: Azure/k8s-deploy@v4 - # with: - # manifests: ./src/ContosoTraders.Api.Products/Manifests/ClusterRole.yaml - # force: true - # - name: set productsApiEndpoint in kv - # uses: azure/CLI@v1 - # with: - # inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" - - # deploy-ui: - # runs-on: ubuntu-latest - # needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] - # steps: - # - name: checkout code - # uses: actions/checkout@v3 - # - name: azure login - # uses: azure/login@v1 - # with: - # creds: ${{ secrets.SERVICEPRINCIPAL }} - # - name: get carts api endpoint - # uses: azure/CLI@v1 - # id: get-cartsApiEndpoint - # with: - # inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - # - name: get products api endpoint - # uses: azure/CLI@v1 - # id: get-productsApiEndpoint - # with: - # inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - # - name: substitute tokens in ui configuration - # uses: cschleiden/replace-tokens@v1.2 - # with: - # tokenPrefix: "{{" - # tokenSuffix: "}}" - # files: ./src/ContosoTraders.Ui.Website/.env - # env: - # CARTS_API_ENDPOINT: ${{ steps.get-cartsApiEndpoint.outputs.cartsApiEndpoint }} - # PRODUCTS_API_ENDPOINT: ${{ steps.get-productsApiEndpoint.outputs.productsApiEndpoint }} - # - name: npm install - # run: npm install - # working-directory: src/ContosoTraders.Ui.Website - # - name: npm run build - # run: npm run build - # working-directory: src/ContosoTraders.Ui.Website - # - name: deploy to storage - # uses: azure/CLI@v1 - # with: - # inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' - # - name: purge CDN endpoint - # uses: azure/CLI@v1 - # with: - # inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' diff --git a/.github/workflows/template2.yml b/.github/workflows/template2.yml deleted file mode 100644 index 2c2d7d2..0000000 --- a/.github/workflows/template2.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: template2 - -on: - workflow_call: - inputs: - ENVIRONMENT: - required: true - type: string - -jobs: - provision-infrastructure: - runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} - steps: - - name: checkout code - uses: actions/checkout@v3 From a48263a3c15eece2f36762df8abafd6b62253ce3 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:42:56 +0530 Subject: [PATCH 15/23] resource suffix is lowercased environment name --- iac/createResources.bicep | 58 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/iac/createResources.bicep b/iac/createResources.bicep index 2091a13..8005c63 100644 --- a/iac/createResources.bicep +++ b/iac/createResources.bicep @@ -29,8 +29,10 @@ param prefixHyphenated string = 'contoso-traders' // variables //////////////////////////////////////////////////////////////////////////////// +var suffix = toLower(environment) + // key vault -var kvName = '${prefix}kv${environment}' +var kvName = '${prefix}kv${suffix}' var kvSecretNameProductsApiEndpoint = 'productsApiEndpoint' var kvSecretNameProductsDbConnStr = 'productsDbConnectionString' var kvSecretNameProfilesDbConnStr = 'profilesDbConnectionString' @@ -43,89 +45,89 @@ var kvSecretNameCognitiveServicesAccountKey = 'cognitiveServicesAccountKey' var kvSecretNameAppInsightsConnStr = 'appInsightsConnectionString' // user-assigned managed identity (for key vault access) -var userAssignedMIForKVAccessName = '${prefixHyphenated}-mi-kv-access${environment}' +var userAssignedMIForKVAccessName = '${prefixHyphenated}-mi-kv-access${suffix}' // cosmos db (stocks db) -var stocksDbAcctName = '${prefixHyphenated}-stocks${environment}' +var stocksDbAcctName = '${prefixHyphenated}-stocks${suffix}' var stocksDbName = 'stocksdb' var stocksDbStocksContainerName = 'stocks' // cosmos db (carts db) -var cartsDbAcctName = '${prefixHyphenated}-carts${environment}' +var cartsDbAcctName = '${prefixHyphenated}-carts${suffix}' var cartsDbName = 'cartsdb' var cartsDbStocksContainerName = 'carts' // app service plan (products api) -var productsApiAppSvcPlanName = '${prefixHyphenated}-products${environment}' -var productsApiAppSvcName = '${prefixHyphenated}-products${environment}' +var productsApiAppSvcPlanName = '${prefixHyphenated}-products${suffix}' +var productsApiAppSvcName = '${prefixHyphenated}-products${suffix}' var productsApiSettingNameKeyVaultEndpoint = 'KeyVaultEndpoint' var productsApiSettingNameManagedIdentityClientId = 'ManagedIdentityClientId' // sql azure (products db) -var productsDbServerName = '${prefixHyphenated}-products${environment}' +var productsDbServerName = '${prefixHyphenated}-products${suffix}' var productsDbName = 'productsdb' var productsDbServerAdminLogin = 'localadmin' var productsDbServerAdminPassword = sqlPassword // sql azure (profiles db) -var profilesDbServerName = '${prefixHyphenated}-profiles${environment}' +var profilesDbServerName = '${prefixHyphenated}-profiles${suffix}' var profilesDbName = 'profilesdb' var profilesDbServerAdminLogin = 'localadmin' var profilesDbServerAdminPassword = sqlPassword // azure container app (carts api) -var cartsApiAcaName = '${prefixHyphenated}-carts${environment}' -var cartsApiAcaEnvName = '${prefix}acaenv${environment}' +var cartsApiAcaName = '${prefixHyphenated}-carts${suffix}' +var cartsApiAcaEnvName = '${prefix}acaenv${suffix}' var cartsApiAcaSecretAcrPassword = 'acr-password' -var cartsApiAcaContainerDetailsName = '${prefixHyphenated}-carts${environment}' +var cartsApiAcaContainerDetailsName = '${prefixHyphenated}-carts${suffix}' var cartsApiSettingNameKeyVaultEndpoint = 'KeyVaultEndpoint' var cartsApiSettingNameManagedIdentityClientId = 'ManagedIdentityClientId' // storage account (product images) -var productImagesStgAccName = '${prefix}img${environment}' +var productImagesStgAccName = '${prefix}img${suffix}' var productImagesProductDetailsContainerName = 'product-details' var productImagesProductListContainerName = 'product-list' // storage account (old website) -var uiStgAccName = '${prefix}ui${environment}' +var uiStgAccName = '${prefix}ui${suffix}' // storage account (new website) -var ui2StgAccName = '${prefix}ui2${environment}' +var ui2StgAccName = '${prefix}ui2${suffix}' // storage account (image classifier) -var imageClassifierStgAccName = '${prefix}ic${environment}' +var imageClassifierStgAccName = '${prefix}ic${suffix}' var imageClassifierWebsiteUploadsContainerName = 'website-uploads' // cognitive service (image recognition) -var cognitiveServiceName = '${prefixHyphenated}-cs${environment}' +var cognitiveServiceName = '${prefixHyphenated}-cs${suffix}' // cdn -var cdnProfileName = '${prefixHyphenated}-cdn${environment}' -var cdnImagesEndpointName = '${prefixHyphenated}-images${environment}' -var cdnUiEndpointName = '${prefixHyphenated}-ui${environment}' -var cdnUi2EndpointName = '${prefixHyphenated}-ui2${environment}' +var cdnProfileName = '${prefixHyphenated}-cdn${suffix}' +var cdnImagesEndpointName = '${prefixHyphenated}-images${suffix}' +var cdnUiEndpointName = '${prefixHyphenated}-ui${suffix}' +var cdnUi2EndpointName = '${prefixHyphenated}-ui2${suffix}' // redis cache -var redisCacheName = '${prefixHyphenated}-cache${environment}' +var redisCacheName = '${prefixHyphenated}-cache${suffix}' // azure container registry -var acrName = '${prefix}acr${environment}' +var acrName = '${prefix}acr${suffix}' // var acrCartsApiRepositoryName = '${prefix}apicarts' // @TODO: unused, probably remove later // load testing service -var loadTestSvcName = '${prefixHyphenated}-loadtest${environment}' +var loadTestSvcName = '${prefixHyphenated}-loadtest${suffix}' // application insights -var logAnalyticsWorkspaceName = '${prefixHyphenated}-loganalytics${environment}' -var appInsightsName = '${prefixHyphenated}-ai${environment}' +var logAnalyticsWorkspaceName = '${prefixHyphenated}-loganalytics${suffix}' +var appInsightsName = '${prefixHyphenated}-ai${suffix}' // portal dashboard -var portalDashboardName = '${prefixHyphenated}-dashboard${environment}' +var portalDashboardName = '${prefixHyphenated}-dashboard${suffix}' // aks cluster -var aksClusterName = '${prefixHyphenated}-aks${environment}' -var aksClusterDnsPrefix = '${prefixHyphenated}-aks${environment}' +var aksClusterName = '${prefixHyphenated}-aks${suffix}' +var aksClusterDnsPrefix = '${prefixHyphenated}-aks${suffix}' var aksClusterNodeResourceGroup = '${prefixHyphenated}-aks-nodes-rg' // tags From 1b5744398cdda346b95487b108c88562882dbb5b Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:43:33 +0530 Subject: [PATCH 16/23] cosmetic update --- iac/createResources.bicep | 1 + 1 file changed, 1 insertion(+) diff --git a/iac/createResources.bicep b/iac/createResources.bicep index 8005c63..19da589 100644 --- a/iac/createResources.bicep +++ b/iac/createResources.bicep @@ -29,6 +29,7 @@ param prefixHyphenated string = 'contoso-traders' // variables //////////////////////////////////////////////////////////////////////////////// +// common var suffix = toLower(environment) // key vault From be1c0ca2a0135c1ac1d82fb79cb719f6de1997b3 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 19:50:07 +0530 Subject: [PATCH 17/23] remove redundant secret for environment name --- ...aders-provisioning-deployment-template.yml | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment-template.yml b/.github/workflows/contoso-traders-provisioning-deployment-template.yml index a8f73ac..09a1cac 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment-template.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment-template.yml @@ -72,39 +72,39 @@ jobs: region: ${{ env.SUB_DEPLOYMENT_REGION }} resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} template: ./iac/createResources.bicep - parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} + parameters: ./iac/createResources.parameters.json environment=${{ inputs.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. # Add the logged-in service principal to the key vault access policy - name: add service principal to kv access policy uses: azure/CLI@v1 with: - inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --secret-permissions get list set --object-id $(az ad sp show --id $(az account show --query "user.name" -o tsv) --query "id" -o tsv) + inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --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: azure/CLI@v1 with: inlineScript: | az vmss identity assign \ - --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "id" -o tsv) \ + --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ inputs.ENVIRONMENT }} --query "id" -o tsv) \ --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ # Seed the DBs and storage accounts - name: seed products db uses: azure/sql-action@v2 with: - connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; + connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ inputs.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql - name: seed product image (product details) uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' - name: seed product image (product list) uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' - name: purge CDN endpoint uses: azure/CLI@v1 with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ inputs.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ inputs.ENVIRONMENT }}' deploy-carts-api: runs-on: ubuntu-latest @@ -121,23 +121,23 @@ jobs: uses: azure/CLI@v1 id: extract-acr-password with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - name: azure container registry login uses: azure/docker-login@v1 with: - login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + login-server: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} + run: docker push --all-tags ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} - name: deploy to aca uses: azure/CLI@v1 with: inlineScript: | az config set extension.use_dynamic_install=yes_without_prompt - az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} deploy-products-api: runs-on: ubuntu-latest @@ -157,42 +157,42 @@ jobs: uses: azure/CLI@v1 id: extract-acr-password with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - name: azure container registry login uses: azure/docker-login@v1 with: - login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + login-server: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} + run: docker push --all-tags ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} - name: set aks context uses: azure/aks-set-context@v3 with: resource-group: ${{ env.RESOURCE_GROUP_NAME }} - cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} - name: setup kubectl uses: azure/setup-kubectl@v3 - name: create kubernetes secret (acr password) uses: Azure/k8s-create-secret@v3.0 with: secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io - container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }} + container-registry-url: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io + container-registry-username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: get managedIdentityClientId uses: azure/CLI@v1 id: get-managedIdentityClientId with: - inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ inputs.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT - name: create kubernetes secret (kv endpoint) uses: Azure/k8s-create-secret@v3.0 with: secret-type: "generic" secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} - string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }}.vault.azure.net/" }' + string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }}.vault.azure.net/" }' - name: create kubernetes secret (managed identity client id) uses: Azure/k8s-create-secret@v3.0 with: @@ -206,7 +206,7 @@ jobs: tokenSuffix: "}" files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} + ENVIRONMENT: ${{ inputs.ENVIRONMENT }} - name: lint deployment manifest uses: azure/k8s-lint@v1 with: @@ -215,7 +215,7 @@ jobs: uses: Azure/k8s-deploy@v4 with: manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + images: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} force: true - name: apply service manifest @@ -226,7 +226,7 @@ jobs: # create the ingress controller - name: create ingress controller run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} ${{ 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 nginx-ingress ingress-nginx/ingress-nginx \ @@ -238,7 +238,7 @@ jobs: - name: set dns label on public ip uses: azure/CLI@v1 with: - inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) + inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ inputs.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) # hack: extract the full fqdn / dns label of the aks app's public IP address - name: get aks-fqdn uses: azure/CLI@v1 @@ -254,7 +254,7 @@ jobs: force: true - name: install cert-manager run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT }} + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml - name: apply clusterIssuer manifest uses: Azure/k8s-deploy@v4 @@ -295,7 +295,7 @@ jobs: - name: set productsApiEndpoint in kv uses: azure/CLI@v1 with: - inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" + inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" deploy-ui: runs-on: ubuntu-latest @@ -312,12 +312,12 @@ jobs: uses: azure/CLI@v1 id: get-cartsApiEndpoint with: - inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - name: get products api endpoint uses: azure/CLI@v1 id: get-productsApiEndpoint with: - inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - name: substitute tokens in ui configuration uses: cschleiden/replace-tokens@v1.2 with: @@ -336,8 +336,8 @@ jobs: - name: deploy to storage uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' + inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' - name: purge CDN endpoint uses: azure/CLI@v1 with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT }}' + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ inputs.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ inputs.ENVIRONMENT }}' From 7218f67e6e4c461acf3d5f2c4c7e2f19df93920f Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 20:09:35 +0530 Subject: [PATCH 18/23] per environment suffix --- ...aders-provisioning-deployment-template.yml | 75 +++++++++---------- ...ontoso-traders-provisioning-deployment.yml | 4 +- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment-template.yml b/.github/workflows/contoso-traders-provisioning-deployment-template.yml index 09a1cac..db8623e 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment-template.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment-template.yml @@ -39,9 +39,8 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: ${{ inputs.environmentName }} steps: - - run: echo ${{ inputs.ENVIRONMENT }} - name: checkout code uses: actions/checkout@v3 - name: azure login @@ -72,43 +71,43 @@ jobs: region: ${{ env.SUB_DEPLOYMENT_REGION }} resourceGroupName: ${{ env.RESOURCE_GROUP_NAME }} template: ./iac/createResources.bicep - parameters: ./iac/createResources.parameters.json environment=${{ inputs.ENVIRONMENT }} sqlPassword=${{ secrets.SQL_PASSWORD }} + parameters: ./iac/createResources.parameters.json environment=${{ secrets.ENVIRONMENT_SUFFIX }} sqlPassword=${{ secrets.SQL_PASSWORD }} failOnStdErr: false # @TODO: Remove this later. Temporarily added to suppress warnings-as-errors during execution. # Add the logged-in service principal to the key vault access policy - name: add service principal to kv access policy uses: azure/CLI@v1 with: - inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --secret-permissions get list set --object-id $(az ad sp show --id $(az account show --query "user.name" -o tsv) --query "id" -o tsv) + inlineScript: az keyvault set-policy -n ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT_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: azure/CLI@v1 with: inlineScript: | az vmss identity assign \ - --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ inputs.ENVIRONMENT }} --query "id" -o tsv) \ + --identities $(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} --query "id" -o tsv) \ --ids $(az vmss list -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} --query "[0].id" -o tsv) \ # Seed the DBs and storage accounts - name: seed products db uses: azure/sql-action@v2 with: - connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ inputs.ENVIRONMENT }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; + connection-string: Server=tcp:${{ env.PRODUCTS_DB_SERVER_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.database.windows.net,1433;Initial Catalog=${{ env.PRODUCTS_DB_NAME }};Persist Security Info=False;User ID=${{ env.PRODUCTS_DB_USER_NAME }};Password=${{ secrets.SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30; path: ./src/ContosoTraders.Api.Products/Migration/productsdb.sql - name: seed product image (product details) uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' -c '${{ env.PRODUCT_DETAILS_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-details' - name: seed product image (product list) uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' + inlineScript: az storage blob sync --account-name '${{ env.PRODUCT_IMAGES_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' -c '${{ env.PRODUCT_LIST_CONTAINER_NAME }}' -s 'src/ContosoTraders.Api.Images/product-list' - name: purge CDN endpoint uses: azure/CLI@v1 with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ inputs.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ inputs.ENVIRONMENT }}' + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.PRODUCTS_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' deploy-carts-api: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: ${{ inputs.environmentName }} needs: provision-infrastructure steps: - name: checkout code @@ -121,27 +120,27 @@ jobs: uses: azure/CLI@v1 id: extract-acr-password with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - name: azure container registry login uses: azure/docker-login@v1 with: - login-server: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} + login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + run: docker build src -f ./src/ContosoTraders.Api.Carts/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} + run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }} - name: deploy to aca uses: azure/CLI@v1 with: inlineScript: | az config set extension.use_dynamic_install=yes_without_prompt - az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + az containerapp update -n ${{ env.CARTS_ACA_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }} --image ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.CARTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} deploy-products-api: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: ${{ inputs.environmentName }} needs: provision-infrastructure steps: - name: checkout code @@ -157,42 +156,42 @@ jobs: uses: azure/CLI@v1 id: extract-acr-password with: - inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "acrPassword"="$(az acr credential show -n ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} -g ${{ env.RESOURCE_GROUP_NAME }} --query "passwords[0].value" --output tsv)" >> $GITHUB_OUTPUT - name: azure container registry login uses: azure/docker-login@v1 with: - login-server: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io - username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} + login-server: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io + username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: docker build - run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + run: docker build src -f ./src/ContosoTraders.Api.Products/Dockerfile -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:latest -t ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} - name: docker push (to acr) - run: docker push --all-tags ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} + run: docker push --all-tags ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }} - name: set aks context uses: azure/aks-set-context@v3 with: resource-group: ${{ env.RESOURCE_GROUP_NAME }} - cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} + cluster-name: ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} - name: setup kubectl uses: azure/setup-kubectl@v3 - name: create kubernetes secret (acr password) uses: Azure/k8s-create-secret@v3.0 with: secret-name: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} - container-registry-url: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io - container-registry-username: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }} + container-registry-url: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io + container-registry-username: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} container-registry-password: ${{ steps.extract-acr-password.outputs.acrPassword }} - name: get managedIdentityClientId uses: azure/CLI@v1 id: get-managedIdentityClientId with: - inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ inputs.ENVIRONMENT }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "managedIdentityClientId"="$(az identity show -g ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.USER_ASSIGNED_MANAGED_IDENTITY_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} --query "clientId" -o tsv)" >> $GITHUB_OUTPUT - name: create kubernetes secret (kv endpoint) uses: Azure/k8s-create-secret@v3.0 with: secret-type: "generic" secret-name: ${{ env.AKS_SECRET_NAME_KV_ENDPOINT }} - string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }}.vault.azure.net/" }' + string-data: '{ "${{ env.AKS_SECRET_NAME_KV_ENDPOINT }}" : "https://${{ env.KV_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.vault.azure.net/" }' - name: create kubernetes secret (managed identity client id) uses: Azure/k8s-create-secret@v3.0 with: @@ -206,7 +205,7 @@ jobs: tokenSuffix: "}" files: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml env: - ENVIRONMENT: ${{ inputs.ENVIRONMENT }} + ENVIRONMENT: ${{ secrets.ENVIRONMENT_SUFFIX }} - name: lint deployment manifest uses: azure/k8s-lint@v1 with: @@ -215,7 +214,7 @@ jobs: uses: Azure/k8s-deploy@v4 with: manifests: ./src/ContosoTraders.Api.Products/Manifests/Deployment.yaml - images: ${{ env.ACR_NAME }}${{ inputs.ENVIRONMENT }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} + images: ${{ env.ACR_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}.azurecr.io/${{ env.PRODUCTS_ACR_REPOSITORY_NAME }}:${{ github.sha }} imagepullsecrets: ${{ env.AKS_SECRET_NAME_ACR_PASSWORD }} force: true - name: apply service manifest @@ -226,7 +225,7 @@ jobs: # create the ingress controller - name: create ingress controller run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT_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 nginx-ingress ingress-nginx/ingress-nginx \ @@ -238,7 +237,7 @@ jobs: - name: set dns label on public ip uses: azure/CLI@v1 with: - inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ inputs.ENVIRONMENT }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) + inlineScript: az network public-ip update --dns-name ${{ env.AKS_DNS_LABEL }}${{ secrets.ENVIRONMENT_SUFFIX }} -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }} -n $(az network public-ip list --query "[?starts_with(name,'kubernetes-') ].name" -o tsv -g ${{ env.AKS_NODES_RESOURCE_GROUP_NAME }}) # hack: extract the full fqdn / dns label of the aks app's public IP address - name: get aks-fqdn uses: azure/CLI@v1 @@ -254,7 +253,7 @@ jobs: force: true - name: install cert-manager run: | - az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ inputs.ENVIRONMENT }} + az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP_NAME }} --name ${{ env.AKS_CLUSTER_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml - name: apply clusterIssuer manifest uses: Azure/k8s-deploy@v4 @@ -295,11 +294,11 @@ jobs: - name: set productsApiEndpoint in kv uses: azure/CLI@v1 with: - inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" + inlineScript: az keyvault secret set --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} --name productsApiEndpoint --value ${{ steps.get-aks-fqdn.outputs.aksFqdn }} --description "endpoint url (fqdn) of the products api" deploy-ui: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: ${{ inputs.environmentName }} needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] steps: - name: checkout code @@ -312,12 +311,12 @@ jobs: uses: azure/CLI@v1 id: get-cartsApiEndpoint with: - inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "cartsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} --name cartsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - name: get products api endpoint uses: azure/CLI@v1 id: get-productsApiEndpoint with: - inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ inputs.ENVIRONMENT }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT + inlineScript: echo "productsApiEndpoint"="$(az keyvault secret show --vault-name ${{ env.KV_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }} --name productsApiEndpoint --query value -o tsv)" >> $GITHUB_OUTPUT - name: substitute tokens in ui configuration uses: cschleiden/replace-tokens@v1.2 with: @@ -336,8 +335,8 @@ jobs: - name: deploy to storage uses: azure/CLI@v1 with: - inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ inputs.ENVIRONMENT }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' + inlineScript: az storage blob sync --account-name '${{ env.UI_STORAGE_ACCOUNT_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' -c '$web' -s 'src/ContosoTraders.Ui.Website/build' - name: purge CDN endpoint uses: azure/CLI@v1 with: - inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ inputs.ENVIRONMENT }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ inputs.ENVIRONMENT }}' + inlineScript: az cdn endpoint purge --no-wait --content-paths '/*' -n '${{ env.UI_CDN_ENDPOINT_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' -g '${{ env.RESOURCE_GROUP_NAME }}' --profile-name '${{ env.CDN_PROFILE_NAME }}${{ secrets.ENVIRONMENT_SUFFIX }}' diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 3e192c6..86cd17b 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -17,8 +17,8 @@ jobs: provision-and-deploy: strategy: matrix: - ENVIRONMENT: [TEST, PROD] + environmentName: [TEST, PROD] uses: ./.github/workflows/contoso-traders-provisioning-deployment-template.yml secrets: inherit with: - ENVIRONMENT: ${{ matrix.environment }} + environmentName: ${{ matrix.environmentName }} From 7ba84876b205a031b2c45b58c61e10be78a17c40 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 20:28:07 +0530 Subject: [PATCH 19/23] environment name --- .../contoso-traders-provisioning-deployment-template.yml | 8 ++++---- .../workflows/contoso-traders-provisioning-deployment.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment-template.yml b/.github/workflows/contoso-traders-provisioning-deployment-template.yml index db8623e..a3aa52d 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment-template.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment-template.yml @@ -39,7 +39,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: ${{ inputs.environmentName }} + environment: ${{ inputs.environment }} steps: - name: checkout code uses: actions/checkout@v3 @@ -107,7 +107,7 @@ jobs: deploy-carts-api: runs-on: ubuntu-latest - environment: ${{ inputs.environmentName }} + environment: ${{ inputs.environment }} needs: provision-infrastructure steps: - name: checkout code @@ -140,7 +140,7 @@ jobs: deploy-products-api: runs-on: ubuntu-latest - environment: ${{ inputs.environmentName }} + environment: ${{ inputs.environment }} needs: provision-infrastructure steps: - name: checkout code @@ -298,7 +298,7 @@ jobs: deploy-ui: runs-on: ubuntu-latest - environment: ${{ inputs.environmentName }} + environment: ${{ inputs.environment }} needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] steps: - name: checkout code diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 86cd17b..04acdfa 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -17,8 +17,8 @@ jobs: provision-and-deploy: strategy: matrix: - environmentName: [TEST, PROD] + environment: [TEST, PROD] uses: ./.github/workflows/contoso-traders-provisioning-deployment-template.yml secrets: inherit with: - environmentName: ${{ matrix.environmentName }} + environment: ${{ matrix.environment }} From 95b8ef7b30fb72dc03d0bb5aa4417acc491a9492 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 20:34:26 +0530 Subject: [PATCH 20/23] env name --- ...ontoso-traders-provisioning-deployment-template.yml | 10 +++++----- .../contoso-traders-provisioning-deployment.yml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/contoso-traders-provisioning-deployment-template.yml b/.github/workflows/contoso-traders-provisioning-deployment-template.yml index a3aa52d..05b0cdd 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment-template.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment-template.yml @@ -3,7 +3,7 @@ name: template on: workflow_call: inputs: - ENVIRONMENT: + environmentName: required: true type: string @@ -39,7 +39,7 @@ env: jobs: provision-infrastructure: runs-on: ubuntu-latest - environment: ${{ inputs.environment }} + environment: ${{ inputs.environmentName }} steps: - name: checkout code uses: actions/checkout@v3 @@ -107,7 +107,7 @@ jobs: deploy-carts-api: runs-on: ubuntu-latest - environment: ${{ inputs.environment }} + environment: ${{ inputs.environmentName }} needs: provision-infrastructure steps: - name: checkout code @@ -140,7 +140,7 @@ jobs: deploy-products-api: runs-on: ubuntu-latest - environment: ${{ inputs.environment }} + environment: ${{ inputs.environmentName }} needs: provision-infrastructure steps: - name: checkout code @@ -298,7 +298,7 @@ jobs: deploy-ui: runs-on: ubuntu-latest - environment: ${{ inputs.environment }} + environment: ${{ inputs.environmentName }} needs: [provision-infrastructure, deploy-carts-api, deploy-products-api] steps: - name: checkout code diff --git a/.github/workflows/contoso-traders-provisioning-deployment.yml b/.github/workflows/contoso-traders-provisioning-deployment.yml index 04acdfa..86cd17b 100644 --- a/.github/workflows/contoso-traders-provisioning-deployment.yml +++ b/.github/workflows/contoso-traders-provisioning-deployment.yml @@ -17,8 +17,8 @@ jobs: provision-and-deploy: strategy: matrix: - environment: [TEST, PROD] + environmentName: [TEST, PROD] uses: ./.github/workflows/contoso-traders-provisioning-deployment-template.yml secrets: inherit with: - environment: ${{ matrix.environment }} + environmentName: ${{ matrix.environmentName }} From d2847cb0409b3b28666fbb6a1628b176fe1d9d3f Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 21:19:22 +0530 Subject: [PATCH 21/23] updated guide --- docs/App-Deployment-Guide.md | 490 ++++++++++++++++++----------------- 1 file changed, 254 insertions(+), 236 deletions(-) diff --git a/docs/App-Deployment-Guide.md b/docs/App-Deployment-Guide.md index 124864c..484c3c1 100644 --- a/docs/App-Deployment-Guide.md +++ b/docs/App-Deployment-Guide.md @@ -1,324 +1,342 @@ -

Contoso Traders - Deployment Guide

+# Contoso Traders - Deployment Guide +This deployment guide is designed to help you deploy the Contoso Traders application in your Azure environment. Contoso Trader is a micro-services-based application, leveraging various Azure services including Azure Kubernetes Service, App Services, Cosmos DB, SQL Database and many more. -This deployment guide is designed to help you deploy Contoso Traders application in your Azure environment. Contoso Trader is a micro-services-based application, leveraging various Azure services including Azure Kubernetes Service, App Services, Cosmos DB, SQL Database and many more. -While it’s possible to deploy overall solution using Azure Portal, CLI, PowerShell, ARM Templates, we will be using a combination of GitHub Actions and bicep templates to automate the provisioning of overall solution. +While it’s possible to deploy the overall solution using Azure Portal, CLI, PowerShell, ARM Templates, we will be using a combination of GitHub Actions and bicep templates to automate the provisioning of overall solution. -This will deploy all components defined in the Contoso Traders [architecture](../docs/architecture/contoso-traders-enhancements.drawio.png) +This will deploy all components defined in the Contoso Traders [architecture](../docs/architecture/contoso-traders-enhancements.drawio.png) -

Pre-Requisites

+## Prerequisites -You will need following before we start with deployment. -1. An Azure Subscription with Owner rights. If you don't have an Azure subscription, create a free account before you begin by clicking [here](https://azure.microsoft.com/free/). -2. A GitHub Account. You can create a free account [here](https://github.com/). +You will need following before we start with deployment: -

Preparing your Azure Subscription

+1. An Azure account with `Owner` role on the Azure subscription. If you don't have an Azure subscription, create a free account before you begin by clicking [here](https://azure.microsoft.com/free/). -

Register Required Resource Providers

+2. A GitHub Account. You can create one for free [here](https://github.com/). + +## Preparing your Azure Subscription + +### Register Required Resource Providers + +You will need to register required resource providers on your Azure subscription to your subscription to use the required Azure services. + +1. Login to the [Azure portal](https://portal.azure.com) and sign-in with an account having Owner privileges. + +2. Navigate to `Subscription` > `Resource Providers`. + +3. Find following resource provider and click register. + + - `Microsoft.OperationsManagement` + - `Microsoft.Cdn` -You will need to register required resource providers on your Azure subscription to your subscription to use the required Azure services. -1. Login to Azure Portal by visiting [Azure portal](https://portal.azure.com) and sign-in with an account having Owner privileges. -2. Navigate to Subscription > Resource Providers -3. Find following resource provider and click register. - 1. Microsoft.Operationsmanagement - 2. Microsoft.Cdn - ![img1](images/Dapp2.png) - - ![img2](images/cdnregister.png) - - - This will take few minutes to complete. -

Create an Azure Service Principal

+4. This will take few minutes to complete. + +### Create an Azure Service Principal + +GitHub Actions will need to authenticate with your Azure account in order to deploy the application. We will be using an Azure AD Service Principal for allowing GitHub Actions to deploy the resources in Azure. + +An Azure service principal is an identity created for use with applications, hosted services, and automated tools to access Azure resources. This access is restricted by the roles assigned to the service principal, giving you control over which resources can be accessed and at which level. + +Let’s create an Azure Service Principal and assign required permissions. + +1. Sign in to your Azure Account through the Azure portal. -GitHub Actions will need to authenticate with your Azure account in order to deploy the application. We will be using an Azure AD Service Principal for allowing GitHub Actions to deploy the resources in Azure. - An Azure service principal is an identity created for use with applications, hosted services, and automated tools to access Azure resources. This access is restricted by the roles assigned to the service principal, giving you control over which resources can be accessed and at which level -Let’s create an Azure Service Principal and assign required permissions. +2. Select `Azure Active Directory`. -1. Sign in to your Azure Account through the Azure portal. -2. Select Azure Active Directory. -3. Select App registrations. -4. Select New registration. -5. Provide following values and click Register - 1. Name: “ContosoTraders-GitHubActions” - 2. Supported Account Type: Select the first option - Accounts in the organizational directory only(Default Directory-Single Tenant) - 3. Redirect URI: Select Web and enter the url : https://www.contosotraders.com or your domain url you can enter. +3. Select `App registrations`. - ![img3](images/appreg.png) +4. Select `New registration`. + +5. Provide following values and click Register: + + 1. Name: `ContosoTraders-GitHubActions` + + 2. Supported Account Type: Select the first option - `Accounts in the organizational directory only (Default Directory-Single Tenant)`. + + 3. Redirect URI: Select Web and enter the url : `https://www.contosotraders.com` or your domain url you can enter. + ![img3](images/appreg.png) Once the app is registered, please make a note of it’s Application ID, Secret and Tenant ID. -1. Find your newly created application in Azure AD > App Registration -2. Make a note of Application ID & Tenant ID - - ![img4](images/APPIDCTenantID.png) - -3. Navigate to Secrets and create a new secret. - 1. Name: ContosoTrader-Secret-GitHubActions - 2. Validity – 1 Year -4. Make a note of the secret value. Please keep it in a safe location until next step. This value can not be retrieved once you navigate away from this page. +1. Find your newly created application in Azure AD > App Registration + +2. Make a note of Application ID & Tenant ID + ![img4](images/APPIDCTenantID.png) + +3. Navigate to Secrets and create a new secret. + + 1. Name: ContosoTrader-Secret-GitHubActions + + 2. Validity – 1 Year + +4. Make a note of the secret value. Please keep it in a safe location until next step. This value can not be retrieved once you navigate away from this page. + +Now, we will assign Owner rights to this SPN on Azure subscription. + +1. In Azure Portal, Navigate to Subscriptions and Select your subscription -Now, we will assign Owner rights to this SPN on Azure subscription. -1. In Azure Portal, Navigate to Subscriptions and Select your subscription -2. Click on Access Control (IAM) and Click Add Role Assignment +2. Click on Access Control (IAM) and Click Add Role Assignment ![img5](images/Accesscontrol.png) - -3. Select Owner as role and find the newly created SPN - + +3. Select Owner as role and find the newly created SPN + ![img6](images/addrolespn.png) -4. Click Review+Assign -Your subscription is now ready for deployment. +4. Click Review+Assign + +Your subscription is now ready for deployment. + +### Accept Responsible AI Terms + +In Contoso Traders, we are using Azure Cognitive Service to facilitate the search by image functionality. Before you can use Azure AI services, you must accept the terms for Responsible AI usage. + +In order to accept the terms, you will need to manually provision a Cognitive Service Resource using Azure Portal, with which you will be able to accept the terms. -

Accept Responsible AI Terms

+It is recommended to create this temporary in a separate resource group, so that you can delete the resource group once the terms are accepted. -In Contoso Traders, we are using Azure Cognitive Service to facilitate the search by image functionality. Before you can use Azure AI services, you must accept the terms for Responsible AI usage. -In order to accept the terms, you will need to manually provision a Cognitive Service Resource using Azure Portal, with which you will be able to accept the terms. -It is recommended to create this temporary in a separate resource group, so that you can delete the resource group once the terms are accepted. -1. Select the following link to create a Computer Vision resource: +1. Click the following link to create a Computer Vision resource: [Computer vision](https://portal.azure.com/#create/Microsoft.CognitiveServicesComputerVision) - [Computer vision](https://portal.azure.com/#create/Microsoft.CognitiveServicesComputerVision) - 2. On the Create page, provide the following information: - -

Project details Description

- - 1. Subscription :Select one of your available Azure subscriptions. - 2. Resource group :Create new > Cognitive-Temp-RG - 3. Region :The location of your cognitive service instance. - 4. Name :A descriptive name for your cognitive services resource. For example, MyTempCognitiveServicesResource1. - 5. Pricing tier :Free or Standard S0. + + ```text + Project details Description + + 1. Subscription: Select one of your available Azure subscriptions. + 2. Resource group: Create new > Cognitive-Temp-RG + 3. Region: The location of your cognitive service instance. + 4. Name: A descriptive name for your cognitive services resource. For example, MyTempCognitiveServicesResource1. + 5. Pricing tier: Free or Standard S0. 6. Scroll down and check the box for reviewing and acknowledging Responsible AI terms. - + ``` + 3. Click Review & Create + 4. After Validating click Create -Once the provisioning is completed, you can delete the resource group “Cognitive-Temp-RG” as terms are accepted for your subscription now. +Once the provisioning is completed, you can delete the resource group “Cognitive-Temp-RG” as terms are accepted for your subscription now. -

Preparing your GitHub Account

+## Preparing your GitHub Account -In this step, you will form the original ContosoTraders GitHub repository to your GitHub Account and prepare for deployment. +In this step, you will form the original ContosoTraders GitHub repository to your GitHub Account and prepare for deployment. Fork the Contoso Traders Repo -1. Login to GitHub by visiting [github](https://github.com). -2. Open [ContosoTraders repository](https://github.com/microsoft/ContosoTraders) and Click on Fork - - ![img7](images/Repofork.png) +1. Login to GitHub by visiting [github](https://github.com). + +2. Open [ContosoTraders repository](https://github.com/microsoft/ContosoTraders) and Click on Fork -3. You should now a clone of this repository in your GitHub Account, with https://github.com/YOURUSERNAME/ContosoTraders. -4. You will be using this repository for deployment. Since it exists in your GitHub Account, you will be able to make changes to the contents as well, including source code. + ![img7](images/Repofork.png) +3. You should now a clone of this repository in your GitHub Account, with `https://github.com/YOURUSERNAME/ContosoTraders`. -

Create Secrets in GitHub

+4. You will be using this repository for deployment. Since it exists in your GitHub Account, you will be able to make changes to the contents as well, including source code. -GitHub Secrets are encrypted and allow you to store sensitive information, such as access tokens, in your repository. In our scenario, we will be using GitHub Secrets to store the Azure authentication credentials and other secrets. -These secretes will be used by GitHub Action Workflows during deployment and CI/CD process. We will be creating following three secrets +### Create Secrets in GitHub + +GitHub Secrets are encrypted and allow you to store sensitive information, such as access tokens, in your repository. In our scenario, we will be using GitHub Secrets to store the Azure authentication credentials and other secrets. +These secrets will be used by GitHub Action Workflows during deployment and CI/CD process. We will be creating following three secrets + +- ENVIRONMENT_SUFFIX: Per-environment suffix for guaranteeing unique resource names, URLs etc. You can give any value, such as `yournametraders`. +- SERVICEPRINCIPAL: Azure Service Principal credentials for GitHub Action workflow to authenticate with Azure +- SQL_PASSWORD: New Password for SQL DB to be created as part of deployment. - * ENVIRONMENT: Pre-fix for resource naming, URLs etc. You can give any value, such as yournametraders - * SERVICEPRINCIPAL: Azure Service Principal credentials for GitHub Action workflow to authenticate with Azure - * SQL_PASSWORD: New Password for SQL DB to be created as part of deployment. - Let’s get started -1. Login to GitHub and navigate to your fork of Contoso traders repository. https://github.com/YOURUSERNAME/ContosoTraders. +1. Login to GitHub and navigate to your fork of Contoso traders repository: `https://github.com/YOURUSERNAME/ContosoTraders`. 2. Under your repository name, click on the "Settings" tab. - - ![img8](images/settingsgithub.png) - + + ![img8](images/settingsgithub.png) + 3. In the left sidebar, click Secrets and select actions. - - ![img9](images/githubsett.png) + + ![img9](images/githubsett.png) 4. On the right bar, click on "Add a new secret" -5. Create the following secret for Azure SPN. - 1. Secret Name: SERVICEPRINCIPAL - 2. Value: Please replace the values with your App ID created earlier. - - { - - "clientId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", - - "clientSecret": "your-client-secret", - - "tenantId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", - - "subscriptionId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz" - - } - - 3. Click Add Secret - - ![img10](images/addserviceprniciopagithub.png) - -9. Create the following secret for ENVIRONMENT. This is a prefix for your environment and all resources are provisioned with this pre-fix to avoid conflict with public resource names in Azure. - - 1. Secret Name: ENVIRONMENT - 2. Value : Add any combination of characters not exceeding 6 and dont take below 3 - - ![img15](images/envwork.png) - - **Note: When you are creating secret for Environment please add combination of alphanumeric characters without any symbols. Maximum characters allowed is 6 and minimum characters allowed is 3. Keep small case letters** - -10. Create the following secret for SQL Password. - 1. Secret Name: SQL_PASSWORD - 2. Value : Add any combination of alphanumeric characters of minimum 12 - - - ![img12](images/sqlsecretgit.png) - -**Note : When you are creating secret for SQL password please add combination of alphanumeric characters. Minimum characters allowed is 12.Keep small case letters.** +5. Create the following secret for Azure SPN. + 1. Secret Name: SERVICEPRINCIPAL + 2. Value: Please replace the values with your App ID created earlier. + + ```json + { + "clientId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", + "clientSecret": "your-client-secret", + "tenantId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", + "subscriptionId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz" + } + ``` + + 3. Click Add Secret + + ![img10](images/addserviceprniciopagithub.png) + +6. Create the following secret for ENVIRONMENT. This is a suffix for your environment and all resources are provisioned with this pre-fix to avoid conflict with public resource names in Azure. + + 1. Secret Name: ENVIRONMENT_SUFFIX -Your GitHub repository is now ready for deployment. + 2. Value : Add any combination of characters not exceeding 6 and don't take below 3 + ![img15](images/envwork.png) -

Deploying the Contoso Traders Application

+ > When you are creating secret for Environment please add combination of alphanumeric characters without any symbols. Maximum characters allowed is 6 and minimum characters allowed is 3. Keep small case letters. +7. Create the following secret for SQL Password. -You are now ready to start deployment of application to your Azure account. We will be using GitHub Action workflows for this deployment. -We will be using following workflows as part of deployment. You can review workflow code by navigating to .github/workflows directory in your repository. -• contoso-traders-provisioning-deployment: + 1. Secret Name: SQL_PASSWORD -Let’s get started. + 2. Value : Add any combination of alphanumeric characters of minimum 12 -1. Login to GitHub and navigate to your fork of Contoso traders repository. https://github.com/YOURUSERNAME/ContosoTraders + ![img12](images/sqlsecretgit.png) + +**Note : When you are creating secret for SQL password please add combination of alphanumeric characters. Minimum characters allowed is 12.Keep small case letters.** + +Your GitHub repository is now ready for deployment. + +## Deploying the Contoso Traders Application + +You are now ready to start deployment of application to your Azure account. We will be using GitHub Action workflows for this deployment. +We will be using following workflows as part of deployment. You can review workflow code by navigating to .github/workflows directory in your repository. + +- contoso-traders-provisioning-deployment: + +Let’s get started. + +1. Login to GitHub and navigate to your fork of Contoso traders repository: `https://github.com/YOURUSERNAME/ContosoTraders` 2. Navigate to Actions and Accept enabling the workflows - - ![img13](images/workflowenable.png) - - + + ![img13](images/workflowenable.png) + 3. In the workflow list, select the “contoso-traders-provisioning-deployment” workflow. - -4. Click on Run Workflow and run the workflow with main branch. - - ![img14](images/workflowrun1.png) + +4. Click on Run Workflow and run the workflow with main branch. + + ![img14](images/workflowrun1.png) 5. If you refresh the page, you will see that workflow provisioning has started. You can click on workflow to see the progress live and logs. If you navigate in the workflow execution, you will the following stages. - 1. Provision-infrastructure: This stage provisions the required resource groups and other Azure services as per architecture and prepares them for app. - 2. You can see each stage and what it does in below screenshot - - ![img19](images/workflow5.png) - 3. Deploy the carts & product API: This stage provisions pushing of carts api and products api to azure container registry. - - ![img22](images/workflow7.png) - ![img20](images/workflow3.png) + 1. Provision-infrastructure: This stage provisions the required resource groups and other Azure services as per architecture and prepares them for app. - 5. Deploy the UI: This stage configure the endpoints of the cart api and products api. - - ![img21](images/workflow4.png) - -**Note : Please note that the workflow provisions all resources through bicep templates, scripts etc. We’ve observed that in many cases, Azure subscription resource cache does not get updated fast enough before the next dependent step starts executing. -If you find workflow failure error due to missing Azure resources (Key vault, CDN, container apps etc, please re-run the failed jobs.** + 2. You can see each stage and what it does in below screenshot. + ![img19](images/workflow5.png) -

Validate & test the deployment

+ 3. Deploy the carts & product API: This stage provisions pushing of carts api and products api to azure container registry. + + ![img22](images/workflow7.png) + ![img20](images/workflow3.png) + + 4. Deploy the UI: This stage configure the endpoints of the cart api and products api. + + ![img21](images/workflow4.png) + +> Note : Please note that the workflow provisions all resources through bicep templates, scripts etc. We’ve observed that in many cases, Azure subscription resource cache does not get updated fast enough before the next dependent step starts executing. +> If you find workflow failure error due to missing Azure resources (Key vault, CDN, container apps etc, please re-run the failed jobs. + +## Validate & test the deployment Contoso Traders application is now ready in your subscription. Let us review and validate the deployment to ensure application is functioning as expected. -

Review Provisioned Azure Resources

+### Review Provisioned Azure Resources Please refer to the architecture walkthrough demo script and technical walkthrough to review the provisioned resources. Please check [here](../demo-scripts/cloud-native-app-architecture/technical-walkthrough.md). +## Test Application + +1. Navigate to Azure and look for CDN endpoints by searching for Content Delivery Network in search menu. Type Content delivery network in the search box and select Front Door and CDN Profiles. + + ![img30](images/test1.png) + +2. Select the CDN profile starting with name contoso-traders-cdn$ENVIRONMENTNAME + + ![img31](images/Test2.png) + +3. Review the Endpoints and make a note of the URL for endpoint containing “UI2” website. It should look like `https://contoso-traders-ui2$ENVNAME.azureedge.net` + + ![img32](images/Test3.png) + +4. Launch the application by clicking on the endpoint hostname url. + + ![img33](images/Test4.png) + +5. The web app will launched. + + ![img34](images/test5.png) + +6. Test the website by navigating through various pages, search by image etc. -

Test Application

- -1. Navigate to Azure and look for CDN endpoints by searching for Content Delivery Network in search menu. Type Content delivery network in the search box and select Front Door and CDN Profiles. - - ![img30](images/test1.png) - -3. Select the CDN profile starting with name contoso-traders-cdn$ENVIRONMENTNAME - - ![img31](images/Test2.png) - -5. Review the Endpoints and make a note of the URL for endpoint containing “UI2” website. It should look like https://contoso-traders-ui2$ENVNAME.azureedge.net - - ![img32](images/Test3.png) - -7. Launch the application by clicking on the endpoint hostname url. - - ![img33](images/Test4.png) - -8. The web app will launched. - - ![img34](images/test5.png) - -9. Test the website by navigating through various pages, search by image etc. - If you would like to add a custom domain, like contosotraders.com, you can purchase the domain and add to CDN profile. Please see documentation [here](https://learn.microsoft.com/en-us/azure/cdn/cdn-map-content-to-custom-domain?tabs=azure-dns%2Cazure-portal%2Cazure-portal-cleanup). -

Deploy Inventory Management PowerApps

+## Deploy Inventory Management PowerApps + +If you are interested, you can follow these steps to deploy the inventory management application used by internal users for managing product pricing, stock etc. -If you are interested, you can follow these steps to deploy the inventory management application used by internal users for managing product pricing, stock etc. It will be hosted using Power Apps and will use Power Automate & MS Teams to enable a full inventory management and approval workflow. -Please follow the instructions here: [Deploy Inventory Management Power App](./Inventory-power-app-deployment-guide.md) - +Please follow the instructions here: [Deploy Inventory Management Power App](./Inventory-power-app-deployment-guide.md) -

Try Out Demo Scripts

- +## Try Out Demo Scripts As further learning, you can try running through some of the demo scripts listed below which’d help in understanding the Azure Cloud Native Technologies. + | Scenario | Level | + | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | Cloud Native App Architecture Walkthrough | [Overview](../demo-scripts/cloud-native-app-architecture/overview.md) \| [Technical Walkthrough](../demo-scripts/cloud-native-app-architecture/technical-walkthrough.md) | + | Autoscaling Cloud Native Apps in Azure | [Overview](../demo-scripts/autoscaling-cloud-native-apps-azure/overview.md) \| [Technical Walkthrough](../demo-scripts/autoscaling-cloud-native-apps-azure/technical-walkthrough.md) | + | DevSecOps Journey with GitHub + Azure | [Overview](../demo-scripts/devsecops/overview.md) \| [Technical Walkthrough](../demo-scripts/devsecops/technical-walkthrough.md) | + | Low Code App Development Power Platform | [Overview](../demo-scripts/low-code-development/overview.md) \| [Technical Walkthrough](../demo-scripts/low-code-development/technical-walkthrough.md) | + | Intelligent Apps with Azure AI Services | [Overview](../demo-scripts/intelligent-apps-with-azure-ai-services/overview.md) \| [Technical Walkthrough](../demo-scripts/intelligent-apps-with-azure-ai-services/technical-walkthrough.md) | + +## Common Errors & Troubleshooting + +This includes some of the common problems you may during deployment and approach to resolve them. + +1. AI Terms and services: + If you see an error stating that "Responsible AI terms are not accepted for this subscription", deploy an Azure Cognitive Service resource manually in your subscription temporarily and re-run the jobs. + +2. Lack of permissions + + Check the role of the service prinipal is owner. If its not shown please provide the owner role to the service principal. + +3. Environment name having not allowed characters + + When you are creating secret for Environment please add combination of alphanumeric characters without any symbols. Maximum characters allowed is 6 and minimum characters allowed is 3. Keep small case letters. + +4. Subscription quota: + + If you get an error related to subscription quota, you may need to raise quota requests in your subscription. For the details of subscription quota please click [here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits). + +5. Can not find resources (Key Vault, CDN, Storage Account, etc. ) + + Please note that the workflow provisions all resources through bicep templates, scripts etc. We’ve observed that in many cases, Azure subscription resource cache does not get updated fast enough before the next dependent step starts executing. + + If you find workflow failure error due to missing Azure resources (Key vault, CDN, container apps etc, please re-run the failed jobs. + +### Known Issues - | Scenario | Level | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | Cloud Native App Architecture Walkthrough | [Overview](../demo-scripts/cloud-native-app-architecture/overview.md) \| [Technical Walkthrough](../demo-scripts/cloud-native-app-architecture/technical-walkthrough.md) | - | Autoscaling Cloud Native Apps in Azure | [Overview](../demo-scripts/autoscaling-cloud-native-apps-azure/overview.md) \| [Technical Walkthrough](../demo-scripts/autoscaling-cloud-native-apps-azure/technical-walkthrough.md) | - | DevSecOps Journey with GitHub + Azure | [Overview](../demo-scripts/devsecops/overview.md) \| [Technical Walkthrough](../demo-scripts/devsecops/technical-walkthrough.md) | - | Low Code App Development Power Platform | [Overview](../demo-scripts/low-code-development/overview.md) \| [Technical Walkthrough](../demo-scripts/low-code-development/technical-walkthrough.md) | - | Intelligent Apps with Azure AI Services | [Overview](../demo-scripts/intelligent-apps-with-azure-ai-services/overview.md) \| [Technical Walkthrough](../demo-scripts/intelligent-apps-with-azure-ai-services/technical-walkthrough.md) | - - - -

Common Errors & Troubleshooting

- -This includes some of the common problems you may during deployment and approach to resolve them. - -1. AI Terms and services: - - **If you see an error stating that "Responsible AI terms are not accepted for this subscription", deploy an Azure Cognitive Service resource manually in your subscription temporarily and re-run the jobs.** - -3. Lack of permissions - - **Check the role of the service prinipal is owner. If its not shown please provide the owner role to the service principal.** - -5. Environment name having not allowed characters - - **When you are creating secret for Environment please add combination of alphanumeric characters without any symbols. Maximum characters allowed is 6 and minimum characters allowed is 3. Keep small case letters** - -8. Subscription quota: - - **If you get an error related to subscription quota, you may need to raise quota requests in your subscription. For the details of subscription quota please click [here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits).** - -10. Can not find resources (Key Vault, CDN, Storage Account, etc. ) - - **Please note that the workflow provisions all resources through bicep templates, scripts etc. We’ve observed that in many cases, Azure subscription resource cache does not get updated fast enough before the next dependent step starts executing. - If you find workflow failure error due to missing Azure resources (Key vault, CDN, container apps etc, please re-run the failed jobs.** - -

Known Issues

- When you run the workflow, it shows following warnings. - -**Error: WARNING: /home/runner/work/ContosoTraders/ContosoTraders/iac/createResources.bicep(191,50) : Warning no-hardcoded-env-urls: Environment URLs should not be hardcoded. Use the environment() function to ensure compatibility across clouds. Found this disallowed host: "database.windows.net". ** -**Warning: WARNING: /home/runner/work/ContosoTraders/ContosoTraders/iac/createResources.bicep(191,50) : Warning no-hardcoded-env-urls: Environment URLs should not be hardcoded. Use the environment() function to ensure compatibility across clouds. Found this disallowed host: "database.windows.net". ** +```text +Error: WARNING: /home/runner/work/ContosoTraders/ContosoTraders/iac/createResources.bicep(191,50) : Warning no-hardcoded-env-urls: Environment URLs should not be hardcoded. Use the environment() function to ensure compatibility across clouds. Found this disallowed host: "database.windows.net". +``` +```text +Warning: WARNING: /home/runner/work/ContosoTraders/ContosoTraders/iac/createResources.bicep(191,50) : Warning no-hardcoded-env-urls: Environment URLs should not be hardcoded. Use the environment() function to ensure compatibility across clouds. Found this disallowed host: "database.windows.net". +``` -This does not block the deployment and workflow will run successfully. It does not have any other impact. It is being tracked here https://github.com/microsoft/ContosoTraders/issues/68 +This does not block the deployment and workflow will run successfully. It does not have any other impact. It is being tracked [here](https://github.com/microsoft/ContosoTraders/issues/68). +## Questions & Support +This project is community supported. Please raise issue via GitHub incase of issues/questions. -

Questions & Support

- -This project is community supported. Please raise issue via GitHub incase of issues/questions. +## Cleanup -

Cleanup

+Once you are done deploying, testing, exploring, you can delete the provisioned RGs to prevent incurring additional cost. -Once you are done deploying, testing, exploring, you can delete the provisioned RGs to prevent incurring additional cost. Delete the following resource groups. -1. contoso-traders-rg -2. contoso-traders-aks-nodes-rg + +1. `contoso-traders-rg` +2. `contoso-traders-aks-nodes-rg` From 9180ab38508665967d4cc6d65ab0c8e117b16c15 Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 21:20:49 +0530 Subject: [PATCH 22/23] cosmetic edits --- README.md | 2 +- demo-scripts/devsecops/technical-walkthrough.md | 2 +- docs/Inventory-power-app-deployment-guide.md | 2 +- docs/setup-local-instructions.md | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 094184b..47be21f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ## Documentation and Resources -* [Deployment Guide](./docs/App-Deployment-Guide.md) +* [Deployment Guide](./docs/app-deployment-Guide.md) * [Deployment Guide for Inventory Management PowerApp](./docs/Inventory-power-app-deployment-guide.md) * [Contributing](./docs/contributing.md) * [Bicep Templates](./iac/) diff --git a/demo-scripts/devsecops/technical-walkthrough.md b/demo-scripts/devsecops/technical-walkthrough.md index 47d648c..3be6da0 100644 --- a/demo-scripts/devsecops/technical-walkthrough.md +++ b/demo-scripts/devsecops/technical-walkthrough.md @@ -15,7 +15,7 @@ The key takeaways from this demo are: ## Before you Begin -You must have Contoso Traders deployed in your environment and setup with GitHub Actions. Please refer to the deployment instructions [here](https://github.com/microsoft/ContosoTraders/blob/main/docs/App-Deployment-Guide.md) +You must have Contoso Traders deployed in your environment and setup with GitHub Actions. Please refer to the deployment instructions [here](https://github.com/microsoft/ContosoTraders/blob/main/docs/app-deployment-Guide.md) ## Walkthrough – DevSecOps with Contoso Traders diff --git a/docs/Inventory-power-app-deployment-guide.md b/docs/Inventory-power-app-deployment-guide.md index 65e37e9..b9886cb 100644 --- a/docs/Inventory-power-app-deployment-guide.md +++ b/docs/Inventory-power-app-deployment-guide.md @@ -13,7 +13,7 @@ You will be using a pre-created Package to import the Power App & Power Automate

Pre-Requisite

You will need the following before we start the deploymment -1. You need to have ContosoTraders App deployed in your Azure Subscription. If you have not deployed it yet, please refer the [documentation](../docs/App-Deployment-Guide.md). +1. You need to have ContosoTraders App deployed in your Azure Subscription. If you have not deployed it yet, please refer the [documentation](../docs/app-deployment-Guide.md). 2. An account with global administrator rights on the M365 tenant. diff --git a/docs/setup-local-instructions.md b/docs/setup-local-instructions.md index ecd80b6..657cee0 100644 --- a/docs/setup-local-instructions.md +++ b/docs/setup-local-instructions.md @@ -5,10 +5,9 @@ 1. You'll need an Azure subscription with the `Microsoft.OperationsManagement` resource provider registered ([steps](https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-register-resource-provider?tabs=azure-portal)). 2. You'll need a service principal in the `owner` role on the Azure subscription where the infrastructure is to be provisioned. 3. Git clone this repository to your machine. -4. Create the `SERVICEPRINCIPAL`, `ENVIRONMENT`, and `SQL_PASSWORD` github secrets ([instructions here](./App-Deployment-Guide)). +4. Create the `SERVICEPRINCIPAL`, `ENVIRONMENT`, and `SQL_PASSWORD` github secrets ([instructions here](./App-deployment-Guide)). 5. Next, run the `contoso-traders-provisioning-deployment` github workflow. You can do this by going to the github repo's `Actions` tab, selecting the workflow, and clicking on the `Run workflow` button. This will both provision the infrastructure on Azure as well as deploy the applications (APIs, UI) to the infrastructure. - ## Running ContosoTraders Locally 1. First ensure that the infrastructure setup has been completed as per steps above. From bd0cd0d034e8b7032d19598607cacd824ef03fcf Mon Sep 17 00:00:00 2001 From: mithun shanbhag Date: Fri, 16 Dec 2022 21:22:11 +0530 Subject: [PATCH 23/23] updates --- docs/setup-local-instructions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/setup-local-instructions.md b/docs/setup-local-instructions.md index 657cee0..430beef 100644 --- a/docs/setup-local-instructions.md +++ b/docs/setup-local-instructions.md @@ -1,11 +1,11 @@ -# Instructions to run Contoso Traders locally. +# Instructions to run Contoso Traders locally ## Setting up ContosoTraders Infrastructure 1. You'll need an Azure subscription with the `Microsoft.OperationsManagement` resource provider registered ([steps](https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-register-resource-provider?tabs=azure-portal)). 2. You'll need a service principal in the `owner` role on the Azure subscription where the infrastructure is to be provisioned. 3. Git clone this repository to your machine. -4. Create the `SERVICEPRINCIPAL`, `ENVIRONMENT`, and `SQL_PASSWORD` github secrets ([instructions here](./App-deployment-Guide)). +4. Create the `SERVICEPRINCIPAL`, `ENVIRONMENT_SUFFIX`, and `SQL_PASSWORD` github secrets ([instructions here](./app-deployment-Guide)). 5. Next, run the `contoso-traders-provisioning-deployment` github workflow. You can do this by going to the github repo's `Actions` tab, selecting the workflow, and clicking on the `Run workflow` button. This will both provision the infrastructure on Azure as well as deploy the applications (APIs, UI) to the infrastructure. ## Running ContosoTraders Locally