Skip to content

Commit

Permalink
Add deploy workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
johnake committed Sep 12, 2023
1 parent b42b844 commit 46c2a16
Show file tree
Hide file tree
Showing 19 changed files with 435 additions and 30 deletions.
68 changes: 68 additions & 0 deletions .github/workflows/actions/deploy_v2/action.yml
Original file line number Diff line number Diff line change
@@ -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
57 changes: 57 additions & 0 deletions .github/workflows/actions/smoke-test-v2/action.yml
Original file line number Diff line number Diff line change
@@ -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 }}
54 changes: 53 additions & 1 deletion .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
description: "Deploy environment ( dev, test, preprod or production )"
required: true
default: dev
type: environment
type: choice
options:
- dev
- test
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/deploy_aks.yml
Original file line number Diff line number Diff line change
@@ -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 }}
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -191,6 +199,8 @@ terraform-init-aks: bin/terrafile
[[ "${SP_AUTH}" != "true" ]] && az account set -s $(AZURE_SUBSCRIPTION) || true
./bin/terrafile -p terraform/aks/vendor/modules -f terraform/aks/workspace_variables/$(CONFIG)_Terrafile
terraform -chdir=terraform/aks init -backend-config workspace_variables/$(CONFIG).backend.tfvars $(backend_config) -upgrade -reconfigure
$(if $(IMAGE_TAG), , $(eval export IMAGE_TAG=2ad42e8958a4d63ed295a58a0847430705725ba8))
$(if $(DOCKER_IMAGE), $(eval export TF_VAR_paas_app_docker_image=$(DOCKER_IMAGE)), $(eval export TF_VAR_paas_app_docker_image=ghcr.io/dfe-digital/find-a-lost-trn:$(IMAGE_TAG)))

terraform-plan-aks: terraform-init-aks
terraform -chdir=terraform/aks plan -var-file workspace_variables/$(CONFIG).tfvars.json
Expand All @@ -205,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
Expand Down
2 changes: 1 addition & 1 deletion global_config/preproduction_aks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_preprod.tfstate
7 changes: 7 additions & 0 deletions global_config/review_aks.sh
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion global_config/test_aks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
DOMAINS_TERRAFORM_BACKEND_KEY=faltrndomains_test.tfstate
64 changes: 64 additions & 0 deletions terraform/aks/application.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,68 @@
locals {
environment = "${var.app_environment}${var.app_suffix}"
service_name = "find-a-lost-trn"
app_secrets = {
DATABASE_URL = var.deploy_postgres ? module.postgres.url : "${data.azurerm_key_vault_secret.db_url[0].value}"
REDIS_URL = var.deploy_redis ? module.redis[0].url : "${data.azurerm_key_vault_secret.redis_url[0].value}"
}
postgres_ssl_mode = var.enable_postgres_ssl ? "require" : "disable"
}

module "web_application" {
source = "./vendor/modules/aks//aks/application"

is_web = true

namespace = var.namespace
environment = local.environment
service_name = local.service_name

cluster_configuration_map = module.cluster_data.configuration_map

kubernetes_config_map_name = module.application_configuration.kubernetes_config_map_name
kubernetes_secret_name = module.application_configuration.kubernetes_secret_name

docker_image = var.paas_app_docker_image
max_memory = var.memory_max
replicas = var.replicas
web_external_hostnames = var.gov_uk_host_names
web_port = 3000
probe_path = "/health"
}

module "application_configuration" {
source = "./vendor/modules/aks//aks/application_configuration"

namespace = var.namespace
environment = local.environment
azure_resource_prefix = var.azure_resource_prefix
service_short = var.service_short
config_short = var.config_short
config_variables = {
AKS_ENV_NAME = var.file_environment
EnableMetrics = false
PGSSLMODE = local.postgres_ssl_mode
}
secret_variables = local.app_secrets
secret_key_vault_short = "app"
}

module "worker_application" {
source = "./vendor/modules/aks//aks/application"

name = "worker"
is_web = false

namespace = var.namespace
environment = local.environment
service_name = local.service_name

cluster_configuration_map = module.cluster_data.configuration_map

kubernetes_config_map_name = module.application_configuration.kubernetes_config_map_name
kubernetes_secret_name = module.application_configuration.kubernetes_secret_name

docker_image = var.paas_app_docker_image
command = ["bundle", "exec", "sidekiq", "-C", "./config/sidekiq.yml"]
probe_command = ["pgrep", "-f", "sidekiq"]
}
Loading

0 comments on commit 46c2a16

Please sign in to comment.