From ba30fb4216c4f3e8cd494727f749c0e7d6517c46 Mon Sep 17 00:00:00 2001 From: Venkata Challa Date: Wed, 20 Dec 2023 16:29:06 +0000 Subject: [PATCH] Added codes to deploy review on test --- .env.test | 2 - .gitignore | 27 +++++ Dockerfile | 2 + Makefile | 102 ++++++++++++++++++ global_config/review.sh | 5 + terraform/application/application.tf | 44 ++++++++ terraform/application/cluster_data.tf | 4 + .../application/config/review.tfvars.json | 6 ++ terraform/application/config/review_Terrafile | 3 + terraform/application/database.tf | 15 +++ terraform/application/output.tf | 3 + terraform/application/secrets.tf | 8 ++ terraform/application/terraform.tf | 37 +++++++ terraform/application/variables.tf | 67 ++++++++++++ 14 files changed, 323 insertions(+), 2 deletions(-) delete mode 100644 .env.test create mode 100644 Makefile create mode 100644 global_config/review.sh create mode 100644 terraform/application/application.tf create mode 100644 terraform/application/cluster_data.tf create mode 100644 terraform/application/config/review.tfvars.json create mode 100644 terraform/application/config/review_Terrafile create mode 100644 terraform/application/database.tf create mode 100644 terraform/application/output.tf create mode 100644 terraform/application/secrets.tf create mode 100644 terraform/application/terraform.tf create mode 100644 terraform/application/variables.tf diff --git a/.env.test b/.env.test deleted file mode 100644 index e7376b79fa..0000000000 --- a/.env.test +++ /dev/null @@ -1,2 +0,0 @@ -PLACEMENTS_HOST=placements.localhost -CLAIMS_HOST=claims.localhost diff --git a/.gitignore b/.gitignore index 6e24451ea1..b120ede186 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,30 @@ tmp/pids/* !tmp/pids/.keep .yarn/* + +# Ignore bundler config +/.bundle + +# bundled gems +/vendor + +# Ignore cache +/.sass-cache +/.cache + +# Ignore .DS_store file +.DS_Store + +# Ignore built documentation +/build + +# Ignore vscode files +.vscode/ + +# Ignore terraform files +bin/terrafile +.terraform +terraform/application/vendor +terraform/domains/environment_domains/vendor +terraform/domains/infrastructure/vendor +terraform.tfstate* diff --git a/Dockerfile b/Dockerfile index 18c72cf1d2..f598645813 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,6 +55,8 @@ RUN rm -rf node_modules log/* tmp/* /tmp && \ # Build runtime image FROM ruby:3.2.2-alpine as production +# Use rails production environment when deployed using docker +ENV RAILS_ENV=production # The application runs from /app WORKDIR /app diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..542cb4fccd --- /dev/null +++ b/Makefile @@ -0,0 +1,102 @@ +TERRAFILE_VERSION=0.8 +ARM_TEMPLATE_TAG=1.1.10 +RG_TAGS={"Product" : "Teacher services cloud"} +REGION=UK South +SERVICE_NAME=itt-mentor-services +SERVICE_SHORT=ittms +DOCKER_REPOSITORY=ghcr.io/dfe-digital/itt-mentor-services + +help: + @grep -E '^[a-zA-Z\._\-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: review +review: test-cluster + $(if ${PR_NUMBER},,$(error Missing PR_NUMBER)) + $(eval ENVIRONMENT=${PR_NUMBER}) + $(eval export TF_VAR_environment=${ENVIRONMENT}) + $(eval include global_config/review.sh) + +composed-variables: + $(eval RESOURCE_GROUP_NAME=${AZURE_RESOURCE_PREFIX}-${SERVICE_SHORT}-${CONFIG_SHORT}-rg) + $(eval KEYVAULT_NAMES='("${AZURE_RESOURCE_PREFIX}-${SERVICE_SHORT}-${CONFIG_SHORT}-app-kv", "${AZURE_RESOURCE_PREFIX}-${SERVICE_SHORT}-${CONFIG_SHORT}-inf-kv")') + $(eval STORAGE_ACCOUNT_NAME=${AZURE_RESOURCE_PREFIX}${SERVICE_SHORT}${CONFIG_SHORT}tfsa) + $(eval LOG_ANALYTICS_WORKSPACE_NAME=${AZURE_RESOURCE_PREFIX}-${SERVICE_SHORT}-${CONFIG_SHORT}-log) + +ci: + $(eval AUTO_APPROVE=-auto-approve) + $(eval SKIP_AZURE_LOGIN=true) + $(eval SKIP_CONFIRM=true) + +bin/terrafile: ## Install terrafile to manage terraform modules + curl -sL https://github.com/coretech/terrafile/releases/download/v${TERRAFILE_VERSION}/terrafile_${TERRAFILE_VERSION}_$$(uname)_x86_64.tar.gz \ + | tar xz -C ./bin terrafile + +set-azure-account: + [ "${SKIP_AZURE_LOGIN}" != "true" ] && az account set -s ${AZURE_SUBSCRIPTION} || true + +terraform-init: composed-variables bin/terrafile set-azure-account + $(if ${DOCKER_IMAGE_TAG}, , $(eval DOCKER_IMAGE_TAG=main)) + + ./bin/terrafile -p terraform/application/vendor/modules -f terraform/application/config/$(CONFIG)_Terrafile + terraform -chdir=terraform/application init -upgrade -reconfigure \ + -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ + -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} \ + -backend-config=key=${ENVIRONMENT}_kubernetes.tfstate + + $(eval export TF_VAR_azure_resource_prefix=${AZURE_RESOURCE_PREFIX}) + $(eval export TF_VAR_config_short=${CONFIG_SHORT}) + $(eval export TF_VAR_service_name=${SERVICE_NAME}) + $(eval export TF_VAR_service_short=${SERVICE_SHORT}) + $(eval export TF_VAR_docker_image=${DOCKER_REPOSITORY}:${DOCKER_IMAGE_TAG}) + +terraform-plan: terraform-init + terraform -chdir=terraform/application plan -var-file "config/${CONFIG}.tfvars.json" + +terraform-apply: terraform-init + terraform -chdir=terraform/application apply -var-file "config/${CONFIG}.tfvars.json" ${AUTO_APPROVE} + +terraform-destroy: terraform-init + terraform -chdir=terraform/application destroy -var-file "config/${CONFIG}.tfvars.json" ${AUTO_APPROVE} + +set-what-if: + $(eval WHAT_IF=--what-if) + +arm-deployment: composed-variables set-azure-account + $(if ${DISABLE_KEYVAULTS},, $(eval KV_ARG=keyVaultNames=${KEYVAULT_NAMES})) + $(if ${ENABLE_KV_DIAGNOSTICS}, $(eval KV_DIAG_ARG=enableDiagnostics=${ENABLE_KV_DIAGNOSTICS} logAnalyticsWorkspaceName=${LOG_ANALYTICS_WORKSPACE_NAME}),) + + az deployment sub create --name "resourcedeploy-tsc-$(shell date +%Y%m%d%H%M%S)" \ + -l "${REGION}" --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=terraform-state" \ + ${KV_ARG} \ + ${KV_DIAG_ARG} \ + "enableKVPurgeProtection=${KV_PURGE_PROTECTION}" \ + ${WHAT_IF} + +deploy-arm-resources: arm-deployment ## Validate ARM resource deployment. Usage: make domains validate-arm-resources + +validate-arm-resources: set-what-if arm-deployment ## Validate ARM resource deployment. Usage: make domains validate-arm-resources + +domains-infra-init: bin/terrafile domains composed-variables set-azure-account + ./bin/terrafile -p terraform/domains/infrastructure/vendor/modules -f terraform/domains/infrastructure/config/zones_Terrafile + + terraform -chdir=terraform/domains/infrastructure init -reconfigure -upgrade \ + -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ + -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} \ + -backend-config=key=domains_infrastructure.tfstate + +test-cluster: + $(eval CLUSTER_RESOURCE_GROUP_NAME=s189t01-tsc-ts-rg) + $(eval CLUSTER_NAME=s189t01-tsc-test-aks) + +production-cluster: + $(eval CLUSTER_RESOURCE_GROUP_NAME=s189p01-tsc-pd-rg) + $(eval CLUSTER_NAME=s189p01-tsc-production-aks) + +get-cluster-credentials: set-azure-account + az aks get-credentials --overwrite-existing -g ${CLUSTER_RESOURCE_GROUP_NAME} -n ${CLUSTER_NAME} + +bin/konduit.sh: + curl -s https://raw.githubusercontent.com/DFE-Digital/teacher-services-cloud/main/scripts/konduit.sh -o bin/konduit.sh \ + && chmod +x bin/konduit.sh diff --git a/global_config/review.sh b/global_config/review.sh new file mode 100644 index 0000000000..6f2c5d5c2e --- /dev/null +++ b/global_config/review.sh @@ -0,0 +1,5 @@ +CONFIG=review +CONFIG_SHORT=rv +AZURE_SUBSCRIPTION=s189-teacher-services-cloud-test +AZURE_RESOURCE_PREFIX=s189t01 +KV_PURGE_PROTECTION=false diff --git a/terraform/application/application.tf b/terraform/application/application.tf new file mode 100644 index 0000000000..b5ab6a4da6 --- /dev/null +++ b/terraform/application/application.tf @@ -0,0 +1,44 @@ +module "application_configuration" { + source = "./vendor/modules/aks//aks/application_configuration" + + namespace = var.namespace + environment = var.environment + azure_resource_prefix = var.azure_resource_prefix + service_short = var.service_short + config_short = var.config_short + secret_key_vault_short = "app" + + # Delete for non rails apps + is_rails_application = true + + config_variables = { + ENVIRONMENT_NAME = var.environment + PGSSLMODE = local.postgres_ssl_mode + SIGN_IN_METHOD = var.sign_in_method + CLAIMS_HOST = local.claims_host + PLACEMENTS_HOST = local.placements_host + } + secret_variables = { + DATABASE_URL = module.postgres.url + } +} + +module "web_application" { + source = "./vendor/modules/aks//aks/application" + + is_web = true + + namespace = var.namespace + environment = var.environment + service_name = var.service_name + web_external_hostnames = [ + local.claims_host, + local.placements_host + ] + + 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.docker_image +} diff --git a/terraform/application/cluster_data.tf b/terraform/application/cluster_data.tf new file mode 100644 index 0000000000..42778646b9 --- /dev/null +++ b/terraform/application/cluster_data.tf @@ -0,0 +1,4 @@ +module "cluster_data" { + source = "./vendor/modules/aks//aks/cluster_data" + name = var.cluster +} diff --git a/terraform/application/config/review.tfvars.json b/terraform/application/config/review.tfvars.json new file mode 100644 index 0000000000..390d4618bb --- /dev/null +++ b/terraform/application/config/review.tfvars.json @@ -0,0 +1,6 @@ +{ + "cluster": "test", + "namespace": "bat-qa", + "deploy_azure_backing_services": false, + "enable_postgres_ssl" : false +} diff --git a/terraform/application/config/review_Terrafile b/terraform/application/config/review_Terrafile new file mode 100644 index 0000000000..65af53b11d --- /dev/null +++ b/terraform/application/config/review_Terrafile @@ -0,0 +1,3 @@ +aks: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "main" diff --git a/terraform/application/database.tf b/terraform/application/database.tf new file mode 100644 index 0000000000..b8da6665df --- /dev/null +++ b/terraform/application/database.tf @@ -0,0 +1,15 @@ +module "postgres" { + source = "./vendor/modules/aks//aks/postgres" + + namespace = var.namespace + environment = var.environment + azure_resource_prefix = var.azure_resource_prefix + service_name = var.service_name + service_short = var.service_short + config_short = var.config_short + cluster_configuration_map = module.cluster_data.configuration_map + use_azure = var.deploy_azure_backing_services + azure_enable_monitoring = var.enable_monitoring + azure_enable_backup_storage = var.enable_postgres_backup_storage + server_version = "14" +} diff --git a/terraform/application/output.tf b/terraform/application/output.tf new file mode 100644 index 0000000000..989dbad146 --- /dev/null +++ b/terraform/application/output.tf @@ -0,0 +1,3 @@ +output "url" { + value = module.web_application.url +} diff --git a/terraform/application/secrets.tf b/terraform/application/secrets.tf new file mode 100644 index 0000000000..f3592a80a6 --- /dev/null +++ b/terraform/application/secrets.tf @@ -0,0 +1,8 @@ +module "infrastructure_secrets" { + source = "./vendor/modules/aks//aks/secrets" + + azure_resource_prefix = var.azure_resource_prefix + service_short = var.service_short + config_short = var.config_short + key_vault_short = "inf" +} diff --git a/terraform/application/terraform.tf b/terraform/application/terraform.tf new file mode 100644 index 0000000000..5aa44b1175 --- /dev/null +++ b/terraform/application/terraform.tf @@ -0,0 +1,37 @@ +terraform { + required_version = "= 1.6.4" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.82.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "2.24.0" + } + # statuscake = { + # source = "StatusCakeDev/statuscake" + # version = "2.1.0" + # } + } + backend "azurerm" { + container_name = "terraform-state" + } +} + +provider "azurerm" { + features {} + + skip_provider_registration = true +} + +provider "kubernetes" { + host = module.cluster_data.kubernetes_host + client_certificate = module.cluster_data.kubernetes_client_certificate + client_key = module.cluster_data.kubernetes_client_key + cluster_ca_certificate = module.cluster_data.kubernetes_cluster_ca_certificate +} + +# provider "statuscake" { +# api_token = module.infrastructure_secrets.map.STATUSCAKE-API-TOKEN +# } diff --git a/terraform/application/variables.tf b/terraform/application/variables.tf new file mode 100644 index 0000000000..58484928fb --- /dev/null +++ b/terraform/application/variables.tf @@ -0,0 +1,67 @@ +variable "cluster" { + description = "AKS cluster where this app is deployed. Either 'test' or 'production'" +} +variable "namespace" { + description = "AKS namespace where this app is deployed" +} +variable "environment" { + description = "Name of the deployed environment in AKS" +} +variable "azure_resource_prefix" { + description = "Standard resource prefix. Usually s189t01 (test) or s189p01 (production)" +} +variable "config_short" { + description = "Short name of the environment configuration, e.g. dv, st, pd..." +} +variable "service_name" { + description = "Full name of the service. Lowercase and hyphen separated" +} +variable "service_short" { + description = "Short name to identify the service. Up to 6 charcters." +} +variable "deploy_azure_backing_services" { + default = true + description = "Deploy real Azure backing services like databases, as opposed to containers inside of AKS" +} +variable "enable_postgres_ssl" { + default = true + description = "Enforce SSL connection from the client side" +} +variable "enable_postgres_backup_storage" { + default = false + description = "Create a storage account to store database dumps" +} +variable "docker_image" { + description = "Docker image full name to identify it in the registry. Includes docker registry, repository and tag e.g.: ghcr.io/dfe-digital/teacher-pay-calculator:673f6309fd0c907014f44d6732496ecd92a2bcd0" +} +variable "external_url" { + default = null + description = "Healthcheck URL for StatusCake monitoring" +} +variable "statuscake_contact_groups" { + default = [] + description = "ID of the contact group in statuscake web UI" +} +variable "enable_monitoring" { + default = false + description = "Enable monitoring and alerting" +} + +variable "sign_in_method" { + default = "persona" + description = "sign in method for the app" +} + +variable "claims_host" { + default = null +} + +variable "placements_host" { + default = null +} + +locals { + postgres_ssl_mode = var.enable_postgres_ssl ? "require" : "disable" + placements_host = var.claims_host == null ? "manage-school-placements-${ var.environment }.test.teacherservices.cloud" : var.claims_host + claims_host = var.placements_host == null ? "track-and-pay-${ var.environment }.test.teacherservices.cloud" : var.placements_host +}