From 56443fe761fb47509b169403eb5d158e9b6809fd Mon Sep 17 00:00:00 2001 From: John Ake Date: Fri, 18 Aug 2023 09:34:19 +0100 Subject: [PATCH] Add deploy workflow --- .../workflows/actions/deploy_v2/action.yml | 68 +++++++++++++++++++ .../actions/smoke-test-v2/action.yml | 57 ++++++++++++++++ .github/workflows/build-and-deploy.yml | 54 ++++++++++++++- .github/workflows/deploy.yml | 2 +- .github/workflows/deploy_aks.yml | 52 ++++++++++++++ Makefile | 12 +++- global_config/preproduction_aks.sh | 2 +- global_config/review_aks.sh | 7 ++ global_config/test_aks.sh | 2 +- .../development_aks.tfvars.json | 3 +- .../preproduction_aks.tfvars.json | 3 +- .../production_aks.tfvars.json | 3 +- .../review_aks.backend.tfvars | 3 + .../review_aks.tfvars.json | 12 ++++ .../workspace_variables/review_aks_Terrafile | 4 ++ .../workspace_variables/test_aks.tfvars.json | 3 +- 16 files changed, 277 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/actions/deploy_v2/action.yml create mode 100644 .github/workflows/actions/smoke-test-v2/action.yml create mode 100644 .github/workflows/deploy_aks.yml create mode 100644 global_config/review_aks.sh create mode 100644 terraform/aks/workspace_variables/review_aks.backend.tfvars create mode 100644 terraform/aks/workspace_variables/review_aks.tfvars.json create mode 100644 terraform/aks/workspace_variables/review_aks_Terrafile diff --git a/.github/workflows/actions/deploy_v2/action.yml b/.github/workflows/actions/deploy_v2/action.yml new file mode 100644 index 00000000..39a1f302 --- /dev/null +++ b/.github/workflows/actions/deploy_v2/action.yml @@ -0,0 +1,68 @@ +name: Deploy to AKS +description: deploys application +inputs: + environment: + description: Environment to deploy to + required: true + docker_image: + description: Docker image to be deployed + required: true + azure-credentials: + description: Credentials for azure + required: true + arm-access-key: + required: true + pr-id: + description: PR number for the review app + required: false +outputs: + deploy-url: + value: ${{ steps.set_env_var.outputs.deploy_url }} +runs: + using: composite + steps: + - name: Set Environment variables + id: set_env_var + shell: bash + run: | + tf_vars_file=terraform/aks/workspace_variables/${{ inputs.environment }}.tfvars.json + terraform_version=$(awk '/{/{f=/^terraform/;next}f' terraform/aks/terraform.tf | grep -o [0-9\.]*) + echo "cluster=$(jq -r '.cluster' ${tf_vars_file})" >> $GITHUB_ENV + echo "TERRAFORM_VERSION=$terraform_version" >> $GITHUB_ENV + echo "namespace=$(jq -r '.namespace' ${tf_vars_file})" >> $GITHUB_ENV + + if [ -n "${{ inputs.pr-id }}" ]; then + APP_NAME=pr-${{ inputs.pr-id }} + echo "deploy_url=https://find-a-lost-trn-review-${APP_NAME}.test.teacherservices.cloud" >> $GITHUB_OUTPUT + else + aks_app_environment=$(jq -r '.app_environment' ${tf_vars_file}) + hostname=$(jq -r '.gov_uk_host_names[0]' ${tf_vars_file}) + if [[ $hostname != null ]]; then + echo "deploy_url=https://${hostname}" >> $GITHUB_OUTPUT + else + if [[ $cluster == 'production' ]]; then + echo "deploy_url=https://find-a-lost-trn-${aks_app_environment}.teacherservices.cloud" >> $GITHUB_OUTPUT + else + echo "deploy_url=https://find-a-lost-trn-${aks_app_environment}.${cluster}.teacherservices.cloud" >> $GITHUB_OUTPUT + fi + fi + fi + + - name: Use Terraform ${{ env.TERRAFORM_VERSION }} + uses: hashicorp/setup-terraform@v2 + with: + terraform_version: ${{ env.TERRAFORM_VERSION }} + + - uses: azure/login@v1 + with: + creds: ${{ inputs.azure-credentials }} + + - name: Terraform init, plan & apply + shell: bash + run: make ci ${{ inputs.environment }} terraform-apply-aks + env: + ARM_ACCESS_KEY: ${{ inputs.arm-access-key }} + DOCKER_IMAGE: ${{ inputs.docker_image }} + pr_id: ${{ inputs.pr-id }} + TF_VAR_azure_credentials: ${{ inputs.azure-credentials }} + CONFIRM_PRODUCTION: true diff --git a/.github/workflows/actions/smoke-test-v2/action.yml b/.github/workflows/actions/smoke-test-v2/action.yml new file mode 100644 index 00000000..589c2e7b --- /dev/null +++ b/.github/workflows/actions/smoke-test-v2/action.yml @@ -0,0 +1,57 @@ +name: Run smoke test + +inputs: + environment: + description: The name of the environment + required: true + azure_credentials: + description: JSON object containing a service principal that can read from Azure Key Vault + required: true + +runs: + using: composite + + steps: + - uses: Azure/login@v1 + with: + creds: ${{ inputs.azure_credentials }} + + - name: Prepare application environment + uses: ./.github/actions/prepare-app-env + + - name: Set environment variables + shell: bash + run: | + tf_vars_file=terraform/aks/workspace_variables/${{ inputs.environment }}.tfvars.json + echo "APP_KEY_VAULT=$(jq -r '.app_key_vault' ${tf_vars_file})" >> $GITHUB_ENV + + - name: Retrieve Secrets from KV + uses: azure/CLI@v1 + id: retrieve-secrets + with: + inlineScript: | + HOSTING_DOMAIN=$(az keyvault secret show --name HOSTING-DOMAIN --vault-name "${{ env.APP_KEY_VAULT}}" --query 'value' -o tsv) + echo "::add-mask::$HOSTING_DOMAIN" + echo "HOSTING_DOMAIN=$HOSTING_DOMAIN" >> $GITHUB_OUTPUT + GOVUK_NOTIFY_API_KEY=$(az keyvault secret show --name GOVUK-NOTIFY-API-KEY --vault-name "${{ env.APP_KEY_VAULT}}" --query 'value' -o tsv) + echo "::add-mask::$GOVUK_NOTIFY_API_KEY" + echo "GOVUK_NOTIFY_API_KEY=$GOVUK_NOTIFY_API_KEY" >> $GITHUB_OUTPUT + HOSTING_ENVIRONMENT_NAME=$(az keyvault secret show --name HOSTING-ENVIRONMENT-NAME --vault-name "${{ env.APP_KEY_VAULT}}" --query 'value' -o tsv) + echo "::add-mask::$HOSTING_ENVIRONMENT_NAME" + echo "HOSTING_ENVIRONMENT_NAME=$HOSTING_ENVIRONMENT_NAME" >> $GITHUB_OUTPUT + SUPPORT_USERNAME=$(az keyvault secret show --name SUPPORT-USERNAME --vault-name "${{ env.APP_KEY_VAULT}}" --query 'value' -o tsv) + echo "::add-mask::$SUPPORT_USERNAME" + echo "SUPPORT_USERNAME=$SUPPORT_USERNAME" >> $GITHUB_OUTPUT + SUPPORT_PASSWORD=$(az keyvault secret show --name SUPPORT-PASSWORD --vault-name "${{ env.APP_KEY_VAULT}}" --query 'value' -o tsv) + echo "::add-mask::$SUPPORT_PASSWORD" + echo "SUPPORT_PASSWORD=$SUPPORT_PASSWORD" >> $GITHUB_OUTPUT + + - name: Run deployment smoke test + shell: bash + run: bin/smoke + env: + HOSTING_DOMAIN: ${{ steps.retrieve-secrets.outputs.HOSTING_DOMAIN }} + RAILS_ENV: ${{ steps.retrieve-secrets.outputs.HOSTING_ENVIRONMENT_NAME }} + GOVUK_NOTIFY_API_KEY: ${{ steps.retrieve-secrets.outputs.GOVUK_NOTIFY_API_KEY }} + SUPPORT_USERNAME: ${{ steps.retrieve-secrets.outputs.SUPPORT_USERNAME }} + SUPPORT_PASSWORD: ${{ steps.retrieve-secrets.outputs.SUPPORT_PASSWORD }} diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index e0edf8a6..84e9c25e 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -21,7 +21,7 @@ env: jobs: docker: name: Docker build and push - if: contains(github.event.pull_request.labels.*.name, 'deploy') || github.event_name != 'pull_request' + if: contains(github.event.pull_request.labels.*.name, 'deploy') || contains(github.event.pull_request.labels.*.name, 'deploy_v2') || github.event_name != 'pull_request' runs-on: ubuntu-latest outputs: docker_image: ${{ steps.dockerimage.outputs.docker_image_tag }} @@ -60,6 +60,58 @@ jobs: message: | Review app deployed to ${{ steps.deploy.outputs.environment_url }} + deploy_v2_review: + name: Deploy to review_aks environment + concurrency: deploy_v2_review_${{ github.event.pull_request.number }} + needs: [docker] + runs-on: ubuntu-latest + if: contains(github.event.pull_request.labels.*.name, 'deploy_v2') + environment: + name: review_aks + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/workflows/actions/deploy_v2 + id: deploy_v2 + with: + environment: review_aks + docker_image: ${{ needs.docker.outputs.docker_image }} + azure-credentials: ${{ secrets.AZURE_CREDENTIALS }} + arm-access-key: ${{ secrets.ARM_ACCESS_KEY }} + pr-id: ${{ github.event.pull_request.number }} + + - name: Post sticky pull request comment + if: github.event_name == 'pull_request' + uses: marocchino/sticky-pull-request-comment@v2 + with: + message: | + AKS review app deployed to ${{ steps.deploy_v2.outputs.environment_url }} + + deploy_v2_dev: + name: Deploy to development_aks environment + concurrency: deploy_v2_development + needs: [docker] + runs-on: ubuntu-latest + continue-on-error: true + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + environment: + name: development_aks + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/workflows/actions/deploy_v2 + id: deploy_v2 + with: + environment: development_aks + docker_image: ${{ needs.docker.outputs.docker_image }} + azure-credentials: ${{ secrets.AZURE_CREDENTIALS }} + arm-access-key: ${{ secrets.ARM_ACCESS_KEY }} + - uses: ./.github/workflows/actions/smoke-test-v2 + id: smoke-test + with: + environment: development + azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} + deploy_nonprod: name: Deploy to ${{ matrix.environment }} environment runs-on: ubuntu-latest diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1da3c84e..0cfd920d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,7 +6,7 @@ on: description: "Deploy environment ( dev, test, preprod or production )" required: true default: dev - type: environment + type: choice options: - dev - test diff --git a/.github/workflows/deploy_aks.yml b/.github/workflows/deploy_aks.yml new file mode 100644 index 00000000..a9b0a5a0 --- /dev/null +++ b/.github/workflows/deploy_aks.yml @@ -0,0 +1,52 @@ +name: Manual deployment +on: + workflow_dispatch: + inputs: + environment: + description: "Deploy environment ( development_aks, test, preprod or production )" + required: true + default: development_aks + type: choice + options: + - development_aks + sha: + description: Commit sha to be deployed + required: true + default: 588bfd4567e53f6b809d5ed107dc70b3d040710a + type: choice + options: + - 588bfd4567e53f6b809d5ed107dc70b3d040710a +env: + CONTAINER_REGISTRY: ghcr.io + +jobs: + deploy_v2_environment: + name: Deploy to development_aks environment + runs-on: ubuntu-latest + environment: + name: development_aks + steps: + - uses: actions/checkout@v3 + + - name: Docker image tag + id: image + run: | + echo ::set-output name=tag::$CONTAINER_REGISTRY/$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]'):$INPUT_GITHUB_SHA + env: + CONTAINER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} + INPUT_GITHUB_SHA: 588bfd4567e53f6b809d5ed107dc70b3d040710a + shell: bash + + - uses: ./.github/workflows/actions/deploy_v2 + id: deploy + with: + environment: development_aks + docker_image: ${{ steps.image.outputs.tag }} + azure-credentials: ${{ secrets.AZURE_CREDENTIALS }} + arm-access-key: ${{ secrets.ARM_ACCESS_KEY }} + + - uses: ./.github/workflows/actions/smoke-test-v2 + id: smoke-test + with: + environment: development_aks + azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} diff --git a/Makefile b/Makefile index e48d0c83..8479b34f 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ dev: .PHONY: development_aks ## For AKS development_aks: aks ## Specify development aks environment $(eval include global_config/development_aks.sh) - + .PHONY: test test: $(eval DEPLOY_ENV=test) @@ -78,7 +78,15 @@ review: $(eval backend_config=-backend-config="key=review/review$(env).tfstate") $(eval export TF_VAR_app_suffix=$(env)) +.PHONY: review_aks +review_aks: aks ## Specify review aks environment + $(if $(pr_id), , $(error Missing environment variable "pr_id")) + $(eval include global_config/review_aks.sh) + $(eval env=-pr-$(pr_id)) + $(eval backend_config=-backend-config="key=review_aks$(env).tfstate") + $(eval export TF_VAR_app_suffix=$(env)) +.PHONY: ci ci: ## Run in automation environment $(eval DISABLE_PASSCODE=true) $(eval AUTO_APPROVE=-auto-approve) @@ -207,7 +215,7 @@ deploy-azure-resources: set-azure-account tags # make dev deploy-azure-resources $(if $(CONFIRM_DEPLOY), , $(error can only run with CONFIRM_DEPLOY)) az deployment sub create -l "West Europe" --template-uri "https://raw.githubusercontent.com/DFE-Digital/tra-shared-services/main/azure/resourcedeploy.json" --parameters "resourceGroupName=${RESOURCE_NAME_PREFIX}-faltrn-${ENV_SHORT}-rg" 'tags=${RG_TAGS}' "environment=${DEPLOY_ENV}" "tfStorageAccountName=${RESOURCE_NAME_PREFIX}faltrntfstate${ENV_SHORT}" "tfStorageContainerName=faltrn-tfstate" "dbBackupStorageAccountName=false" "dbBackupStorageContainerName=false" "keyVaultName=${RESOURCE_NAME_PREFIX}-faltrn-${ENV_SHORT}-kv" -validate-azure-resources: set-azure-account tags# make dev validate-azure-resources +validate-azure-resources: set-azure-account tags # make dev validate-azure-resources az deployment sub create -l "West Europe" --template-uri "https://raw.githubusercontent.com/DFE-Digital/tra-shared-services/main/azure/resourcedeploy.json" --parameters "resourceGroupName=${RESOURCE_NAME_PREFIX}-faltrn-${ENV_SHORT}-rg" 'tags=${RG_TAGS}' "environment=${DEPLOY_ENV}" "tfStorageAccountName=${RESOURCE_NAME_PREFIX}faltrntfstate${ENV_SHORT}" "tfStorageContainerName=faltrn-tfstate" "dbBackupStorageAccountName=false" "dbBackupStorageContainerName=false" "keyVaultName=${RESOURCE_NAME_PREFIX}-faltrn-${ENV_SHORT}-kv" --what-if .PHONY: set-azure-template-tag diff --git a/global_config/preproduction_aks.sh b/global_config/preproduction_aks.sh index 90dbbbbd..ec16091d 100644 --- a/global_config/preproduction_aks.sh +++ b/global_config/preproduction_aks.sh @@ -4,4 +4,4 @@ CONFIG_SHORT=pp AZURE_SUBSCRIPTION=s189-teacher-services-cloud-test AZURE_RESOURCE_PREFIX=s189t01 ENV_TAG=Test -DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_preprod.tfstate \ No newline at end of file +DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_preprod.tfstate diff --git a/global_config/review_aks.sh b/global_config/review_aks.sh new file mode 100644 index 00000000..23f35d0e --- /dev/null +++ b/global_config/review_aks.sh @@ -0,0 +1,7 @@ +CONFIG=review_aks +DEPLOY_ENV=review +CONFIG_SHORT=rv +AZURE_SUBSCRIPTION=s189-teacher-services-cloud-test +AZURE_RESOURCE_PREFIX=s189t01 +ENV_TAG=Test +DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_review.tfstate diff --git a/global_config/test_aks.sh b/global_config/test_aks.sh index 93610fd7..1673b1f5 100644 --- a/global_config/test_aks.sh +++ b/global_config/test_aks.sh @@ -4,4 +4,4 @@ CONFIG_SHORT=ts AZURE_SUBSCRIPTION=s189-teacher-services-cloud-test AZURE_RESOURCE_PREFIX=s189t01 ENV_TAG=Test -DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_test.tfstate \ No newline at end of file +DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_test.tfstate diff --git a/terraform/aks/workspace_variables/development_aks.tfvars.json b/terraform/aks/workspace_variables/development_aks.tfvars.json index ebe622e1..dc9b89c0 100644 --- a/terraform/aks/workspace_variables/development_aks.tfvars.json +++ b/terraform/aks/workspace_variables/development_aks.tfvars.json @@ -6,5 +6,6 @@ "namespace": "tra-development", "azure_resource_prefix": "s189t01", "config_short": "dv", - "service_short": "faltrn" + "service_short": "faltrn", + "app_key_vault": "s189t01-faltrn-dv-app-kv" } diff --git a/terraform/aks/workspace_variables/preproduction_aks.tfvars.json b/terraform/aks/workspace_variables/preproduction_aks.tfvars.json index 70afb624..1f066b1f 100644 --- a/terraform/aks/workspace_variables/preproduction_aks.tfvars.json +++ b/terraform/aks/workspace_variables/preproduction_aks.tfvars.json @@ -5,5 +5,6 @@ "namespace": "tra-test", "azure_resource_prefix": "s189t01", "config_short": "pp", - "service_short": "faltrn" + "service_short": "faltrn", + "app_key_vault": "s189t01-faltrn-pp-app-kv" } diff --git a/terraform/aks/workspace_variables/production_aks.tfvars.json b/terraform/aks/workspace_variables/production_aks.tfvars.json index a6d5ca68..9e0c6a86 100644 --- a/terraform/aks/workspace_variables/production_aks.tfvars.json +++ b/terraform/aks/workspace_variables/production_aks.tfvars.json @@ -5,5 +5,6 @@ "namespace": "tra-production", "azure_resource_prefix": "s189p01", "config_short": "pd", - "service_short": "faltrn" + "service_short": "faltrn", + "app_key_vault": "s189p01-faltrn-pp-app-kv" } diff --git a/terraform/aks/workspace_variables/review_aks.backend.tfvars b/terraform/aks/workspace_variables/review_aks.backend.tfvars new file mode 100644 index 00000000..3d01b90c --- /dev/null +++ b/terraform/aks/workspace_variables/review_aks.backend.tfvars @@ -0,0 +1,3 @@ +resource_group_name = "s189t01-faltrn-rv-rg" +storage_account_name = "s189t01faltrntfstatervsa" + diff --git a/terraform/aks/workspace_variables/review_aks.tfvars.json b/terraform/aks/workspace_variables/review_aks.tfvars.json new file mode 100644 index 00000000..7ad851fc --- /dev/null +++ b/terraform/aks/workspace_variables/review_aks.tfvars.json @@ -0,0 +1,12 @@ +{ + "app_environment": "review", + "cluster": "test", + "file_environment": "review", + "enable_monitoring": false, + "namespace": "tra-development", + "azure_resource_prefix": "s189t01", + "config_short": "rv", + "service_short": "faltrn", + "deploy_azure_backing_services": false, + "enable_postgres_ssl": false +} diff --git a/terraform/aks/workspace_variables/review_aks_Terrafile b/terraform/aks/workspace_variables/review_aks_Terrafile new file mode 100644 index 00000000..fa0b42c0 --- /dev/null +++ b/terraform/aks/workspace_variables/review_aks_Terrafile @@ -0,0 +1,4 @@ +aks: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "main" + \ No newline at end of file diff --git a/terraform/aks/workspace_variables/test_aks.tfvars.json b/terraform/aks/workspace_variables/test_aks.tfvars.json index 5203ec3e..787a8aa2 100644 --- a/terraform/aks/workspace_variables/test_aks.tfvars.json +++ b/terraform/aks/workspace_variables/test_aks.tfvars.json @@ -5,5 +5,6 @@ "namespace": "tra-test", "azure_resource_prefix": "s189t01", "config_short": "ts", - "service_short": "faltrn" + "service_short": "faltrn", + "app_key_vault": "s189t01-faltrn-ts-app-kv" }