From 22280105ee9d61312384e0f259d8fa0a478c26b1 Mon Sep 17 00:00:00 2001 From: Thomas Jespersen Date: Fri, 24 May 2024 20:53:44 +0200 Subject: [PATCH] Update GitHub actions for deploying infrastructure and container apps, removing hardcoded West Europe location, making it configurable with GitHub environment variables --- .github/workflows/_deploy-container.yml | 55 ++++-- .github/workflows/cloud-infrastructure.yml | 218 ++++++++++++--------- 2 files changed, 159 insertions(+), 114 deletions(-) diff --git a/.github/workflows/_deploy-container.yml b/.github/workflows/_deploy-container.yml index 145e793c4..26de02973 100644 --- a/.github/workflows/_deploy-container.yml +++ b/.github/workflows/_deploy-container.yml @@ -23,10 +23,18 @@ on: type: string jobs: - staging-west-europe-deploy: + stage: name: Staging - if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest + # environment: "staging" Manual approval disabled + if: ${{ vars.STAGING_CLUSTER_ENABLED }} && github.ref == 'refs/heads/main' + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "stage" + CLUSTER_LOCATION_ACRONYM: ${{ vars.STAGING_CLUSTER_LOCATION_ACRONYM }} + SERVICE_PRINCIPAL_ID: ${{ vars.STAGING_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.STAGING_SUBSCRIPTION_ID }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -40,12 +48,12 @@ jobs: - name: Login to Azure uses: azure/login@v2 with: - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{env.SUBSCRIPTION_ID }} - name: Login to ACR - run: az acr login --name ${{ vars.UNIQUE_PREFIX }}stage + run: az acr login --name ${{ env.UNIQUE_PREFIX }}${{env.ENVIRONMENT}} - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 @@ -57,32 +65,39 @@ jobs: docker buildx build \ --platform linux/amd64,linux/arm64 \ --build-arg VERSION=${{ inputs.version }} \ - -t ${{ vars.UNIQUE_PREFIX }}stage.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }} \ - -t ${{ vars.UNIQUE_PREFIX }}stage.azurecr.io/${{ inputs.image_name }}:latest \ + -t ${{ env.UNIQUE_PREFIX }}${{env.ENVIRONMENT}}.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }} \ + -t ${{ env.UNIQUE_PREFIX }}${{env.ENVIRONMENT}}.azurecr.io/${{ inputs.image_name }}:latest \ -f ${{ inputs.docker_file }} \ --push . docker buildx rm - - name: Deploy Staging West Europe cluster + - name: Deploy Container run: | SURFIX=$(echo "${{ inputs.version }}" | sed 's/\./-/g') - az containerapp update --name ${{ inputs.image_name }} --resource-group "${{ vars.UNIQUE_PREFIX }}-stage-weu" --image "${{ vars.UNIQUE_PREFIX }}stage.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }}" --revision-suffix $SURFIX + az containerapp update --name ${{ inputs.image_name }} --resource-group "${{ env.UNIQUE_PREFIX }}-${{env.ENVIRONMENT}}-${{env.CLUSTER_LOCATION_ACRONYM}}" --image "${{ vars.UNIQUE_PREFIX }}${{env.ENVIRONMENT}}.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }}" --revision-suffix $SURFIX - production-west-europe-deploy: - name: Production - if: false && github.ref == 'refs/heads/main' ## Disable production for now - needs: staging-west-europe-deploy + prod1: + name: Production 1 + needs: stage + environment: "production" # Force a manual approval runs-on: ubuntu-latest - environment: "production" ## Force a manual approval + if: ${{ vars.PRODUCTION_CLUSTER1_ENABLED }} && github.ref == 'refs/heads/main' + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "prod" + CLUSTER_LOCATION_ACRONYM: ${{ vars.PRODUCTION_CLUSTER1_LOCATION_ACRONYM }} + SERVICE_PRINCIPAL_ID: ${{ vars.PRODUCTION_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.PRODUCTION_SUBSCRIPTION_ID }} steps: - name: Login to Azure uses: azure/login@v2 with: - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{env.SUBSCRIPTION_ID }} - - name: Deploy Production West Europe cluster + - name: Deploy Container run: | SURFIX=$(echo "${{ inputs.version }}" | sed 's/\./-/g') - az containerapp update --name ${{ inputs.image_name }} --resource-group "${{ vars.UNIQUE_PREFIX }}-prod-weu" --image "${{ vars.UNIQUE_PREFIX }}prod.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }}" --revision-suffix $SURFIX + az containerapp update --name ${{ inputs.image_name }} --resource-group "${{ vars.UNIQUE_PREFIX }}-${{env.ENVIRONMENT}}-${{env.CLUSTER_LOCATION_ACRONYM}}" --image "${{ vars.UNIQUE_PREFIX }}${{env.ENVIRONMENT}}.azurecr.io/${{ inputs.image_name }}:${{ inputs.version }}" --revision-suffix $SURFIX diff --git a/.github/workflows/cloud-infrastructure.yml b/.github/workflows/cloud-infrastructure.yml index 83bc4220c..be2872b5d 100644 --- a/.github/workflows/cloud-infrastructure.yml +++ b/.github/workflows/cloud-infrastructure.yml @@ -20,9 +20,20 @@ permissions: contents: read jobs: - plan: - name: Plan Changes + plan-stage: + name: Plan Changes Staging runs-on: ubuntu-latest + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "stage" + SHARED_LOCATION: ${{ vars.STAGING_SHARED_LOCATION }} + CLUSTER_LOCATION: ${{ vars.STAGING_CLUSTER_LOCATION }} + CLUSTER_LOCATION_ACRONYM: ${{ vars.STAGING_CLUSTER_LOCATION_ACRONYM }} + SQL_ADMIN_OBJECT_ID: ${{ vars.STAGING_SQL_ADMIN_OBJECT_ID }} + DOMAIN_NAME: ${{ vars.STAGING_DOMAIN_NAME }} + SERVICE_PRINCIPAL_ID: ${{ vars.STAGING_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.STAGING_SUBSCRIPTION_ID }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -34,43 +45,36 @@ jobs: sudo mv ./bicep /usr/local/bin/bicep && bicep --version - - name: Login to Azure subscription + - name: Login to Azure uses: azure/login@v2 with: - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Plan Changes to Shared Staging Environment Resources - env: - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - run: bash ./cloud-infrastructure/environment/config/staging.sh --plan - - - name: Plan Changes to Staging West Europe Cluster - env: - ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID: ${{ secrets.ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID }} - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - DOMAIN_NAME: ${{ vars.DOMAIN_NAME_STAGING }} - run: bash ./cloud-infrastructure/cluster/config/staging-west-europe.sh --plan - - - name: Plan Changes to Shared Production Environment Resources - if: false ## Disable production for now - run: bash ./cloud-infrastructure/environment/config/production.sh --plan - - - name: Plan Changes to Production West Europe Cluster - if: false ## Disable production for now - env: - ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID: ${{ secrets.ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID }} - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - DOMAIN_NAME: ${{ vars.DOMAIN_NAME_PRODUCTION }} - run: bash ./cloud-infrastructure/cluster/config/production-west-europe.sh --plan - - staging: - name: Staging - if: github.ref == 'refs/heads/main' - needs: plan + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{ env.SUBSCRIPTION_ID }} + + - name: Plan Changes to Shared Environment Resources + run: bash ./cloud-infrastructure/environment/deploy-environment.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.SHARED_LOCATION }} --plan + + - name: Plan Changes to Cluster + run: bash ./cloud-infrastructure/cluster/deploy-cluster.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION }} ${{ env.CLUSTER_LOCATION_ACRONYM }} ${{ env.SQL_ADMIN_OBJECT_ID }} ${{ env.DOMAIN_NAME }} --plan + + deploy-stage: + name: Deploy Staging + needs: plan-stage runs-on: ubuntu-latest - environment: "staging" ## Force a manual approval + environment: "staging" # Force a manual approval + if: ${{ vars.STAGING_CLUSTER_ENABLED == 'true' && github.ref != 'refs/heads/main' }} + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "stage" + SHARED_LOCATION: ${{ vars.STAGING_SHARED_LOCATION }} + CLUSTER_LOCATION: ${{ vars.STAGING_CLUSTER_LOCATION }} + CLUSTER_LOCATION_ACRONYM: ${{ vars.STAGING_CLUSTER_LOCATION_ACRONYM }} + SQL_ADMIN_OBJECT_ID: ${{ vars.STAGING_SQL_ADMIN_OBJECT_ID }} + DOMAIN_NAME: ${{ vars.STAGING_DOMAIN_NAME }} + SERVICE_PRINCIPAL_ID: ${{ vars.STAGING_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.STAGING_SUBSCRIPTION_ID }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -90,50 +94,88 @@ jobs: sudo apt-get update && sudo apt-get install -y sqlcmd - - name: Login to Azure Subscription + - name: Login to Azure uses: azure/login@v2 with: - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{ env.SUBSCRIPTION_ID }} - - name: Deploy Shared Staging Environment Resources - env: - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - run: bash ./cloud-infrastructure/environment/config/staging.sh --apply + - name: Deploy Shared Environment Resources + run: bash ./cloud-infrastructure/environment/deploy-environment.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.SHARED_LOCATION }} --apply - - name: Deploy Staging West Europe Cluster + - name: Deploy Cluster Resources id: deploy_cluster - env: - ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID: ${{ secrets.ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID }} - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - DOMAIN_NAME: ${{ vars.DOMAIN_NAME_STAGING }} - run: bash ./cloud-infrastructure/cluster/config/staging-west-europe.sh --apply + run: bash ./cloud-infrastructure/cluster/deploy-cluster.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION }} ${{ env.CLUSTER_LOCATION_ACRONYM }} ${{ env.SQL_ADMIN_OBJECT_ID }} ${{ env.DOMAIN_NAME }} --apply - - name: Refresh Azure Tokens ## The previous step may take a while, so we refresh the token to avoid timeouts + - name: Refresh Azure Tokens # The previous step may take a while, so we refresh the token to avoid timeouts uses: azure/login@v2 with: - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{ env.SUBSCRIPTION_ID }} - name: Grant Database Permissions - env: - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - ENVIRONMENT: "stage" - LOCATION_ACRONYM: "weu" run: | - ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID=${{ steps.deploy_cluster.outputs.ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID }} - bash ./cloud-infrastructure/cluster/grant-database-permissions.sh 'account-management' $ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID - BACK_OFFICE_IDENTITY_CLIENT_ID=${{ steps.deploy_cluster.outputs.BACK_OFFICE_IDENTITY_CLIENT_ID }} - bash ./cloud-infrastructure/cluster/grant-database-permissions.sh 'back-office' $BACK_OFFICE_IDENTITY_CLIENT_ID - - production: - name: Production - if: false && github.ref == 'refs/heads/main' ## Disable production for now - needs: staging + bash ./cloud-infrastructure/cluster/grant-database-permissions.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION_ACRONYM }} 'account-management' ${{ steps.deploy_cluster.outputs.ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID }} + bash ./cloud-infrastructure/cluster/grant-database-permissions.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION_ACRONYM }} 'back-office' ${{ steps.deploy_cluster.outputs.BACK_OFFICE_IDENTITY_CLIENT_ID }} + + plan-prod1: + name: Plan Changes Production + needs: deploy-stage + runs-on: ubuntu-latest + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "prod" + SHARED_LOCATION: ${{ vars.PRODUCTION_SHARED_LOCATION }} + CLUSTER_LOCATION: ${{ vars.PRODUCTION_CLUSTER1_LOCATION }} + CLUSTER_LOCATION_ACRONYM: ${{ vars.PRODUCTION_CLUSTER1_LOCATION_ACRONYM }} + SQL_ADMIN_OBJECT_ID: ${{ vars.PRODUCTION_SQL_ADMIN_OBJECT_ID }} + DOMAIN_NAME: ${{ vars.PRODUCTION_DOMAIN_NAME }} + SERVICE_PRINCIPAL_ID: ${{ vars.PRODUCTION_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.PRODUCTION_SUBSCRIPTION_ID }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Install Bicep CLI + run: | + curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 && + chmod +x ./bicep && + sudo mv ./bicep /usr/local/bin/bicep && + bicep --version + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{ env.SUBSCRIPTION_ID }} + + - name: Plan Changes to Shared Environment Resources + run: bash ./cloud-infrastructure/environment/deploy-environment.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.SHARED_LOCATION }} --plan + + - name: Plan Changes to Cluster + run: bash ./cloud-infrastructure/cluster/deploy-cluster.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION }} ${{ env.CLUSTER_LOCATION_ACRONYM }} ${{ env.SQL_ADMIN_OBJECT_ID }} ${{ env.DOMAIN_NAME }} --plan + + deploy-prod1: + name: Deploy Production + needs: plan-prod1 runs-on: ubuntu-latest - environment: "production" ## Force a manual approval + environment: "production" # Force a manual approval + if: ${{ vars.PRODUCTION_CLUSTER1_ENABLED == 'true' && github.ref == 'refs/heads/main' }} + env: + UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} + ENVIRONMENT: "prod" + SHARED_LOCATION: ${{ vars.PRODUCTION_SHARED_LOCATION }} + CLUSTER_LOCATION: ${{ vars.PRODUCTION_CLUSTER1_LOCATION }} + CLUSTER_LOCATION_ACRONYM: ${{ vars.PRODUCTION_CLUSTER1_LOCATION_ACRONYM }} + SQL_ADMIN_OBJECT_ID: ${{ vars.PRODUCTION_SQL_ADMIN_OBJECT_ID }} + DOMAIN_NAME: ${{ vars.PRODUCTION_DOMAIN_NAME }} + SERVICE_PRINCIPAL_ID: ${{ vars.PRODUCTION_SERVICE_PRINCIPAL_ID }} + TENANT_ID: ${{ vars.TENANT_ID }} + SUBSCRIPTION_ID: ${{ vars.PRODUCTION_SUBSCRIPTION_ID }} steps: - name: Checkout Code uses: actions/checkout@v4 @@ -153,40 +195,28 @@ jobs: sudo apt-get update && sudo apt-get install -y sqlcmd - - name: Login to Azure Subscription + - name: Login to Azure uses: azure/login@v2 with: - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{env.SUBSCRIPTION_ID }} - - name: Deploy Shared Production Environment Resources - env: - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - run: bash ./cloud-infrastructure/environment/config/production.sh --apply + - name: Deploy Shared Environment Resources + run: bash ./cloud-infrastructure/environment/deploy-environment.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.SHARED_LOCATION }} --apply - - name: Deploy Production West Europe Cluster + - name: Deploy Cluster Resources id: deploy_cluster - env: - ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID: ${{ secrets.ACTIVE_DIRECTORY_SQL_ADMIN_OBJECT_ID }} - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - DOMAIN_NAME: ${{ vars.DOMAIN_NAME_PRODUCTION }} - run: bash ./cloud-infrastructure/cluster/config/production-west-europe.sh --apply + run: bash ./cloud-infrastructure/cluster/deploy-cluster.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION }} ${{ env.CLUSTER_LOCATION_ACRONYM }} ${{ env.SQL_ADMIN_OBJECT_ID }} ${{ env.DOMAIN_NAME }} --apply - - name: Refresh Azure Tokens ## The previous step may take a while, so we refresh the token to avoid timeouts + - name: Refresh Azure Tokens # The previous step may take a while, so we refresh the token to avoid timeouts uses: azure/login@v2 with: - client-id: ${{ secrets.AZURE_SERVICE_PRINCIPAL_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + client-id: ${{ env.SERVICE_PRINCIPAL_ID }} + tenant-id: ${{ env.TENANT_ID }} + subscription-id: ${{env.SUBSCRIPTION_ID }} - name: Grant Database Permissions - env: - UNIQUE_PREFIX: ${{ vars.UNIQUE_PREFIX }} - ENVIRONMENT: "prod" - LOCATION_ACRONYM: "weu" run: | - ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID=${{ steps.deploy_cluster.outputs.ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID }} - bash ./cloud-infrastructure/cluster/grant-database-permissions.sh 'account-management' $ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID - BACK_OFFICE_IDENTITY_CLIENT_ID=${{ steps.deploy_cluster.outputs.BACK_OFFICE_IDENTITY_CLIENT_ID }} - bash ./cloud-infrastructure/cluster/grant-database-permissions.sh 'back-office' $BACK_OFFICE_IDENTITY_CLIENT_ID + bash ./cloud-infrastructure/cluster/grant-database-permissions.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION_ACRONYM }} 'account-management' ${{ steps.deploy_cluster.outputs.ACCOUNT_MANAGEMENT_IDENTITY_CLIENT_ID }} + bash ./cloud-infrastructure/cluster/grant-database-permissions.sh ${{ env.UNIQUE_PREFIX }} ${{ env.ENVIRONMENT }} ${{ env.CLUSTER_LOCATION_ACRONYM }} 'back-office' ${{ steps.deploy_cluster.outputs.BACK_OFFICE_IDENTITY_CLIENT_ID }}