From 0acb9182b8c3361580ba8ea3d3f1450a5e9390a6 Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 9 Jan 2025 12:40:58 +0000 Subject: [PATCH 1/5] Github action to test application deployment --- .../actions/test-app-deployment/action.yml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/actions/test-app-deployment/action.yml diff --git a/.github/actions/test-app-deployment/action.yml b/.github/actions/test-app-deployment/action.yml new file mode 100644 index 00000000..80d6dbcf --- /dev/null +++ b/.github/actions/test-app-deployment/action.yml @@ -0,0 +1,73 @@ +name: Test application deployment +description: Test deployment of an ITTMS review app to the cluster + +inputs: + azure-client-id: + description: Azure managed identity client ID for OIDC authentication + required: true + azure-subscription-id: + description: Azure managed identity subscription ID for OIDC authentication + required: true + azure-tenant-id: + description: Azure managed identity tenant ID for OIDC authentication + required: true + environment: + description: The application environment config + required: true + +runs: + using: composite + + steps: + - name: Check out ITTMS repository + uses: actions/checkout@v4 + with: + repository: DFE-Digital/itt-mentor-services + path: itt-mentor-services + ref: 843-github-actions-oidc # Remove this line when the 843-github-actions-oidc branch is merged + + - name: Set Environment variables + id: set_env_var + shell: bash + working-directory: itt-mentor-services + run: | + terraform_version=$(awk '/{/{f=/^terraform/;next}f' terraform/application/terraform.tf | grep -o [0-9\.]*) + echo "TERRAFORM_VERSION=$terraform_version" >> $GITHUB_ENV + + - name: Use Terraform ${{ env.TERRAFORM_VERSION }} + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TERRAFORM_VERSION }} + terraform_wrapper: false + + - uses: DFE-Digital/github-actions/set-kubelogin-environment@master + with: + azure-client-id: ${{ inputs.azure-client-id }} + azure-tenant-id: ${{ inputs.azure-tenant-id }} + azure-subscription-id: ${{ inputs.azure-subscription-id }} + + - name: Deploy application to ${{ inputs.environment }} + shell: bash + working-directory: itt-mentor-services + run: make ${{ inputs.environment }} ci terraform-apply + env: + DOCKER_IMAGE_TAG: main + PR_NUMBER: 9999 + + - name: Run healthcheck + shell: bash + working-directory: itt-mentor-services + run: | + external_urls=$(terraform -chdir=terraform/application output -json external_urls | jq -r '.[]') + for url in $external_urls; do + echo "Check health for $url/healthcheck/all..." + curl -sS --fail "$url/healthcheck/all" > /dev/null + done + + - name: Delete application + shell: bash + working-directory: itt-mentor-services + run: make ${{ inputs.environment }} ci terraform-destroy + env: + DOCKER_IMAGE_TAG: main + PR_NUMBER: 9999 From 93f58f40d33d0cf71fd7467bceb129674c2ffe25 Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 9 Jan 2025 12:41:41 +0000 Subject: [PATCH 2/5] Use federated credentials in Github workflows --- .github/actions/deploy-environment/action.yml | 21 ++++++++++++++----- .github/workflows/deploy-cluster.yml | 21 ++++++++++++++++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/.github/actions/deploy-environment/action.yml b/.github/actions/deploy-environment/action.yml index ff265ab9..e1fa66f3 100644 --- a/.github/actions/deploy-environment/action.yml +++ b/.github/actions/deploy-environment/action.yml @@ -1,8 +1,15 @@ -name: Deploy Environment +name: Deploy environment +description: Deploy cluster and configure kubernetes inputs: - azure_credentials: - description: Credentials with Contributor & KeyVault access to Azure subscription + azure-client-id: + description: Azure managed identity client ID for OIDC authentication + required: true + azure-subscription-id: + description: Azure managed identity subscription ID for OIDC authentication + required: true + azure-tenant-id: + description: Azure managed identity tenant ID for OIDC authentication required: true environment_name: description: Name of the environment in Makefile @@ -60,7 +67,9 @@ runs: - uses: Azure/login@v2 with: - creds: ${{ inputs.azure_credentials }} + client-id: ${{ inputs.azure-client-id }} + tenant-id: ${{ inputs.azure-tenant-id }} + subscription-id: ${{ inputs.azure-subscription-id }} - id: deploy-arm-resources run: | @@ -75,7 +84,9 @@ runs: - name: Set ARM and kubelogin environment uses: DFE-Digital/github-actions/set-kubelogin-environment@master with: - azure-credentials: ${{ inputs.AZURE_CREDENTIALS }} + azure-client-id: ${{ inputs.azure-client-id }} + azure-tenant-id: ${{ inputs.azure-tenant-id }} + azure-subscription-id: ${{ inputs.azure-subscription-id }} - id: terraform run: | diff --git a/.github/workflows/deploy-cluster.yml b/.github/workflows/deploy-cluster.yml index b19b9139..8af16ea4 100644 --- a/.github/workflows/deploy-cluster.yml +++ b/.github/workflows/deploy-cluster.yml @@ -13,7 +13,6 @@ on: - reopened - opened - converted_to_draft - workflow_dispatch: jobs: validate-terraform: @@ -91,14 +90,28 @@ jobs: max-parallel: 1 matrix: environment: [platform-test, test, production] + permissions: + id-token: write # Required for OIDC authentication to Azure + steps: - uses: actions/checkout@v4 - uses: ./.github/actions/deploy-environment with: - azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} + azure-client-id: ${{ secrets.AZURE_CLIENT_ID }} + azure-subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }} environment_name: ${{ matrix.environment }} + - name: Test application deployment + if: vars.TEST_APP_DEPLOYMENT == 'true' + uses: ./.github/actions/test-app-deployment + with: + azure-client-id: ${{ secrets.AZURE_CLIENT_ID }} + azure-subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }} + environment: ${{ vars.ITTMS_ENVIRONMENT }} + - name: Send Slack notification on failure if: failure() uses: rtCamp/action-slack-notify@master @@ -133,7 +146,9 @@ jobs: - name: Set ARM environment variables uses: DFE-Digital/github-actions/set-arm-environment-variables@master with: - azure-credentials: ${{ secrets.AZURE_CREDENTIALS }} + azure-client-id: ${{ secrets.AZURE_CLIENT_ID }} + azure-subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }} - name: Update DNS in ${{ matrix.environment }} run: | From 584b2a5319fe97debcbb892ef9942a36761c360e Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 9 Jan 2025 12:43:20 +0000 Subject: [PATCH 3/5] Use federated credentials in kubernetes terraform --- cluster/terraform_kubernetes/terraform.tf | 52 +++++++---------------- cluster/terraform_kubernetes/variables.tf | 24 ++++------- 2 files changed, 24 insertions(+), 52 deletions(-) diff --git a/cluster/terraform_kubernetes/terraform.tf b/cluster/terraform_kubernetes/terraform.tf index bf0380ec..7456570c 100644 --- a/cluster/terraform_kubernetes/terraform.tf +++ b/cluster/terraform_kubernetes/terraform.tf @@ -48,16 +48,11 @@ data "azurerm_kubernetes_cluster" "clone" { provider "kubernetes" { host = data.azurerm_kubernetes_cluster.main.kube_config[0].host cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].cluster_ca_certificate) - client_certificate = local.rbac_enabled ? null : base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].client_certificate) - client_key = local.rbac_enabled ? null : base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].client_key) - dynamic "exec" { - for_each = local.rbac_enabled ? [1] : [] - content { - api_version = "client.authentication.k8s.io/v1beta1" - command = "kubelogin" - args = local.kubelogin_args - } + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "kubelogin" + args = local.kubelogin_args } } @@ -65,16 +60,11 @@ provider "kubernetes" { alias = "clone" host = try(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].host, null) cluster_ca_certificate = try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].cluster_ca_certificate), null) - client_certificate = local.rbac_enabled_clone ? null : try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].client_certificate), null) - client_key = local.rbac_enabled_clone ? null : try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].client_key), null) - dynamic "exec" { - for_each = local.rbac_enabled_clone ? [1] : [] - content { - api_version = "client.authentication.k8s.io/v1beta1" - command = "kubelogin" - args = local.kubelogin_args - } + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "kubelogin" + args = local.kubelogin_args } } @@ -82,16 +72,11 @@ provider "helm" { kubernetes { host = data.azurerm_kubernetes_cluster.main.kube_config[0].host cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].cluster_ca_certificate) - client_certificate = local.rbac_enabled ? null : base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].client_certificate) - client_key = local.rbac_enabled ? null : base64decode(data.azurerm_kubernetes_cluster.main.kube_config[0].client_key) - dynamic "exec" { - for_each = local.rbac_enabled ? [1] : [] - content { - api_version = "client.authentication.k8s.io/v1beta1" - command = "kubelogin" - args = local.kubelogin_args - } + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "kubelogin" + args = local.kubelogin_args } } } @@ -101,16 +86,11 @@ provider "helm" { kubernetes { host = try(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].host, null) cluster_ca_certificate = try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].cluster_ca_certificate), null) - client_certificate = local.rbac_enabled_clone ? null : try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].client_certificate), null) - client_key = local.rbac_enabled_clone ? null : try(base64decode(data.azurerm_kubernetes_cluster.clone[0].kube_config[0].client_key), null) - dynamic "exec" { - for_each = local.rbac_enabled_clone ? [1] : [] - content { - api_version = "client.authentication.k8s.io/v1beta1" - command = "kubelogin" - args = local.kubelogin_args - } + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "kubelogin" + args = local.kubelogin_args } } } diff --git a/cluster/terraform_kubernetes/variables.tf b/cluster/terraform_kubernetes/variables.tf index 058419e7..0ca3275c 100644 --- a/cluster/terraform_kubernetes/variables.tf +++ b/cluster/terraform_kubernetes/variables.tf @@ -252,20 +252,8 @@ locals { lowpriority_app_name = "lowpriority-app" lowpriority_app_namespace = "infra" - rbac_enabled = length(data.azurerm_kubernetes_cluster.main.azure_active_directory_role_based_access_control) > 0 - rbac_enabled_clone = try( - length(data.azurerm_kubernetes_cluster.clone[0].azure_active_directory_role_based_access_control) > 0, - false - ) - - kubelogin_spn_args = [ + kubelogin_github_actions_args = [ "get-token", - "--login", - "spn", - "--environment", - "AzurePublicCloud", - "--tenant-id", - data.azurerm_client_config.current.tenant_id, "--server-id", "6dae42f8-4368-4678-94ff-3960e28e3630" # See https://azure.github.io/kubelogin/concepts/aks.html ] @@ -276,9 +264,13 @@ locals { "--server-id", "6dae42f8-4368-4678-94ff-3960e28e3630" ] - - spn_authentication = contains(keys(data.environment_variables.github_actions.items), "GITHUB_ACTIONS") - kubelogin_args = local.spn_authentication ? local.kubelogin_spn_args : local.kubelogin_azurecli_args + running_in_github_actions = contains(keys(data.environment_variables.github_actions.items), "GITHUB_ACTIONS") + # If running in github actions, AAD_LOGIN_METHOD determines the login method, either workloadidentity or spn + # If not, use azurecli explicitly as command line argument + kubelogin_args = (local.running_in_github_actions ? + local.kubelogin_github_actions_args : + local.kubelogin_azurecli_args + ) template_variable_map = { storage-account-name = azurerm_storage_account.thanos.name From aea83cf2e8896c4f65146c1d896c6bc7f25f1953 Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 9 Jan 2025 14:01:48 +0000 Subject: [PATCH 4/5] Refactor domains configuration Required to use the same environments as development and production to reuse the same federated credentials --- .github/workflows/check_sp.yml | 8 ++-- .github/workflows/deploy-cluster.yml | 4 +- Makefile | 42 +++++++++++-------- cluster/config/development.sh | 4 -- cluster/config/domains.sh | 5 +++ cluster/config/platform-test.sh | 4 -- cluster/config/production.sh | 4 -- cluster/config/test.sh | 4 -- custom_domains/config/dev-domain.sh | 10 ----- custom_domains/config/prod-domain.sh | 10 ----- ...cd.tfvars.json => development.tfvars.json} | 0 ...scp.tfvars.json => production.tfvars.json} | 0 12 files changed, 35 insertions(+), 60 deletions(-) create mode 100644 cluster/config/domains.sh delete mode 100644 custom_domains/config/dev-domain.sh delete mode 100644 custom_domains/config/prod-domain.sh rename custom_domains/terraform/infrastructure/config/{tscd.tfvars.json => development.tfvars.json} (100%) rename custom_domains/terraform/infrastructure/config/{tscp.tfvars.json => production.tfvars.json} (100%) diff --git a/.github/workflows/check_sp.yml b/.github/workflows/check_sp.yml index 88d5de1f..ac076498 100644 --- a/.github/workflows/check_sp.yml +++ b/.github/workflows/check_sp.yml @@ -14,10 +14,10 @@ jobs: - name: Select Tests id: select-tests run: | - d="{'environment' :'dev-domain' , 'principal': 's189d01-tsc-contributor'}" - t="{'environment' :'test' , 'principal': 's189t01-tsc-contributor'}" - p="{'environment' :'production' , 'principal': 's189p01-tsc-contributor'}" - tests="{ 'data':[ ${d} , ${t} , ${p} ]}" + d="{'environment' :'development', 'principal': 's189d01-tsc-contributor'}" + t="{'environment' :'test', 'principal': 's189t01-tsc-contributor'}" + p="{'environment' :'production', 'principal': 's189p01-tsc-contributor'}" + tests="{'data':[${d}, ${t}, ${p}]}" echo "tests=${tests}" >> $GITHUB_OUTPUT check_expires: diff --git a/.github/workflows/deploy-cluster.yml b/.github/workflows/deploy-cluster.yml index 8af16ea4..b17ecf5f 100644 --- a/.github/workflows/deploy-cluster.yml +++ b/.github/workflows/deploy-cluster.yml @@ -134,7 +134,7 @@ jobs: strategy: max-parallel: 1 matrix: - environment: [dev-domain, prod-domain] + environment: [development, production] steps: - uses: actions/checkout@v4 @@ -155,7 +155,7 @@ jobs: make ci ${{ matrix.environment }} domains-infra-apply shell: bash env: - TF_VAR_azure_sp_credentials_json: ${{ secrets.AZURE_CREDENTIALS }} + ENVIRONMENT: dummy # "make development" requires the ENVIRONMENT var but it is not used for domains - name: Send Slack notification on failure if: failure() diff --git a/Makefile b/Makefile index 7b15c469..852fbd21 100644 --- a/Makefile +++ b/Makefile @@ -22,13 +22,19 @@ production: $(if $(or ${CI}, ${CONFIRM_PRODUCTION}), , $(error Missing CONFIRM_PRODUCTION=yes)) $(eval include cluster/config/production.sh) -prod-domain: - $(if $(or ${CI}, ${CONFIRM_PROD_DOMAIN}), , $(error Missing CONFIRM_PROD_DOMAIN=yes)) - $(eval include custom_domains/config/prod-domain.sh) +domains: + $(eval include cluster/config/domains.sh) -dev-domain: - $(if $(or ${CI}, ${CONFIRM_DEV_DOMAIN}), , $(error Missing CONFIRM_DEV_DOMAIN=yes)) - $(eval include custom_domains/config/dev-domain.sh) +cluster-composed-variables: + $(eval RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-rg) + $(eval KEYVAULT_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-kv) + $(eval STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tsctfstate${CONFIG_SHORT}) + $(eval MANAGE_IDENTITY_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-id) + +domains-composed-variables: domains + $(eval RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tscdomains-rg) + $(eval KEYVAULT_NAME=${RESOURCE_PREFIX}-tscdomains-kv) + $(eval STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tscdomainstf) clone: $(eval CLONE_STRING=-clone) @@ -36,7 +42,7 @@ clone: set-azure-account: [ "${SKIP_AZURE_LOGIN}" != "true" ] && az account set -s ${AZ_SUBSCRIPTION} || true -terraform-aks-cluster-init: set-azure-account +terraform-aks-cluster-init: cluster-composed-variables set-azure-account terraform -chdir=cluster/terraform_aks_cluster init -reconfigure -upgrade \ -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} \ @@ -58,7 +64,7 @@ terraform-aks-cluster-apply: terraform-aks-cluster-init terraform-aks-cluster-destroy: terraform-aks-cluster-init terraform -chdir=cluster/terraform_aks_cluster destroy -var-file config/${CONFIG}.tfvars.json ${AUTO_APPROVE} -terraform-kubernetes-init: set-azure-account +terraform-kubernetes-init: cluster-composed-variables set-azure-account rm -rf cluster/terraform_kubernetes/vendor/modules/aks git -c advice.detachedHead=false clone --depth=1 --single-branch --branch ${TERRAFORM_MODULES_TAG} https://github.com/DFE-Digital/terraform-modules.git cluster/terraform_kubernetes/vendor/modules/aks @@ -95,7 +101,7 @@ set-what-if: check-auto-approve: $(if $(AUTO_APPROVE), , $(error can only run with AUTO_APPROVE)) -arm-deployment: set-azure-account +arm-deployment: cluster-composed-variables set-azure-account az deployment sub create --name "resourcedeploy-tsc-$(shell date +%Y%m%d%H%M%S)" \ -l "UK South" --template-uri "https://raw.githubusercontent.com/DFE-Digital/tra-shared-services/${ARM_TEMPLATE_TAG}/azure/resourcedeploy.json" \ --parameters "resourceGroupName=${RESOURCE_GROUP_NAME}" 'tags=${RG_TAGS}' \ @@ -109,32 +115,32 @@ arm-deployment: set-azure-account --parameters "managedIdentityName=${MANAGE_IDENTITY_NAME}" \ ${WHAT_IF} -deploy-azure-resources: check-auto-approve arm-deployment # make dev deploy-azure-resources -validate-azure-resources: set-what-if arm-deployment # make dev validate-azure-resources +deploy-azure-resources: check-auto-approve arm-deployment # make test deploy-azure-resources +validate-azure-resources: set-what-if arm-deployment # make test validate-azure-resources -domains-arm-deployment: set-azure-account +domains-arm-deployment: domains-composed-variables set-azure-account az deployment sub create --name "resourcedeploy-tscdomains-$(shell date +%Y%m%d%H%M%S)" \ -l "UK South" --template-uri "https://raw.githubusercontent.com/DFE-Digital/tra-shared-services/${ARM_TEMPLATE_TAG}/azure/resourcedeploy.json" \ --parameters "resourceGroupName=${RESOURCE_GROUP_NAME}" 'tags=${RG_TAGS}' \ "tfStorageAccountName=${STORAGE_ACCOUNT_NAME}" "tfStorageContainerName=tscdomains-tfstate" \ "keyVaultName=${KEYVAULT_NAME}" ${WHAT_IF} -deploy-domains-azure-resources: check-auto-approve domains-arm-deployment # make dev deploy-domains-azure-resources -validate-domains-azure-resources: set-what-if domains-arm-deployment # make dev validate-domains-azure-resources +deploy-domains-azure-resources: check-auto-approve domains-arm-deployment # make test deploy-domains-azure-resources +validate-domains-azure-resources: set-what-if domains-arm-deployment # make test validate-domains-azure-resources -domains-infra-init: set-azure-account +domains-infra-init: domains-composed-variables set-azure-account rm -rf custom_domains/terraform/infrastructure/vendor/modules/domains - git clone --depth=1 --single-branch --branch ${TERRAFORM_MODULES_TAG} https://github.com/DFE-Digital/terraform-modules.git custom_domains/terraform/infrastructure/vendor/modules/domains + git -c advice.detachedHead=false clone --depth=1 --single-branch --branch ${TERRAFORM_MODULES_TAG} https://github.com/DFE-Digital/terraform-modules.git custom_domains/terraform/infrastructure/vendor/modules/domains terraform -chdir=custom_domains/terraform/infrastructure init -reconfigure -upgrade \ -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} domains-infra-plan: domains-infra-init - terraform -chdir=custom_domains/terraform/infrastructure plan -var-file config/${DOMAINS_ID}.tfvars.json + terraform -chdir=custom_domains/terraform/infrastructure plan -var-file config/${CONFIG}.tfvars.json domains-infra-apply: domains-infra-init - terraform -chdir=custom_domains/terraform/infrastructure apply -var-file config/${DOMAINS_ID}.tfvars.json ${AUTO_APPROVE} + terraform -chdir=custom_domains/terraform/infrastructure apply -var-file config/${CONFIG}.tfvars.json ${AUTO_APPROVE} get-cluster-credentials: set-azure-account ## make get-cluster-credentials [ENVIRONMENT=] az aks get-credentials --overwrite-existing -g ${RESOURCE_GROUP_NAME} -n ${RESOURCE_PREFIX}-tsc-${ENVIRONMENT}${CLONE_STRING}-aks diff --git a/cluster/config/development.sh b/cluster/config/development.sh index 493ee49e..22b13dba 100644 --- a/cluster/config/development.sh +++ b/cluster/config/development.sh @@ -2,8 +2,4 @@ CONFIG=development CONFIG_SHORT=dv AZ_SUBSCRIPTION=s189-teacher-services-cloud-development RESOURCE_PREFIX=s189d01 -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tsc2-${CONFIG_SHORT}-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tsctfstate${CONFIG_SHORT} -MANAGE_IDENTITY_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-id TERRAFORM_MODULES_TAG=main diff --git a/cluster/config/domains.sh b/cluster/config/domains.sh new file mode 100644 index 00000000..1f116139 --- /dev/null +++ b/cluster/config/domains.sh @@ -0,0 +1,5 @@ +AZURE_SUBSCRIPTION=s189-teacher-services-cloud-production +AZURE_RESOURCE_PREFIX=s189p01 +CONFIG_SHORT=tscdomains +DISABLE_KEYVAULTS=true +TERRAFORM_MODULES_TAG=stable diff --git a/cluster/config/platform-test.sh b/cluster/config/platform-test.sh index 1d2f72a0..1f81a96d 100644 --- a/cluster/config/platform-test.sh +++ b/cluster/config/platform-test.sh @@ -3,8 +3,4 @@ CONFIG=platform-test CONFIG_SHORT=pt AZ_SUBSCRIPTION=s189-teacher-services-cloud-test RESOURCE_PREFIX=s189t01 -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tsctfstate${CONFIG_SHORT} -MANAGE_IDENTITY_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-id TERRAFORM_MODULES_TAG=testing diff --git a/cluster/config/production.sh b/cluster/config/production.sh index 155abeec..5b66d5ac 100644 --- a/cluster/config/production.sh +++ b/cluster/config/production.sh @@ -3,8 +3,4 @@ CONFIG=production CONFIG_SHORT=pd AZ_SUBSCRIPTION=s189-teacher-services-cloud-production RESOURCE_PREFIX=s189p01 -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tsctfstate${CONFIG_SHORT} -MANAGE_IDENTITY_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-id TERRAFORM_MODULES_TAG=stable diff --git a/cluster/config/test.sh b/cluster/config/test.sh index abc33daf..18ccd89a 100644 --- a/cluster/config/test.sh +++ b/cluster/config/test.sh @@ -3,8 +3,4 @@ CONFIG=test CONFIG_SHORT=ts AZ_SUBSCRIPTION=s189-teacher-services-cloud-test RESOURCE_PREFIX=s189t01 -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tsctfstate${CONFIG_SHORT} -MANAGE_IDENTITY_NAME=${RESOURCE_PREFIX}-tsc-${CONFIG_SHORT}-id TERRAFORM_MODULES_TAG=testing diff --git a/custom_domains/config/dev-domain.sh b/custom_domains/config/dev-domain.sh deleted file mode 100644 index 9f352aed..00000000 --- a/custom_domains/config/dev-domain.sh +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG=development -CONFIG_SHORT=dv -AZ_SUBSCRIPTION=s189-teacher-services-cloud-development -RESOURCE_PREFIX=s189d01 -ENV_TAG=Dev -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tscdomains-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tscdomains-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tscdomainstf -DOMAINS_ID=tscd -TERRAFORM_MODULES_TAG=testing diff --git a/custom_domains/config/prod-domain.sh b/custom_domains/config/prod-domain.sh deleted file mode 100644 index 65902c11..00000000 --- a/custom_domains/config/prod-domain.sh +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG=production -CONFIG_SHORT=pd -AZ_SUBSCRIPTION=s189-teacher-services-cloud-production -RESOURCE_PREFIX=s189p01 -ENV_TAG=Prod -RESOURCE_GROUP_NAME=${RESOURCE_PREFIX}-tscdomains-rg -KEYVAULT_NAME=${RESOURCE_PREFIX}-tscdomains-kv -STORAGE_ACCOUNT_NAME=${RESOURCE_PREFIX}tscdomainstf -DOMAINS_ID=tscp -TERRAFORM_MODULES_TAG=stable diff --git a/custom_domains/terraform/infrastructure/config/tscd.tfvars.json b/custom_domains/terraform/infrastructure/config/development.tfvars.json similarity index 100% rename from custom_domains/terraform/infrastructure/config/tscd.tfvars.json rename to custom_domains/terraform/infrastructure/config/development.tfvars.json diff --git a/custom_domains/terraform/infrastructure/config/tscp.tfvars.json b/custom_domains/terraform/infrastructure/config/production.tfvars.json similarity index 100% rename from custom_domains/terraform/infrastructure/config/tscp.tfvars.json rename to custom_domains/terraform/infrastructure/config/production.tfvars.json From b14ef0897d67cf4b2fa9a1c31fcfa3d40850f2d1 Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 9 Jan 2025 14:25:06 +0000 Subject: [PATCH 5/5] Update documentation with workflow change --- documentation/platform-set-up.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/documentation/platform-set-up.md b/documentation/platform-set-up.md index c96bf273..c3854e4f 100644 --- a/documentation/platform-set-up.md +++ b/documentation/platform-set-up.md @@ -10,7 +10,7 @@ There are two DNS zones for ingress DNS: ### Zone Build ``` -make {dev/prod}-domain domains-infra-{plan/apply} +make {development/production} domains-infra-{plan/apply} ``` There is also an NS record for delegation from teacherservices.cloud to development.teacherservices.cloud, @@ -100,3 +100,14 @@ When creating a brand new cluster with its own configuration, follow these steps - Run: `make terraform-apply` - Configure a domain pointing at the new ingress IP following [Cluster DNS zone configuration](#cluster-dns-zone-configuration) - Create or update the user AD groups as per the [AD groups documentation](https://educationgovuk.sharepoint.com/sites/teacher-services-infrastructure/SitePages/AKS%20AD%20groups.aspx) + +## Deployment workflow +When a pull request is created, the `Deploy Cluster` workflow runs and validates the terraform code. + +When the pull request is merged, the workflow continues and deploys successively the `platform-test`, `test` and `production` clusters. Then it updates the domains in the `development` and `production` zones. + +The jobs run in separate Github environments. Each environment contains secrets `AZURE_CLIENT_ID` and `AZURE_SUBSCRIPTION_ID` required for [Github OIDC authentication](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-azure), as well as `AZURE_TENANT_ID` stored as repository secret. The variables correspond to Entra ID app registrations that have the `s189-Contributor and Key Vault editor` role. + +[Federated credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#github-actions) are created manually by an app registration owner. Each one authenticates a Github environment in the teacher-services-cloud repository. + +The Github environment variables `TEST_APP_DEPLOYMENT` enables the application deployment smoke test after the deployment. It simulates a typical application deployment using OIDC by deploying *ITT mentor services* to the cluster, testing, and deleting the application. `ITTMS_ENVIRONMENT` points at the chosen environment in [ITTMS](https://github.com/DFE-Digital/itt-mentor-services).