From eb3e318d338d1dc7fdc28dac60ea672c2013daaf Mon Sep 17 00:00:00 2001 From: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com> Date: Thu, 10 Jun 2021 13:14:15 -0700 Subject: [PATCH] QA auto slot swapping (#1383) * updating the qa deploy to dynamically pull the publish profile instead of proxying it through a key vault * fixing the download-artifact hash * fixing typo * trying out the custom keyvault getter * fixing the new deploy matrix * fixing the custom action path * setting custom action commit hash * paramaterized the deploy job * adding the staging slot to the publish profiles * trying a custom way to pull the publishing profile * removing the publish profile altogether since it might not even be needed * removing unnecessary publish profile stuff * removing the subscription id from the qa deploy workflow * adding auto swap for QA identity * adding the rest of the webapp slot swapping automation * fixing the job dependencies * fixing the matrix name variable and adding some debugging code * removing admin and identity out of the matrix swap * switching the alive check * fixing the identity endpoint * fixing the while loops * adding in sleeps to see if it is a matrix issue * running the matrix sequentially to see if that rids us of the slot swapping conflits * removing the sleep command in the matrix * removing the sequential controller * disabling the build and deploy for swapping tests * changing the live test a bit * fixing the identity status url * adding in a fail safe if not hit the alive endpoint * fixing the azure secret names * removing the debugging code * Update QA Deploy Workflow (#1387) * Testing workflow * Add whitespace to workflow Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com> --- .github/workflows/qa-deploy.yml | 326 ++++++++++++++------------------ 1 file changed, 144 insertions(+), 182 deletions(-) diff --git a/.github/workflows/qa-deploy.yml b/.github/workflows/qa-deploy.yml index 6e8076d379..1c17534dde 100644 --- a/.github/workflows/qa-deploy.yml +++ b/.github/workflows/qa-deploy.yml @@ -114,6 +114,7 @@ jobs: echo "placeholder for cleaning DB" echo "placeholder for loading test dataset" + update-db: if: ${{ github.events.inputs.migrateDb }} == "true" runs-on: ubuntu-latest @@ -125,16 +126,35 @@ jobs: echo "placeholder for updateing DB" - deploy-identity: + deploy: runs-on: ubuntu-latest needs: - reset-db - update-db + strategy: + fail-fast: false + matrix: + include: + - name: Api + - name: Admin + - name: Billing + - name: Events + - name: Sso + - name: Portal + - name: Identity steps: + - name: Setup + id: setup + run: | + NAME_LOWER=$(echo "${{ matrix.name }}" | awk '{print tolower($0)}') + echo "Matrix name: ${{ matrix.name }}" + echo "NAME_LOWER: $NAME_LOWER" + echo "::set-output name=name_lower::$NAME_LOWER" + - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 + uses: actions/download-artifact@158ca71f7c614ae705e79f25522ef4658df18253 with: - name: Identity.zip + name: ${{ matrix.name }}.zip - name: Login to Azure uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a @@ -143,31 +163,86 @@ jobs: - name: Retrieve secrets id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-identity-webapp-name, - appservices-identity-webapp-publish-profile" + env: + VAULT_NAME: "bitwarden-qa-kv" + run: | + webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-${{ steps.setup.outputs.name_lower }}-webapp-name --query value --output tsv) + echo "::add-mask::$webapp_name" + echo "::set-output name=webapp-name::$webapp_name" - - name: Deploy Identity + - name: Deploy App uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-name }} + app-name: ${{ steps.retrieve-secrets.outputs.webapp-name }} slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-identity-webapp-publish-profile }} - package: ./Identity.zip + package: ./${{ matrix.name }}.zip - deploy-api: + swap-identity: runs-on: ubuntu-latest - needs: - - reset-db - - update-db + needs: deploy steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 + - name: Login to Azure + uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a with: - name: Api.zip + creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} + + - name: Retrieve secrets + id: retrieve-secrets + env: + VAULT_NAME: "bitwarden-qa-kv" + run: | + identity_webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-identity-webapp-name --query value --output tsv) + echo "::add-mask::$identity_webapp_name" + echo "::set-output name=identity-webapp-name::$identity_webapp_name" + + - name: Start staging slot + run: az webapp start --name ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --resource-group bitwarden-qa --slot staging + + - name: Make sure staging endpoint is alive + run: | + SUCCESS="no" + while read OUTPUT + do + STATUS=$( curl -is https://${{ steps.retrieve-secrets.outputs.identity-webapp-name }}-staging.azurewebsites.net/.well-known/openid-configuration/jwks | head -1 ) + if [[ "$STATUS" == *"200 OK"* ]]; then + echo "It is live!" + SUCCESS="yes" + break + fi + echo -e "STAUS=$STATUS\nRetrying: $OUTPUT" + sleep 4; + done < <(seq 15) + + if [[ "$SUCCESS" == "no" ]]; then + exit 1 + fi + + - name: Swap Identity + run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --slot staging --target-slot production + + - name: Stop staging slot + run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.identity-webapp-name }} --resource-group bitwarden-qa --slot staging + + + swap-slots: + runs-on: ubuntu-latest + needs: swap-identity + strategy: + fail-fast: false + matrix: + include: + - name: Api + - name: Billing + - name: Events + - name: Sso + - name: Portal + steps: + - name: Setup + id: setup + run: | + NAME_LOWER=$(echo "${{ matrix.name }}" | awk '{print tolower($0)}') + echo "::set-output name=name_lower::$NAME_LOWER" - name: Login to Azure uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a @@ -176,32 +251,46 @@ jobs: - name: Retrieve secrets id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-api-webapp-name, - appservices-api-webapp-publish-profile" + env: + VAULT_NAME: "bitwarden-qa-kv" + run: | + webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-${{ steps.setup.outputs.name_lower }}-webapp-name --query value --output tsv) + echo "::add-mask::$webapp_name" + echo "::set-output name=webapp-name::$webapp_name" - - name: Deploy Api - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-api-webapp-publish-profile }} - package: ./Api.zip + - name: Start staging slot + run: az webapp start --name ${{ steps.retrieve-secrets.outputs.webapp-name }} --resource-group bitwarden-qa --slot staging + + - name: Make sure staging endpoint is alive + run: | + SUCCESS="no" + while read OUTPUT + do + STATUS=$( curl -is https://${{ steps.retrieve-secrets.outputs.webapp-name }}-staging.azurewebsites.net/alive | head -1 ) + if [[ "$STATUS" == *"200 OK"* ]]; then + echo "It is live!" + SUCCESS="yes" + break + fi + echo -e "STAUS=$STATUS\nRetrying: $OUTPUT" + sleep 4; + done < <(seq 15) + + if [[ "$SUCCESS" == "no" ]]; then + exit 1 + fi + + - name: Swap slots + run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.webapp-name }} --slot staging --target-slot production + + - name: Stop staging slot + run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.webapp-name }} --resource-group bitwarden-qa --slot staging - deploy-billing: + swap-admin: runs-on: ubuntu-latest - needs: - - reset-db - - update-db + needs: swap-slots steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 - with: - name: Billing.zip - - name: Login to Azure uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a with: @@ -209,149 +298,22 @@ jobs: - name: Retrieve secrets id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-billing-webapp-name, - appservices-billing-webapp-publish-profile" + env: + VAULT_NAME: "bitwarden-qa-kv" + run: | + admin_webapp_name=$(az keyvault secret show --vault-name $VAULT_NAME --name appservices-admin-webapp-name --query value --output tsv) + echo "::add-mask::$admin_webapp_name" + echo "::set-output name=admin-webapp-name::$admin_webapp_name" - - name: Deploy Billing - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-billing-webapp-publish-profile }} - package: ./Billing.zip + - name: Start staging slot + run: az webapp start --name ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --resource-group bitwarden-qa --slot staging + - name: Make sure staging endpoint is alive + run: | + sleep 60 # I don't think the admin portal has an alive endpoint - deploy-events: - runs-on: ubuntu-latest - needs: - - reset-db - - update-db - steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 - with: - name: Events.zip - - - name: Login to Azure - uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a - with: - creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} - - - name: Retrieve secrets - id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-events-webapp-name, - appservices-events-webapp-publish-profile" - - - name: Deploy Events - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-events-webapp-publish-profile }} - package: ./Events.zip - - - deploy-sso: - runs-on: ubuntu-latest - needs: - - reset-db - - update-db - steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 - with: - name: Sso.zip - - - name: Login to Azure - uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a - with: - creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} - - - name: Retrieve secrets - id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-sso-webapp-name, - appservices-sso-webapp-publish-profile" - - - name: Deploy SSO - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-sso-webapp-publish-profile }} - package: ./Sso.zip - - - deploy-portal: - runs-on: ubuntu-latest - needs: - - reset-db - - update-db - steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 - with: - name: Portal.zip - - - name: Login to Azure - uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a - with: - creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} - - - name: Retrieve secrets - id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-portal-webapp-name, - appservices-portal-webapp-publish-profile" - - - name: Deploy Portal - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-portal-webapp-publish-profile }} - package: ./Portal.zip - - - deploy-admin: - runs-on: ubuntu-latest - needs: - - reset-db - - update-db - steps: - - name: Download aritifacts - uses: actions/download-artifact@v158ca71f7c614ae705e79f25522ef4658df18253 - with: - name: Admin.zip - - - name: Login to Azure - uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a - with: - creds: ${{ secrets.AZURE_QA_KV_CREDENTIALS }} - - - name: Retrieve secrets - id: retrieve-secrets - uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403 - with: - keyvault: "bitwarden-qa-kv" - secrets: "appservices-admin-webapp-name, - appservices-admin-webapp-publish-profile" - - - name: Deploy Admin - uses: azure/webapps-deploy@798e43877120eda6a2a690a4f212c545e586ae31 - with: - app-name: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-name }} - slot-name: "staging" - publish-profile: ${{ steps.retrieve-secrets.outputs.appservices-admin-webapp-publish-profile }} - package: ./Admin.zip + - name: Swap Admin + run: az webapp deployment slot swap -g bitwarden-qa -n ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --slot staging --target-slot production + - name: Stop staging slot + run: az webapp stop --name ${{ steps.retrieve-secrets.outputs.admin-webapp-name }} --resource-group bitwarden-qa --slot staging