From b04ba80175ed0784c51c26f55531bca1c57d0fde Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:47:26 +0000 Subject: [PATCH 1/7] Route Guacamole traffic through app-gateway --- Makefile | 6 +- core/terraform/appgateway/appgateway.tf | 2 +- core/terraform/main.tf | 1 + .../resource_processor/vmss_porter/locals.tf | 4 + .../vmss_porter/variables.tf | 4 +- core/terraform/variables.tf | 5 + core/version.txt | 2 +- devops/scripts/load_and_validate_env.sh | 4 +- .../core-application-gateway/.dockerignore | 8 + .../core-application-gateway/Dockerfile.tmpl | 9 + .../core-application-gateway/import.sh | 63 +++++ .../core-application-gateway/parameters.json | 44 ++++ .../core-application-gateway/porter.yaml | 98 ++++++++ .../template_schema.json | 43 ++++ .../terraform/.terraform.lock.hcl | 22 ++ .../terraform/appgateway.tf | 221 ++++++++++++++++++ .../terraform/data.tf | 29 +++ .../terraform/imports.tf | 9 + .../terraform/locals.tf | 39 ++++ .../terraform/main.tf | 15 ++ .../terraform/variables.tf | 9 + .../workspace_services/guacamole/porter.yaml | 43 +++- .../guacamole/template_schema.json | 97 +++++++- .../guacamole/terraform/locals.tf | 3 + .../guacamole/terraform/outputs.tf | 14 +- .../guacamole/terraform/variables.tf | 3 + .../guacamole/terraform/web_app.tf | 3 +- .../guacamole-azure-windowsvm/porter.yaml | 23 +- .../template_schema.json | 4 +- .../terraform/.terraform.lock.hcl | 28 +-- .../terraform/data.tf | 5 - .../terraform/main.tf | 2 +- .../terraform/outputs.tf | 2 +- .../terraform/variables.tf | 3 + 34 files changed, 805 insertions(+), 62 deletions(-) create mode 100644 templates/shared_services/core-application-gateway/.dockerignore create mode 100644 templates/shared_services/core-application-gateway/Dockerfile.tmpl create mode 100755 templates/shared_services/core-application-gateway/import.sh create mode 100755 templates/shared_services/core-application-gateway/parameters.json create mode 100644 templates/shared_services/core-application-gateway/porter.yaml create mode 100644 templates/shared_services/core-application-gateway/template_schema.json create mode 100644 templates/shared_services/core-application-gateway/terraform/.terraform.lock.hcl create mode 100644 templates/shared_services/core-application-gateway/terraform/appgateway.tf create mode 100644 templates/shared_services/core-application-gateway/terraform/data.tf create mode 100644 templates/shared_services/core-application-gateway/terraform/imports.tf create mode 100644 templates/shared_services/core-application-gateway/terraform/locals.tf create mode 100644 templates/shared_services/core-application-gateway/terraform/main.tf create mode 100644 templates/shared_services/core-application-gateway/terraform/variables.tf diff --git a/Makefile b/Makefile index f450e2a36f..b8248ae636 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ E2E_TESTS_NUMBER_PROCESSES_DEFAULT=4 # can be overridden in e2e_tests/.env target_title = @echo -e "\n\e[34mยปยปยป ๐Ÿงฉ \e[96m$(1)\e[0m..." all: bootstrap mgmt-deploy images tre-deploy ## ๐Ÿš€ Provision all the application resources from beginning to end -tre-deploy: deploy-core build-and-deploy-ui firewall-install db-migrate show-core-output ## ๐Ÿš€ Provision TRE using existing images +tre-deploy: deploy-core build-and-deploy-ui firewall-install application-gateway-install db-migrate show-core-output ## ๐Ÿš€ Provision TRE using existing images images: build-and-push-api build-and-push-resource-processor build-and-push-airlock-processor ## ๐Ÿ“ฆ Build and push all images build-and-push-api: build-api-image push-api-image @@ -305,6 +305,10 @@ firewall-install: $(MAKE) bundle-build bundle-publish bundle-register deploy-shared-service \ DIR=${MAKEFILE_DIR}/templates/shared_services/firewall/ BUNDLE_TYPE=shared_service +application-gateway-install: + $(MAKE) bundle-build bundle-publish bundle-register deploy-shared-service \ + DIR=${MAKEFILE_DIR}/templates/shared_services/core-application-gateway/ BUNDLE_TYPE=shared_service + static-web-upload: $(call target_title, "Uploading to static website") \ && . ${MAKEFILE_DIR}/devops/scripts/check_dependencies.sh nodocker,env \ diff --git a/core/terraform/appgateway/appgateway.tf b/core/terraform/appgateway/appgateway.tf index c3c573c8ae..adc1abee0b 100644 --- a/core/terraform/appgateway/appgateway.tf +++ b/core/terraform/appgateway/appgateway.tf @@ -188,7 +188,7 @@ resource "azurerm_application_gateway" "agw" { } # We don't want Terraform to revert certificate cycle changes. We assume the certificate will be renewed in keyvault. - lifecycle { ignore_changes = [ssl_certificate, tags] } + lifecycle { ignore_changes = [ssl_certificate, tags, url_path_map, backend_http_settings, backend_address_pool, rewrite_rule_set] } } diff --git a/core/terraform/main.tf b/core/terraform/main.tf index 3727a8ab01..8fec0836a3 100644 --- a/core/terraform/main.tf +++ b/core/terraform/main.tf @@ -159,6 +159,7 @@ module "resource_processor_vmss_porter" { resource_processor_vmss_sku = var.resource_processor_vmss_sku arm_environment = var.arm_environment rp_bundle_values = var.rp_bundle_values + tre_url = var.tre_url depends_on = [ module.network, diff --git a/core/terraform/resource_processor/vmss_porter/locals.tf b/core/terraform/resource_processor/vmss_porter/locals.tf index c64d9d2c7f..72cbf234a6 100644 --- a/core/terraform/resource_processor/vmss_porter/locals.tf +++ b/core/terraform/resource_processor/vmss_porter/locals.tf @@ -9,4 +9,8 @@ locals { "public" = "AzureCloud" "usgovernment" = "AzureUSGovernment" }, var.arm_environment, "AzureCloud") + + rp_bundle_values_all = merge(var.rp_bundle_values, { tre_url = var.tre_url }) + rp_bundle_values_dic = [for key in keys(local.rp_bundle_values_all) : "RP_BUNDLE_${key}=${local.rp_bundle_values_all[key]}"] + rp_bundle_values_formatted = join("\n ", local.rp_bundle_values_dic) } diff --git a/core/terraform/resource_processor/vmss_porter/variables.tf b/core/terraform/resource_processor/vmss_porter/variables.tf index fcf7acab4c..344df78331 100644 --- a/core/terraform/resource_processor/vmss_porter/variables.tf +++ b/core/terraform/resource_processor/vmss_porter/variables.tf @@ -71,6 +71,6 @@ variable "rp_bundle_values" { type = map(string) } -locals { - rp_bundle_values_formatted = join("\n ", [for key in keys(var.rp_bundle_values) : "RP_BUNDLE_${key}=${var.rp_bundle_values[key]}"]) +variable "tre_url" { + type = string } diff --git a/core/terraform/variables.tf b/core/terraform/variables.tf index 5766776051..08c6713787 100644 --- a/core/terraform/variables.tf +++ b/core/terraform/variables.tf @@ -180,3 +180,8 @@ variable "is_cosmos_defined_throughput" { type = bool default = false } + +variable "tre_url" { + type = string + default = "" +} diff --git a/core/version.txt b/core/version.txt index 8d8e3b7702..3e2f46a3a3 100644 --- a/core/version.txt +++ b/core/version.txt @@ -1 +1 @@ -__version__ = "0.8.9" +__version__ = "0.9.0" diff --git a/devops/scripts/load_and_validate_env.sh b/devops/scripts/load_and_validate_env.sh index 3b79c9ef6a..c5b9c4c835 100755 --- a/devops/scripts/load_and_validate_env.sh +++ b/devops/scripts/load_and_validate_env.sh @@ -78,11 +78,13 @@ else # The ARM Environment is required by terraform to indicate the destination cloud. ARM_ENVIRONMENT=$(convert_azure_env_to_arm_env "${AZURE_ENVIRONMENT}") - export ARM_ENVIRONMENT + export ARM_ENVIRONMENT #TODO: isn't used by scripts, right? export TF_VAR_arm_environment="${ARM_ENVIRONMENT}" + #TODO: this can't be set via config which means DNS CNAMEs can't be used. TRE_URL=$(construct_tre_url "${TRE_ID}" "${LOCATION}" "${AZURE_ENVIRONMENT}") export TRE_URL + export TF_VAR_tre_url="${TRE_URL}" fi set +o nounset diff --git a/templates/shared_services/core-application-gateway/.dockerignore b/templates/shared_services/core-application-gateway/.dockerignore new file mode 100644 index 0000000000..5c57b198cd --- /dev/null +++ b/templates/shared_services/core-application-gateway/.dockerignore @@ -0,0 +1,8 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Put files here that you don't want copied into your bundle's invocation image +.gitignore +**/.terraform/* +**/*_backend.tf +Dockerfile.tmpl +terraform/import_state.sh +terraform/remove_state.sh diff --git a/templates/shared_services/core-application-gateway/Dockerfile.tmpl b/templates/shared_services/core-application-gateway/Dockerfile.tmpl new file mode 100644 index 0000000000..3452b48f1d --- /dev/null +++ b/templates/shared_services/core-application-gateway/Dockerfile.tmpl @@ -0,0 +1,9 @@ +# syntax=docker/dockerfile-upstream:1.4.0 +FROM debian:bullseye-slim + +# PORTER_INIT + +# PORTER_MIXINS + +# Use the BUNDLE_DIR build argument to copy files into the bundle +COPY --link . ${BUNDLE_DIR}/ diff --git a/templates/shared_services/core-application-gateway/import.sh b/templates/shared_services/core-application-gateway/import.sh new file mode 100755 index 0000000000..5cc2b20470 --- /dev/null +++ b/templates/shared_services/core-application-gateway/import.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set +o nounset + +while [ "$1" != "" ]; do + case $1 in + --mgmt_resource_group_name) + shift + mgmt_resource_group_name=$1 + ;; + --mgmt_storage_account_name) + shift + mgmt_storage_account_name=$1 + ;; + --container_name) + shift + container_name=$1 + ;; + --key) + shift + key=$1 + ;; + + + --tre_id) + shift + tre_id=$1 + ;; + --azure_subscription_id) + shift + azure_subscription_id=$1 + ;; + *) + echo "Unexpected argument: '$1'" + usage + ;; + esac + + if [[ -z "$2" ]]; then + # if no more args then stop processing + break + fi + + shift # remove the current value for `$1` and use the next +done + +set -o nounset + +core_resource_group_name="rg-${tre_id}" +application_gateway_name="agw-${tre_id}" + +terraform -chdir=terraform init -input=false -backend=true -reconfigure \ + -backend-config="resource_group_name=${mgmt_resource_group_name}" \ + -backend-config="storage_account_name=${mgmt_storage_account_name}" \ + -backend-config="container_name=${container_name}" \ + -backend-config="key=${key}" + +terraform -chdir=terraform import \ + -var "tre_id=${tre_id}" \ + azurerm_application_gateway.agw \ + "/subscriptions/${azure_subscription_id}/resourceGroups/${core_resource_group_name}/providers/Microsoft.Network/applicationGateways/${application_gateway_name}" diff --git a/templates/shared_services/core-application-gateway/parameters.json b/templates/shared_services/core-application-gateway/parameters.json new file mode 100755 index 0000000000..9eef45a557 --- /dev/null +++ b/templates/shared_services/core-application-gateway/parameters.json @@ -0,0 +1,44 @@ +{ + "schemaType": "ParameterSet", + "schemaVersion": "1.0.1", + "namespace": "", + "name": "tre-shared-service-application-gateway", + "parameters": [ + { + "name": "tre_id", + "source": { + "env": "TRE_ID" + } + }, + { + "name": "id", + "source": { + "env": "ID" + } + }, + { + "name": "tfstate_container_name", + "source": { + "env": "TERRAFORM_STATE_CONTAINER_NAME" + } + }, + { + "name": "tfstate_resource_group_name", + "source": { + "env": "MGMT_RESOURCE_GROUP_NAME" + } + }, + { + "name": "tfstate_storage_account_name", + "source": { + "env": "MGMT_STORAGE_ACCOUNT_NAME" + } + }, + { + "name": "arm_environment", + "source": { + "env": "ARM_ENVIRONMENT" + } + } + ] +} diff --git a/templates/shared_services/core-application-gateway/porter.yaml b/templates/shared_services/core-application-gateway/porter.yaml new file mode 100644 index 0000000000..d4d201cac1 --- /dev/null +++ b/templates/shared_services/core-application-gateway/porter.yaml @@ -0,0 +1,98 @@ +--- +schemaVersion: 1.0.0 +name: tre-shared-service-application-gateway +version: 0.1.2 +description: "An Azure Application Gateway shared service" +dockerfile: Dockerfile.tmpl +registry: azuretre + +credentials: + - name: azure_tenant_id + env: ARM_TENANT_ID + - name: azure_subscription_id + env: ARM_SUBSCRIPTION_ID + - name: azure_client_id + env: ARM_CLIENT_ID + - name: azure_client_secret + env: ARM_CLIENT_SECRET + +parameters: + - name: tre_id + type: string + description: "The ID of the parent TRE instance e.g., mytre-dev-3142" + - name: id + type: string + description: "Resource ID" + - name: tfstate_resource_group_name + type: string + description: "Resource group containing the Terraform state storage account" + - name: tfstate_storage_account_name + type: string + description: "The name of the Terraform state storage account" + - name: tfstate_container_name + type: string + default: "tfstate" + description: "The name of the Terraform state storage container" + - name: arm_use_msi + env: ARM_USE_MSI + type: boolean + default: false + - name: backend_collection + type: string + default: "W10=" # b64 for [] + description: "Backends list used to route traffic into specific TRE services." + - name: arm_environment + type: string + +mixins: + - terraform: + clientVersion: 1.4.6 + - exec + +install: + # TODO: delete when we use Terraform 1.5+ + - exec: + command: bash + arguments: + - ./import.sh + flags: + mgmt_resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } + mgmt_storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } + container_name: ${ bundle.parameters.tfstate_container_name } + key: ${ bundle.parameters.tre_id }-${ bundle.name }_${ bundle.parameters.id } + tre_id: ${ bundle.parameters.tre_id } + azure_subscription_id: ${ bundle.credentials.azure_subscription_id } + envs: + ARM_USE_MSI: ${ bundle.parameters.arm_use_msi } + ARM_ENVIRONMENT: ${ bundle.parameters.arm_environment } + + # TODO: uncomment when we use Terraform 1.5+ + # - terraform: + # description: "Install shared service" + # vars: + # tre_id: ${ bundle.parameters.tre_id } + # backend_collection_b64: ${ bundle.parameters.backend_collection } + # backendConfig: + # resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } + # storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } + # container_name: ${ bundle.parameters.tfstate_container_name } + # key: ${ bundle.parameters.tre_id }-${ bundle.name }_${ bundle.parameters.id } + +upgrade: + - terraform: + description: "Upgrade shared service" + vars: + tre_id: ${ bundle.parameters.tre_id } + backend_collection_b64: ${ bundle.parameters.backend_collection } + backendConfig: + resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } + storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } + container_name: ${ bundle.parameters.tfstate_container_name } + key: ${ bundle.parameters.tre_id }-${ bundle.name }_${ bundle.parameters.id } + +uninstall: + - exec: + description: "Tear down shared service" + command: echo + arguments: + - "Dummy uninstall as the underlining Azure resource shouldn't be removed by this action." diff --git a/templates/shared_services/core-application-gateway/template_schema.json b/templates/shared_services/core-application-gateway/template_schema.json new file mode 100644 index 0000000000..586398e1a7 --- /dev/null +++ b/templates/shared_services/core-application-gateway/template_schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://github.com/microsoft/AzureTRE/templates/shared_services/firewall/template_schema.json", + "type": "object", + "title": "Application Gateway Shared Service", + "description": "Provides routing services into the TRE", + "required": [], + "properties": { + "backend_collection": { + "$id": "#properties/backend_collection", + "title": "backend collections", + "type": "array", + "default": [], + "updateable": true, + "items":{ + "title": "items", + "type": "object", + "required": [ + "name", + "fqdn" + ], + "properties": { + "name": { + "title": "name", + "type": "string", + "examples": [ + "my-backend" + ], + "pattern": "^.*$" + }, + "fqdn": { + "title": "fqdn", + "type": "string", + "examples": [ + "my-web-site.azurewebsites.com" + ], + "pattern": "^(https?)?.*$" + } + } + } + } + } +} diff --git a/templates/shared_services/core-application-gateway/terraform/.terraform.lock.hcl b/templates/shared_services/core-application-gateway/terraform/.terraform.lock.hcl new file mode 100644 index 0000000000..6a134423f3 --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "3.74.0" + constraints = "3.74.0" + hashes = [ + "h1:ETVZfmulZQ435+lgFCkZRpfVOLyAxfDOwbPXFg3aLLQ=", + "zh:0424c70152f949da1ec52ba96d20e5fd32fd22d9bd9203ce045d5f6aab3d20fc", + "zh:16dbf581d10f8e7937185bcdcceb4f91d08c919e452fb8da7580071288c8c397", + "zh:3019103bc2c3b4e185f5c65696c349697644c968f5c085af5505fed6d01c4241", + "zh:49bb56ebaed6653fdb913c2b2bb74fc8b5399e7258d1e89084f72c44ea1130dd", + "zh:85547666517f899d88620bd23a000a8f43c7dc93587c350eb1ea17bcb3e645c7", + "zh:8bed8b646ff1822d8764de68b56b71e5dd971a4b77eba80d47f400a530800bea", + "zh:8bfa6c70c004ba05ebce47f74f49ce872c28a68a18bb71b281a9681bcbbdbfa1", + "zh:a2ae9e38fda0695fb8aa810e4f1ce4b104bfda651a87923b307bb1728680d8b6", + "zh:beac1efe32f99072c892095f5ff46e40d6852b66679a03bc3acbe1b90fb1f653", + "zh:d8a6ca20e49ebe7ea5688d91233d571e2c2ccc3e41000c39a7d7031df209ea8e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f937b5fdf49b072c0347408d0a1c5a5d822dae1a23252915930e5a82d1d8ce8b", + ] +} diff --git a/templates/shared_services/core-application-gateway/terraform/appgateway.tf b/templates/shared_services/core-application-gateway/terraform/appgateway.tf new file mode 100644 index 0000000000..b29229ee02 --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/appgateway.tf @@ -0,0 +1,221 @@ +resource "azurerm_application_gateway" "agw" { + name = "agw-${var.tre_id}" + resource_group_name = local.core_resource_group_name + location = data.azurerm_resource_group.core.location + tags = local.tre_core_tags + + sku { + name = "Standard_v2" + tier = "Standard_v2" + capacity = 1 + } + + # User-assign managed identify id required to access certificate in KeyVault + identity { + type = "UserAssigned" + identity_ids = [data.azurerm_user_assigned_identity.agw.id] + } + + # Internal subnet for gateway backend. + gateway_ip_configuration { + name = "gateway-ip-configuration" + subnet_id = data.azurerm_subnet.agw.id + } + + frontend_port { + name = local.insecure_frontend_port_name + port = 80 + } + + frontend_port { + name = local.secure_frontend_port_name + port = 443 + } + + # Public front-end + frontend_ip_configuration { + name = local.frontend_ip_configuration_name + public_ip_address_id = data.azurerm_public_ip.agw.id + } + + # Backend pool with the static website in storage account. + backend_address_pool { + name = local.staticweb_backend_pool_name + fqdns = [data.azurerm_storage_account.staticweb.primary_web_host] + } + + # Backend pool with the API App Service. + backend_address_pool { + name = local.api_backend_pool_name + fqdns = [data.azurerm_linux_web_app.api.default_hostname] + } + + dynamic "backend_address_pool" { + for_each = { for i, v in local.dynamic_backends : i => v } + content { + name = "beap-${backend_address_pool.value.name}" + fqdns = [regex(local.url_parts_pattern, "//${trimprefix(trimprefix(backend_address_pool.value.fqdn, "http://"), "https://")}").fqdn] + } + } + + # Backend settings for api. + # Using custom probe to test specific health endpoint + backend_http_settings { + name = local.api_http_setting_name + cookie_based_affinity = "Disabled" + port = 443 + protocol = "Https" + request_timeout = 60 + pick_host_name_from_backend_address = true + probe_name = local.api_probe_name + } + + backend_http_settings { + name = local.dynamic_backend_settings_name + cookie_based_affinity = "Disabled" + port = 443 + protocol = "Https" + pick_host_name_from_backend_address = true + } + + # Backend settings for static web. + # Using default probe to test root path (/) + backend_http_settings { + name = local.staticweb_http_setting_name + cookie_based_affinity = "Disabled" + port = 443 + protocol = "Https" + request_timeout = 60 + pick_host_name_from_backend_address = true + } + + # Custom health probe for API. + probe { + name = local.api_probe_name + pick_host_name_from_backend_http_settings = true + interval = 15 + protocol = "Https" + # Use the /api/ping endpoint to verify that we can connect to the API + # This still allows the richer information from /api/health to be queried + # in the event of a component being unavailable + # It also avoids incurring the Azure Management API calls to resource processor + # when not needed (which can cause throttling) + path = "/api/ping" + timeout = "30" + unhealthy_threshold = "3" + } + + # Public HTTPS listener + http_listener { + name = local.secure_listener_name + frontend_ip_configuration_name = local.frontend_ip_configuration_name + frontend_port_name = local.secure_frontend_port_name + protocol = "Https" + ssl_certificate_name = local.certificate_name + } + + # Public HTTP listener + http_listener { + name = local.insecure_listener_name + frontend_ip_configuration_name = local.frontend_ip_configuration_name + frontend_port_name = local.insecure_frontend_port_name + protocol = "Http" + } + + request_routing_rule { + name = local.request_routing_rule_name + rule_type = "PathBasedRouting" + http_listener_name = local.secure_listener_name + url_path_map_name = local.app_path_map_name + priority = 100 + } + + # Routing rule to redirect non-secure traffic to HTTPS + request_routing_rule { + name = local.redirect_request_routing_rule_name + rule_type = "PathBasedRouting" + http_listener_name = local.insecure_listener_name + url_path_map_name = local.redirect_path_map_name + priority = 10 + } + + # Default traffic is routed to the static website. Exception is API. + url_path_map { + name = local.app_path_map_name + default_backend_address_pool_name = local.staticweb_backend_pool_name + default_backend_http_settings_name = local.staticweb_http_setting_name + + path_rule { + name = "api" + paths = ["/api/*", "/openapi.json"] + backend_address_pool_name = local.api_backend_pool_name + backend_http_settings_name = local.api_http_setting_name + } + + dynamic "path_rule" { + for_each = { for i, v in local.dynamic_backends : i => v if v.fqdn != "" } + content { + name = path_rule.value.name + paths = ["/${path_rule.value.name}*"] + backend_address_pool_name = "beap-${path_rule.value.name}" + backend_http_settings_name = local.dynamic_backend_settings_name + rewrite_rule_set_name = local.dynamic_rewrite_set + } + } + } + + # Redirect any HTTP traffic to HTTPS unless its the ACME challenge path used for LetsEncrypt validation. + url_path_map { + name = local.redirect_path_map_name + default_redirect_configuration_name = local.redirect_configuration_name + + path_rule { + name = "acme" + paths = ["/.well-known/acme-challenge/*"] + backend_address_pool_name = local.staticweb_backend_pool_name + backend_http_settings_name = local.staticweb_http_setting_name + } + } + + # Redirect to HTTPS + redirect_configuration { + name = local.redirect_configuration_name + redirect_type = "Permanent" + target_listener_name = local.secure_listener_name + include_path = true + include_query_string = true + } + + dynamic "rewrite_rule_set" { + for_each = length(local.dynamic_backends) == 0 ? [0] : [1] + content { + name = local.dynamic_rewrite_set + rewrite_rule { + name = "X-Forwarded-Uri" + rule_sequence = 100 + request_header_configuration { + header_name = "X-Forwarded-Uri" + header_value = "{var_request_uri}" + } + } + rewrite_rule { + name = "URL-remove-first-part" + rule_sequence = 200 + condition { + pattern = "^\\/(.+?)\\/(.*)" + variable = "var_uri_path" + ignore_case = true + } + url { + components = "path_only" + path = "{var_uri_path_2}" + reroute = false + } + } + } + } + + # We don't want Terraform to revert certificate cycle changes. We assume the certificate will be renewed in keyvault. + lifecycle { ignore_changes = [ssl_certificate, tags] } + +} diff --git a/templates/shared_services/core-application-gateway/terraform/data.tf b/templates/shared_services/core-application-gateway/terraform/data.tf new file mode 100644 index 0000000000..e476d98f39 --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/data.tf @@ -0,0 +1,29 @@ +data "azurerm_resource_group" "core" { + name = local.core_resource_group_name +} + +data "azurerm_public_ip" "agw" { + name = "pip-agw-${var.tre_id}" + resource_group_name = local.core_resource_group_name +} + +data "azurerm_user_assigned_identity" "agw" { + name = "id-agw-${var.tre_id}" + resource_group_name = local.core_resource_group_name +} + +data "azurerm_storage_account" "staticweb" { + name = local.staticweb_storage_name + resource_group_name = local.core_resource_group_name +} + +data "azurerm_linux_web_app" "api" { + name = "api-${var.tre_id}" + resource_group_name = local.core_resource_group_name +} + +data "azurerm_subnet" "agw" { + name = "AppGwSubnet" + virtual_network_name = "vnet-${var.tre_id}" + resource_group_name = local.core_resource_group_name +} diff --git a/templates/shared_services/core-application-gateway/terraform/imports.tf b/templates/shared_services/core-application-gateway/terraform/imports.tf new file mode 100644 index 0000000000..c3fb349dec --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/imports.tf @@ -0,0 +1,9 @@ +# TODO: uncomment when we use Terraform 1.5+ + +# data "azurerm_subscription" "current" { +# } + +# import { +# to = azurerm_application_gateway.agw +# id = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${local.core_resource_group_name}/providers/Microsoft.Network/applicationGateways/agw-${var.tre_id}" +# } diff --git a/templates/shared_services/core-application-gateway/terraform/locals.tf b/templates/shared_services/core-application-gateway/terraform/locals.tf new file mode 100644 index 0000000000..aaab9f9cf5 --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/locals.tf @@ -0,0 +1,39 @@ +locals { + staticweb_storage_name = lower(replace("stweb${var.tre_id}", "-", "")) + + staticweb_backend_pool_name = "beap-staticweb" + api_backend_pool_name = "beap-api" + app_path_map_name = "upm-application" + redirect_path_map_name = "upm-redirect" + + insecure_frontend_port_name = "feport-insecure" + secure_frontend_port_name = "feport-secure" + + frontend_ip_configuration_name = "feip-public" + + api_http_setting_name = "be-htst-api" + staticweb_http_setting_name = "be-htst-staticweb" + + api_probe_name = "hp-api" + + insecure_listener_name = "httplstn-insecure" + secure_listener_name = "httplstn-secure" + + redirect_request_routing_rule_name = "rqrt-redirect" + request_routing_rule_name = "rqrt-application" + redirect_configuration_name = "rdrcfg-tosecure" + + certificate_name = "cert-primary" + tre_core_tags = { + tre_id = var.tre_id + tre_core_service_id = var.tre_id + } + + core_resource_group_name = "rg-${var.tre_id}" + + dynamic_backend_settings_name = "bes-generic-443-with-host" + dynamic_rewrite_set = "rs-non-core" + dynamic_backends = jsondecode(base64decode(var.backend_collection_b64)) + + url_parts_pattern = "(?:(?P[^:/?#]+):)?(?://(?P[^/?#:]*))?(?::(?P[0-9]+))?(?P[^?#]*)(?:\\?(?P[^#]*))?(?:#(?P.*))?" +} diff --git a/templates/shared_services/core-application-gateway/terraform/main.tf b/templates/shared_services/core-application-gateway/terraform/main.tf new file mode 100644 index 0000000000..979d79adec --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/main.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "= 3.74" + } + } + + backend "azurerm" {} +} + + +provider "azurerm" { + features {} +} diff --git a/templates/shared_services/core-application-gateway/terraform/variables.tf b/templates/shared_services/core-application-gateway/terraform/variables.tf new file mode 100644 index 0000000000..eda3a4e48a --- /dev/null +++ b/templates/shared_services/core-application-gateway/terraform/variables.tf @@ -0,0 +1,9 @@ +variable "tre_id" { + type = string + description = "Unique TRE ID" +} + +variable "backend_collection_b64" { + type = string + default = "W10=" #b64 for [] +} diff --git a/templates/workspace_services/guacamole/porter.yaml b/templates/workspace_services/guacamole/porter.yaml index f58bafd202..2c3ca82dc8 100644 --- a/templates/workspace_services/guacamole/porter.yaml +++ b/templates/workspace_services/guacamole/porter.yaml @@ -1,7 +1,8 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole -version: 0.10.5 +version: 0.11.0 + description: "An Azure TRE service for Guacamole" dockerfile: Dockerfile.tmpl registry: azuretre @@ -83,7 +84,6 @@ parameters: - name: aad_authority_url type: string default: "https://login.microsoftonline.com" - # the following are added automatically by the resource processor - name: id type: string description: "An Id for this installation" @@ -105,14 +105,26 @@ parameters: default: false - name: arm_environment type: string + - name: tre_url + type: string outputs: - - name: authentication_callback_uri - type: string - applyTo: - - install - - upgrade - - name: web_apps_addresses + # - name: authentication_callback_uri + # type: string + # applyTo: + # - install + # - upgrade + # - name: connection_uri + # type: string + # applyTo: + # - install + # - upgrade + # - name: web_apps_addresses + # type: string + # applyTo: + # - install + # - upgrade + - name: internals type: string applyTo: - install @@ -148,15 +160,18 @@ install: tre_resource_id: ${ bundle.parameters.id } aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } container_name: ${ bundle.parameters.tfstate_container_name } key: tre-service-guacamole-${ bundle.parameters.id } outputs: - - name: authentication_callback_uri - - name: web_apps_addresses + # - name: authentication_callback_uri + # - name: web_apps_addresses - name: admin_connection_uri + # - name: connection_uri + - name: internals upgrade: - terraform: @@ -179,15 +194,18 @@ upgrade: tre_resource_id: ${ bundle.parameters.id } aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } container_name: ${ bundle.parameters.tfstate_container_name } key: tre-service-guacamole-${ bundle.parameters.id } outputs: - - name: authentication_callback_uri - - name: web_apps_addresses + # - name: authentication_callback_uri + # - name: web_apps_addresses - name: admin_connection_uri + # - name: connection_uri + - name: internals uninstall: - terraform: @@ -210,6 +228,7 @@ uninstall: tre_resource_id: ${ bundle.parameters.id } aad_authority_url: ${ bundle.parameters.aad_authority_url } arm_environment: ${ bundle.parameters.arm_environment } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } diff --git a/templates/workspace_services/guacamole/template_schema.json b/templates/workspace_services/guacamole/template_schema.json index e0f052bd08..71a94bf9cb 100644 --- a/templates/workspace_services/guacamole/template_schema.json +++ b/templates/workspace_services/guacamole/template_schema.json @@ -77,6 +77,25 @@ { "stepId": "main" }, + { + "stepId": "f8259f78-8659-4393-b602-ce2dec677a41", + "stepTitle": "Update AppGW", + "resourceTemplateName": "tre-shared-service-application-gateway", + "resourceType": "shared-service", + "resourceAction": "upgrade", + "properties": [ + { + "name": "backend_collection", + "type": "array", + "arraySubstitutionAction": "replace", + "arrayMatchField": "name", + "value": { + "name": "{{ resource.id }}", + "fqdn": "{{ resource.properties.internals.routing_fqdn }}" + } + } + ] + }, { "stepId": "12ba0dad-ea6c-4d0d-9255-d316212f5ffa", "stepTitle": "Add Guacamole URI as AAD redirect URI", @@ -90,7 +109,7 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "value": "{{ resource.properties.authentication_callback_uri }}" + "value": "{{ resource.properties.internals.authentication_callback_uri }}" } } ] @@ -114,7 +133,7 @@ { "name": "AzureAD", "description": "AAD access for authNZ", - "source_addresses": "{{ resource.properties.web_apps_addresses }}", + "source_addresses": "{{ resource.properties.internals.web_apps_addresses }}", "destination_addresses": [ "AzureActiveDirectory" ], @@ -135,6 +154,25 @@ { "stepId": "main" }, + { + "stepId": "a9e993ac-0128-4a9d-b22f-e49bdf153ac4", + "stepTitle": "Update AppGW", + "resourceTemplateName": "tre-shared-service-application-gateway", + "resourceType": "shared-service", + "resourceAction": "upgrade", + "properties": [ + { + "name": "backend_collection", + "type": "array", + "arraySubstitutionAction": "replace", + "arrayMatchField": "name", + "value": { + "name": "{{ resource.id }}", + "fqdn": "{{ resource.properties.internals.routing_fqdn }}" + } + } + ] + }, { "stepId": "741c7ff2-eff5-47b2-bf62-2b410d65c96b", "stepTitle": "Update Guacamole URI in AAD", @@ -148,7 +186,42 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "value": "{{ resource.properties.authentication_callback_uri }}" + "value": "{{ resource.properties.internals.authentication_callback_uri }}" + } + } + ] + }, + { + "stepId": "d16688d7-3801-487d-a8eb-04a91b0a0629", + "stepTitle": "Update network firewall rules for guacamole", + "resourceTemplateName": "tre-shared-service-firewall", + "resourceType": "shared-service", + "resourceAction": "upgrade", + "properties": [ + { + "name": "network_rule_collections", + "type": "array", + "arraySubstitutionAction": "replace", + "arrayMatchField": "name", + "value": { + "name": "nrc_svc_{{ resource.id }}_guacamole", + "action": "Allow", + "rules": [ + { + "name": "AzureAD", + "description": "AAD access for authNZ", + "source_addresses": "{{ resource.properties.internals.web_apps_addresses }}", + "destination_addresses": [ + "AzureActiveDirectory" + ], + "destination_ports": [ + "*" + ], + "protocols": [ + "TCP" + ] + } + ] } } ] @@ -190,6 +263,24 @@ } ] }, + { + "stepId": "62d9f3b7-bc49-456f-b909-23011ad6d448", + "stepTitle": "Update AppGW", + "resourceTemplateName": "tre-shared-service-application-gateway", + "resourceType": "shared-service", + "resourceAction": "upgrade", + "properties": [ + { + "name": "backend_collection", + "type": "array", + "arraySubstitutionAction": "remove", + "arrayMatchField": "name", + "value": { + "name": "{{ resource.id }}" + } + } + ] + }, { "stepId": "main" } diff --git a/templates/workspace_services/guacamole/terraform/locals.tf b/templates/workspace_services/guacamole/terraform/locals.tf index 59b77e8a00..ef0eb87b73 100644 --- a/templates/workspace_services/guacamole/terraform/locals.tf +++ b/templates/workspace_services/guacamole/terraform/locals.tf @@ -23,4 +23,7 @@ locals { "AppServiceHTTPLogs", "AppServiceConsoleLogs", "AppServiceAppLogs", "AppServiceFileAuditLogs", "AppServiceAuditLogs", "AppServiceIPSecAuditLogs", "AppServicePlatformLogs", "AppServiceAntivirusScanAuditLogs" ] + + webapp_access_prefix = var.is_exposed_externally ? "${var.tre_url}/${var.tre_resource_id}" : "https://${local.webapp_name}.${local.webapp_suffix}" + webapp_auth_callback_url = "${local.webapp_access_prefix}/oauth2/callback" } diff --git a/templates/workspace_services/guacamole/terraform/outputs.tf b/templates/workspace_services/guacamole/terraform/outputs.tf index 5c85c9551f..42170caf95 100644 --- a/templates/workspace_services/guacamole/terraform/outputs.tf +++ b/templates/workspace_services/guacamole/terraform/outputs.tf @@ -1,11 +1,11 @@ -output "authentication_callback_uri" { - value = "https://${azurerm_linux_web_app.guacamole.default_hostname}/oauth2/callback" -} - -output "web_apps_addresses" { - value = jsonencode(data.azurerm_subnet.web_apps.address_prefixes) +output "internals" { + value = jsonencode({ + authentication_callback_uri = local.webapp_auth_callback_url + routing_fqdn = var.is_exposed_externally ? azurerm_linux_web_app.guacamole.default_hostname : "" + web_apps_addresses = data.azurerm_subnet.web_apps.address_prefixes + }) } output "admin_connection_uri" { - value = "https://${azurerm_linux_web_app.guacamole.default_hostname}/guacamole" + value = "${local.webapp_access_prefix}/guacamole/" } diff --git a/templates/workspace_services/guacamole/terraform/variables.tf b/templates/workspace_services/guacamole/terraform/variables.tf index 26fcbb2f05..a25a399d0d 100644 --- a/templates/workspace_services/guacamole/terraform/variables.tf +++ b/templates/workspace_services/guacamole/terraform/variables.tf @@ -66,3 +66,6 @@ variable "arm_environment" { type = string description = "The ARM cloud environment" } +variable "tre_url" { + type = string +} diff --git a/templates/workspace_services/guacamole/terraform/web_app.tf b/templates/workspace_services/guacamole/terraform/web_app.tf index 53d998cb05..5ca8a6bafa 100644 --- a/templates/workspace_services/guacamole/terraform/web_app.tf +++ b/templates/workspace_services/guacamole/terraform/web_app.tf @@ -63,7 +63,7 @@ resource "azurerm_linux_web_app" "guacamole" { OAUTH2_PROXY_CLIENT_ID = "@Microsoft.KeyVault(SecretUri=${data.azurerm_key_vault_secret.workspace_client_id.id})" OAUTH2_PROXY_CLIENT_SECRET = "@Microsoft.KeyVault(SecretUri=${data.azurerm_key_vault_secret.workspace_client_secret.id})" - OAUTH2_PROXY_REDIRECT_URI = "https://${local.webapp_name}.${local.webapp_suffix}/oauth2/callback" + OAUTH2_PROXY_REDIRECT_URI = local.webapp_auth_callback_url OAUTH2_PROXY_EMAIL_DOMAIN = "\"*\"" # oauth proxy will allow all email domains only when the value is "*" OAUTH2_PROXY_OIDC_ISSUER_URL = local.issuer OAUTH2_PROXY_JWKS_ENDPOINT = local.jwks_endpoint @@ -121,7 +121,6 @@ resource "azurerm_role_assignment" "guac_acr_pull" { resource "azurerm_private_endpoint" "guacamole" { # disabling this makes the webapp available on the public internet - count = var.is_exposed_externally == false ? 1 : 0 name = "pe-${local.webapp_name}" location = data.azurerm_resource_group.ws.location resource_group_name = data.azurerm_resource_group.ws.name diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml index 3b3354ef84..02d14d1869 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm -version: 0.7.9 +version: 0.8.2 description: "An Azure TRE User Resource Template for Guacamole (Windows 10)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -14,18 +14,11 @@ custom: "8 CPU | 32GB RAM": Standard_D8s_v5 "16 CPU | 64GB RAM": Standard_D16s_v5 image_options: - "Windows 10": - source_image_reference: - publisher: MicrosoftWindowsDesktop - offer: Windows-10 - sku: win10-21h2-pro-g2 - version: latest - conda_config: false "Windows 11": source_image_reference: publisher: microsoftwindowsdesktop offer: windows-11 - sku: win11-21h2-pro + sku: win11-22h2-pro version: latest conda_config: false "Server 2019 Data Science VM": @@ -35,6 +28,13 @@ custom: sku: winserver-2019 version: latest conda_config: true + "Server 2022 Data Science VM": + source_image_reference: + publisher: microsoft-dsvm + offer: dsvm-win-2022 + sku: winserver-2022 + version: latest + conda_config: true # For information on using custom images, see README.me in the guacamole/user-resources folder # "Custom Image From Gallery": # source_image_name: your-image @@ -100,6 +100,8 @@ parameters: default: "vm-shared-storage" - name: arm_environment type: string + - name: tre_url + type: string outputs: - name: ip @@ -145,6 +147,7 @@ install: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } @@ -169,6 +172,7 @@ upgrade: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } @@ -202,6 +206,7 @@ uninstall: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/template_schema.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/template_schema.json index 74518f33ee..08a74c2d3f 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/template_schema.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/template_schema.json @@ -16,9 +16,9 @@ "title": "Windows image", "description": "Select Windows image to use for VM", "enum": [ - "Windows 10", "Windows 11", - "Server 2019 Data Science VM" + "Server 2019 Data Science VM", + "Server 2022 Data Science VM" ] }, "vm_size": { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/.terraform.lock.hcl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/.terraform.lock.hcl index 1306331e37..36ca7b692b 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/.terraform.lock.hcl @@ -2,21 +2,21 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azurerm" { - version = "3.57.0" - constraints = "3.57.0" + version = "3.73.0" + constraints = "3.73.0" hashes = [ - "h1:SOBKU/ioGnpuQpAx6dgaD0EzfAM2W+uS9e6p59viSxs=", - "zh:028202b0ae01f1262dac076b383cb68b5dd624977669b6db833418c215eb8401", - "zh:26fcf9e9b73cb3bbf87a048361a89050d2e52bdc91190a305e624a62be26a3f4", - "zh:2f381103953e4513068eee62089a0ec8c60a18ecef2235138b6c29a45920d6a2", - "zh:376f016f4b449b2cf38f75e27e7a9157fdcfc925f28198124a30e316abb54f3d", - "zh:7d491bab94d5aba91cd9c307dbd4b655dcdc0a6212541e7800b9a902be98befe", - "zh:85fa7d8339efd15494f947cda02e9ed127eafa32652e568f54261b2e97d2b3ee", - "zh:950e079e55a7e321adbd2f6a0639a4b3b0fac47d2e4bb3a12791e0817b694238", - "zh:975260e09379c5c97cad3171327db2f0b4914909861d4c24ab784b0ecd79c54a", - "zh:a26bb67ab2d2f20e5fee4d41110584af17357f4b4266d80f9debfad61fa0a4fd", - "zh:da0e5d1ec301c69b6fae684e55059fc5e1b91699ed3696229f599d558401556b", - "zh:ea11e62ce53caec240cb3a1da25d248805387fa246314001ed3e07e9105f6e12", + "h1:+Z5ZcAQO4e6aWh1N7zX4JqyV/xnDkTRYoCa8pEtNR20=", + "zh:068dfe743c9486d09eeaf97eb7817870b932ecb8132b92b8e0d96eadcf51b349", + "zh:2a16b0d50feb80919880d32cc12d636c37918bbc9133d7b3ff0d610bac1bee86", + "zh:2a77e0deabd3d0f83974125cedca7871add825bf4470688f117a35b6964916cf", + "zh:3ade6f3b9483746f168e7daf5223fd65d5d26313616bca37d9117d5b4fba2b66", + "zh:44554a1fc5f69a1069bbac3fbe1122794943692f81fc2aabda435740f5e10a67", + "zh:69d41ad1073f274548bca763a1ed14813388e5b9b702c15fdc78f2b22b082a09", + "zh:8cf5ce91432fc5ed1b9906bca14ab6f0d3b18e78a9f25e00b1de632ae7669645", + "zh:b70c294e7d55c3404c40ae18e54113e625ee975e80e3f7d558f3fedde89b038e", + "zh:cadab8bc17685a239f45438c555fba156baa709803da55f59cce8c7f1cb70fc1", + "zh:cb74e02e1495df938d464e233a41aa5ffab9f0fd79079016d0a630955ce92b6d", + "zh:cd7a68c03005116fe40542d312d0236ab5bfdd20a2bb6bdf6398d64945c25ef8", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf index b8f4239143..bca869e202 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/data.tf @@ -22,11 +22,6 @@ data "azurerm_key_vault" "ws" { resource_group_name = data.azurerm_resource_group.ws.name } -data "azurerm_linux_web_app" "guacamole" { - name = "guacamole-${var.tre_id}-ws-${local.short_workspace_id}-svc-${local.short_parent_id}" - resource_group_name = data.azurerm_resource_group.ws.name -} - data "azurerm_public_ip" "app_gateway_ip" { name = "pip-agw-${var.tre_id}" resource_group_name = data.azurerm_resource_group.core.name diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/main.tf index 54e5baef02..65465c67d1 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/main.tf @@ -3,7 +3,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "=3.57.0" + version = "=3.73.0" } random = { source = "hashicorp/random" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/outputs.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/outputs.tf index 25737aa472..08d9e66d03 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/outputs.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/outputs.tf @@ -11,7 +11,7 @@ output "azure_resource_id" { } output "connection_uri" { - value = "https://${data.azurerm_linux_web_app.guacamole.default_hostname}/?/client/${textencodebase64("${azurerm_windows_virtual_machine.windowsvm.name}\u0000c\u0000azuretre", "UTF-8")}" + value = "${var.tre_url}/${var.parent_service_id}/?/client/${textencodebase64("${azurerm_windows_virtual_machine.windowsvm.name}\u0000c\u0000azuretre", "UTF-8")}" } output "vm_username" { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf index 4908ae52a2..8742e44891 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf @@ -26,3 +26,6 @@ variable "image_gallery_id" { type = string default = "" } +variable "tre_url" { + type = string +} From 99f43452094ca959d8ab8ac15d94837ffa59403c Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 4 Oct 2023 07:30:36 +0000 Subject: [PATCH 2/7] cicd support for custom TRE_URL --- .../devcontainer_run_command/action.yml | 14 +++++++--- .github/workflows/deploy_tre.yml | 1 + .github/workflows/deploy_tre_branch.yml | 1 + .github/workflows/deploy_tre_reusable.yml | 27 +++++++++++++++++++ devops/scripts/load_and_validate_env.sh | 7 ++--- docs/tre-admins/environment-variables.md | 1 + .../cicd-pre-deployment-steps.md | 1 + .../setup-instructions/workflows.md | 1 + 8 files changed, 47 insertions(+), 6 deletions(-) diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index f403c60083..7c3c0ede65 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -121,6 +121,10 @@ inputs: description: "JSON string containing key/value pairs to injet into the Resource Processor as ENV vars" required: false default: "" + TRE_URL: + description: "The URL of the TRE as registered in DNS, usually via a CNAME" + required: false + default: "" runs: using: composite @@ -147,9 +151,13 @@ runs: - name: Construct TRE_URL shell: bash run: | - source devops/scripts/construct_tre_url.sh - tre_url=$(construct_tre_url "${{ inputs.TRE_ID }}" "${{ inputs.LOCATION }}" "${{ env.AZURE_ENVIRONMENT }}") - echo "TRE_URL=$tre_url" >> $GITHUB_ENV + if [ "${{ secrets.TRE_URL}}" == '' ]; then + source devops/scripts/construct_tre_url.sh + tre_url=$(construct_tre_url "${{ inputs.TRE_ID }}" "${{ inputs.LOCATION }}" "${{ env.AZURE_ENVIRONMENT }}") + echo "TRE_URL=$tre_url" >> $GITHUB_ENV + else + echo "TRE_URL=${{ secrets.TRE_URL }}" >> $GITHUB_ENV + fi - name: Construct ARM_ENVIRONMENT shell: bash diff --git a/.github/workflows/deploy_tre.yml b/.github/workflows/deploy_tre.yml index 7c12cecd98..661ecdc013 100644 --- a/.github/workflows/deploy_tre.yml +++ b/.github/workflows/deploy_tre.yml @@ -53,3 +53,4 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TRE_ID: ${{ secrets.TRE_ID }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} + TRE_URL: ${{ secrets.TRE_URL }} diff --git a/.github/workflows/deploy_tre_branch.yml b/.github/workflows/deploy_tre_branch.yml index a7d171b5c2..ef455f27e0 100644 --- a/.github/workflows/deploy_tre_branch.yml +++ b/.github/workflows/deploy_tre_branch.yml @@ -84,3 +84,4 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TRE_ID: ${{ format('tre{0}', needs.prepare-not-main.outputs.refid) }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} + TRE_URL: ${{ secrets.TRE_URL }} diff --git a/.github/workflows/deploy_tre_reusable.yml b/.github/workflows/deploy_tre_reusable.yml index dc38f22bff..a31cb2e4c8 100644 --- a/.github/workflows/deploy_tre_reusable.yml +++ b/.github/workflows/deploy_tre_reusable.yml @@ -90,6 +90,9 @@ on: # yamllint disable-line rule:truthy AZURE_CREDENTIALS: description: "" required: true + TRE_URL: + description: "" + required: true # This will prevent multiple runs of this entire workflow. # We should NOT cancel in progress runs as that can destabilize the environment. @@ -353,6 +356,7 @@ jobs: CORE_APP_SERVICE_PLAN_SKU: ${{ vars.CORE_APP_SERVICE_PLAN_SKU }} RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE: ${{ vars.RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE }} RP_BUNDLE_VALUES: ${{ vars.RP_BUNDLE_VALUES }} + TRE_URL: "${{ secrets.TRE_URL }}" - name: API Healthcheck uses: ./.github/actions/devcontainer_run_command @@ -364,6 +368,7 @@ jobs: AZURE_ENVIRONMENT: ${{ vars.AZURE_ENVIRONMENT }} TRE_ID: ${{ secrets.TRE_ID }} LOCATION: ${{ vars.LOCATION }} + TRE_URL: "${{ secrets.TRE_URL }}" publish_bundles: name: Publish Bundles @@ -666,6 +671,24 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TRE_ID: ${{ secrets.TRE_ID }} LOCATION: ${{ vars.LOCATION }} + TRE_URL: "${{ secrets.TRE_URL }}" + + - name: Deploy application gateway + uses: ./.github/actions/devcontainer_run_command + with: + COMMAND: "make deploy-shared-service DIR=./templates/shared_services/core-application-gateway/ BUNDLE_TYPE=shared_service" + DEVCONTAINER_TAG: ${{ inputs.DEVCONTAINER_TAG }} + CI_CACHE_ACR_NAME: ${{ secrets.CI_CACHE_ACR_NAME}} + AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} + AZURE_ENVIRONMENT: ${{ vars.AZURE_ENVIRONMENT }} + API_CLIENT_ID: "${{ secrets.API_CLIENT_ID }}" + AAD_TENANT_ID: "${{ secrets.AAD_TENANT_ID }}" + TEST_APP_ID: "${{ secrets.TEST_APP_ID }}" + TEST_ACCOUNT_CLIENT_ID: "${{ secrets.TEST_ACCOUNT_CLIENT_ID }}" + TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" + TRE_ID: ${{ secrets.TRE_ID }} + LOCATION: ${{ vars.LOCATION }} + TRE_URL: "${{ secrets.TRE_URL }}" - name: State Store Migrations uses: ./.github/actions/devcontainer_run_command @@ -685,6 +708,7 @@ jobs: TERRAFORM_STATE_CONTAINER_NAME: ${{ vars.TERRAFORM_STATE_CONTAINER_NAME }} MGMT_RESOURCE_GROUP_NAME: ${{ secrets.MGMT_RESOURCE_GROUP_NAME }} MGMT_STORAGE_ACCOUNT_NAME: ${{ secrets.MGMT_STORAGE_ACCOUNT_NAME }} + TRE_URL: "${{ secrets.TRE_URL }}" deploy_ui: name: Deploy UI @@ -715,6 +739,7 @@ jobs: MGMT_RESOURCE_GROUP_NAME: ${{ secrets.MGMT_RESOURCE_GROUP_NAME }} MGMT_STORAGE_ACCOUNT_NAME: ${{ secrets.MGMT_STORAGE_ACCOUNT_NAME }} SWAGGER_UI_CLIENT_ID: "${{ secrets.SWAGGER_UI_CLIENT_ID }}" + TRE_URL: "${{ secrets.TRE_URL }}" e2e_tests_smoke: name: "Run E2E Tests (Smoke)" @@ -750,6 +775,7 @@ jobs: TRE_ID: ${{ secrets.TRE_ID }} IS_API_SECURED: false WORKSPACE_APP_SERVICE_PLAN_SKU: ${{ vars.WORKSPACE_APP_SERVICE_PLAN_SKU }} + TRE_URL: "${{ secrets.TRE_URL }}" - name: Upload Test Results if: always() @@ -794,6 +820,7 @@ jobs: IS_API_SECURED: false WORKSPACE_APP_SERVICE_PLAN_SKU: ${{ vars.WORKSPACE_APP_SERVICE_PLAN_SKU }} E2E_TESTS_NUMBER_PROCESSES: ${{ inputs.E2E_TESTS_NUMBER_PROCESSES }} + TRE_URL: "${{ secrets.TRE_URL }}" - name: Upload Test Results if: always() diff --git a/devops/scripts/load_and_validate_env.sh b/devops/scripts/load_and_validate_env.sh index c5b9c4c835..68d09cf1b6 100755 --- a/devops/scripts/load_and_validate_env.sh +++ b/devops/scripts/load_and_validate_env.sh @@ -81,9 +81,10 @@ else export ARM_ENVIRONMENT #TODO: isn't used by scripts, right? export TF_VAR_arm_environment="${ARM_ENVIRONMENT}" - #TODO: this can't be set via config which means DNS CNAMEs can't be used. - TRE_URL=$(construct_tre_url "${TRE_ID}" "${LOCATION}" "${AZURE_ENVIRONMENT}") - export TRE_URL + if [ -z "${TRE_URL:-}" ]; then + TRE_URL=$(construct_tre_url "${TRE_ID}" "${LOCATION}" "${AZURE_ENVIRONMENT}") + export TRE_URL + fi export TF_VAR_tre_url="${TRE_URL}" fi diff --git a/docs/tre-admins/environment-variables.md b/docs/tre-admins/environment-variables.md index a998198d81..d43cebaac5 100644 --- a/docs/tre-admins/environment-variables.md +++ b/docs/tre-admins/environment-variables.md @@ -38,6 +38,7 @@ | `CORE_APP_SERVICE_PLAN_SKU` | The SKU of AppService plans created for the core infrastructure. | | `WORKSPACE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan used in E2E tests unless otherwise specified. Default value is `P1v2`. | | `RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE` | Optional. The number of processes to instantiate when the Resource Processor starts. Equates to the number of parallel deployment operations possible in your TRE. Defaults to `5`. | +| `TRE_URL` | Optional. A custom URL for the TRE as registered in the DNS. Defaults to the DNS name used by Azure Application Gateway.| ## For authentication in `/config.yaml` diff --git a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md index d089d1967d..a0986f20f8 100644 --- a/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md +++ b/docs/tre-admins/setup-instructions/cicd-pre-deployment-steps.md @@ -66,6 +66,7 @@ Configure the following secrets in your github environment: | `MGMT_RESOURCE_GROUP_NAME` | The name of the shared resource group for all Azure TRE core resources. | | `MGMT_STORAGE_ACCOUNT_NAME` | The name of the storage account to hold the Terraform state and other deployment artifacts. E.g. `mystorageaccount`. | | `ACR_NAME` | A globally unique name for the Azure Container Registry (ACR) that will be created to store deployment images. | +| `TRE_URL` | An optional custom URL for the TRE as registered in the DNS. | ### Configure Core Variables diff --git a/docs/tre-admins/setup-instructions/workflows.md b/docs/tre-admins/setup-instructions/workflows.md index 28db90d053..a5051a1a9d 100644 --- a/docs/tre-admins/setup-instructions/workflows.md +++ b/docs/tre-admins/setup-instructions/workflows.md @@ -144,6 +144,7 @@ Configure variables used in the deployment workflow: | `WORKSPACE_APP_SERVICE_PLAN_SKU` | Optional. The SKU used for AppService plan used in E2E tests. Default value is `P1v2`. | | `RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE` | Optional. The number of processes to instantiate when the Resource Processor starts. Equates to the number of parallel deployment operations possible in your TRE. Defaults to `5`. | | `ENABLE_SWAGGER` | Optional. Determines whether the Swagger interface for the API will be available. Default value is `false`. | +| `TRE_URL` | Optional. A custom URL for the TRE as registered in the DNS. Defaults to the DNS name used by Azure Application Gateway.| ### Deploy the TRE using the workflow From 49fb9a0f2b86b81e2dbf24e3253c84507f2fb226 Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 4 Oct 2023 08:00:38 +0000 Subject: [PATCH 3/7] fix action --- .github/actions/devcontainer_run_command/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index 7c3c0ede65..ad5fefe777 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -151,12 +151,12 @@ runs: - name: Construct TRE_URL shell: bash run: | - if [ "${{ secrets.TRE_URL}}" == '' ]; then + if [ "${{ inputs.TRE_URL}}" == '' ]; then source devops/scripts/construct_tre_url.sh tre_url=$(construct_tre_url "${{ inputs.TRE_ID }}" "${{ inputs.LOCATION }}" "${{ env.AZURE_ENVIRONMENT }}") echo "TRE_URL=$tre_url" >> $GITHUB_ENV else - echo "TRE_URL=${{ secrets.TRE_URL }}" >> $GITHUB_ENV + echo "TRE_URL=${{ inputs.TRE_URL }}" >> $GITHUB_ENV fi - name: Construct ARM_ENVIRONMENT From f575d58598a0a262c804cc8416a09a5eac812ac6 Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 4 Oct 2023 09:29:54 +0000 Subject: [PATCH 4/7] fix workflow --- .github/workflows/deploy_tre_reusable.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/deploy_tre_reusable.yml b/.github/workflows/deploy_tre_reusable.yml index a31cb2e4c8..79277aa676 100644 --- a/.github/workflows/deploy_tre_reusable.yml +++ b/.github/workflows/deploy_tre_reusable.yml @@ -441,6 +441,8 @@ jobs: include: - {BUNDLE_TYPE: "shared_service", BUNDLE_DIR: "./templates/shared_services/firewall/"} + - {BUNDLE_TYPE: "shared_service", + BUNDLE_DIR: "./templates/shared_services/core-application-gateway"} - {BUNDLE_TYPE: "shared_service", BUNDLE_DIR: "./templates/shared_services/gitea/"} - {BUNDLE_TYPE: "shared_service", @@ -487,6 +489,8 @@ jobs: include: - {BUNDLE_TYPE: "shared_service", BUNDLE_DIR: "./templates/shared_services/firewall"} + - {BUNDLE_TYPE: "shared_service", + BUNDLE_DIR: "./templates/shared_services/core-application-gateway"} - {BUNDLE_TYPE: "shared_service", BUNDLE_DIR: "./templates/shared_services/gitea"} - {BUNDLE_TYPE: "shared_service", From 348b48d0d32d18f98006cbd58f206b7ce29700ca Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:55:09 +0000 Subject: [PATCH 5/7] fix variable not availble in cicd --- .../devcontainer_run_command/action.yml | 1 + core/terraform/.terraform.lock.hcl | 19 +++++++++++++++++++ core/terraform/variables.tf | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index ad5fefe777..743af40f55 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -219,6 +219,7 @@ runs: -e TRE_ID="${{ inputs.TRE_ID }}" \ -e TF_VAR_tre_id="${{ inputs.TRE_ID }}" \ -e TRE_URL="${{ env.TRE_URL }}" \ + -e TF_VAR_tre_url="${{ env.TRE_URL }}" \ -e TEST_WORKSPACE_APP_ID="${{ inputs.TEST_WORKSPACE_APP_ID }}" \ -e TEST_WORKSPACE_APP_SECRET="${{ inputs.TEST_WORKSPACE_APP_SECRET }}" \ -e TEST_APP_ID="${{ inputs.TEST_APP_ID }}" \ diff --git a/core/terraform/.terraform.lock.hcl b/core/terraform/.terraform.lock.hcl index f8c3f1b7c8..851c069f78 100644 --- a/core/terraform/.terraform.lock.hcl +++ b/core/terraform/.terraform.lock.hcl @@ -1,6 +1,25 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/azure/azapi" { + version = "1.9.0" + hashes = [ + "h1:zaLH2Owmj61RX2G1Cy6VDy8Ttfzx+lDsSCyiu5cXkm4=", + "zh:349569471fbf387feaaf8b88da1690669e201147c342f905e5eb03df42b3cf87", + "zh:54346d5fb78cbad3eb7cfd96e1dd7ce4f78666cabaaccfec6ee9437476330018", + "zh:64b799da915ea3a9a58ac7a926c6a31c59fd0d911687804d8e815eda88c5580b", + "zh:9336ed9e112555e0fda8af6be9ba21478e30117d79ba662233311d9560d2b7c6", + "zh:a8aace9897b28ea0b2dbd7a3be3df033e158af40412c9c7670be0956f216ed7e", + "zh:ab23df7de700d9e785009a4ca9ceb38ae1ab894a13f5788847f15d018556f415", + "zh:b4f13f0b13560a67d427c71c85246f8920f98987120341830071df4535842053", + "zh:e58377bf36d8a14d28178a002657865ee17446182dac03525fd43435e41a1b5c", + "zh:ea5db4acc6413fd0fe6b35981e58cdc9850f5f3118031cc3d2581de511aee6aa", + "zh:f0b32c06c6bd4e4af2c02a62be07b947766aeeb09289a03f21aba16c2fd3c60f", + "zh:f1518e766a90c257d7eb36d360dafaf311593a4a9352ff8db0bcfe0ed8cf45ae", + "zh:fa89e84cff0776b5b61ff27049b1d8ed52040bd58c81c4628890d644a6fb2989", + ] +} + provider "registry.terraform.io/hashicorp/azurerm" { version = "3.74.0" constraints = ">= 3.8.0, >= 3.16.0, 3.74.0" diff --git a/core/terraform/variables.tf b/core/terraform/variables.tf index 08c6713787..3fbdf775f8 100644 --- a/core/terraform/variables.tf +++ b/core/terraform/variables.tf @@ -184,4 +184,8 @@ variable "is_cosmos_defined_throughput" { variable "tre_url" { type = string default = "" + validation { + condition = startswith(var.tre_url, "http") && length(var.tre_url) > 10 + error_message = "Invalid tre_url. Must start with http or https." + } } From 4dce05f25699e92da23698747ccfd76c27df1c06 Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:52:21 +0000 Subject: [PATCH 6/7] vm updates --- .../workspace_services/guacamole/porter.yaml | 44 ++++++++----------- .../guacamole/template_schema.json | 12 ++--- .../guacamole/terraform/outputs.tf | 16 ++++--- .../guacamole-azure-linuxvm/porter.yaml | 7 ++- .../guacamole-azure-linuxvm/terraform/main.tf | 5 --- .../terraform/outputs.tf | 2 +- .../terraform/variables.tf | 7 +++ .../terraform/variables.tf | 4 ++ 8 files changed, 53 insertions(+), 44 deletions(-) diff --git a/templates/workspace_services/guacamole/porter.yaml b/templates/workspace_services/guacamole/porter.yaml index 2c3ca82dc8..8315d0d3e2 100644 --- a/templates/workspace_services/guacamole/porter.yaml +++ b/templates/workspace_services/guacamole/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole -version: 0.11.0 +version: 0.11.1 description: "An Azure TRE service for Guacamole" dockerfile: Dockerfile.tmpl @@ -109,22 +109,17 @@ parameters: type: string outputs: - # - name: authentication_callback_uri - # type: string - # applyTo: - # - install - # - upgrade - # - name: connection_uri - # type: string - # applyTo: - # - install - # - upgrade - # - name: web_apps_addresses - # type: string - # applyTo: - # - install - # - upgrade - - name: internals + - name: authentication_callback_uri + type: string + applyTo: + - install + - upgrade + - name: web_apps_addresses + type: string + applyTo: + - install + - upgrade + - name: routing_fqdn type: string applyTo: - install @@ -167,11 +162,10 @@ install: container_name: ${ bundle.parameters.tfstate_container_name } key: tre-service-guacamole-${ bundle.parameters.id } outputs: - # - name: authentication_callback_uri - # - name: web_apps_addresses + - name: authentication_callback_uri + - name: web_apps_addresses - name: admin_connection_uri - # - name: connection_uri - - name: internals + - name: routing_fqdn upgrade: - terraform: @@ -201,11 +195,11 @@ upgrade: container_name: ${ bundle.parameters.tfstate_container_name } key: tre-service-guacamole-${ bundle.parameters.id } outputs: - # - name: authentication_callback_uri - # - name: web_apps_addresses + - name: authentication_callback_uri + - name: web_apps_addresses - name: admin_connection_uri - # - name: connection_uri - - name: internals + - name: routing_fqdn + uninstall: - terraform: diff --git a/templates/workspace_services/guacamole/template_schema.json b/templates/workspace_services/guacamole/template_schema.json index 71a94bf9cb..60bf6df3f4 100644 --- a/templates/workspace_services/guacamole/template_schema.json +++ b/templates/workspace_services/guacamole/template_schema.json @@ -91,7 +91,7 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "fqdn": "{{ resource.properties.internals.routing_fqdn }}" + "fqdn": "{{ resource.properties.routing_fqdn }}" } } ] @@ -109,7 +109,7 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "value": "{{ resource.properties.internals.authentication_callback_uri }}" + "value": "{{ resource.properties.authentication_callback_uri }}" } } ] @@ -133,7 +133,7 @@ { "name": "AzureAD", "description": "AAD access for authNZ", - "source_addresses": "{{ resource.properties.internals.web_apps_addresses }}", + "source_addresses": "{{ resource.properties.web_apps_addresses }}", "destination_addresses": [ "AzureActiveDirectory" ], @@ -168,7 +168,7 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "fqdn": "{{ resource.properties.internals.routing_fqdn }}" + "fqdn": "{{ resource.properties.routing_fqdn }}" } } ] @@ -186,7 +186,7 @@ "arrayMatchField": "name", "value": { "name": "{{ resource.id }}", - "value": "{{ resource.properties.internals.authentication_callback_uri }}" + "value": "{{ resource.properties.authentication_callback_uri }}" } } ] @@ -210,7 +210,7 @@ { "name": "AzureAD", "description": "AAD access for authNZ", - "source_addresses": "{{ resource.properties.internals.web_apps_addresses }}", + "source_addresses": "{{ resource.properties.web_apps_addresses }}", "destination_addresses": [ "AzureActiveDirectory" ], diff --git a/templates/workspace_services/guacamole/terraform/outputs.tf b/templates/workspace_services/guacamole/terraform/outputs.tf index 42170caf95..4873a93090 100644 --- a/templates/workspace_services/guacamole/terraform/outputs.tf +++ b/templates/workspace_services/guacamole/terraform/outputs.tf @@ -1,9 +1,13 @@ -output "internals" { - value = jsonencode({ - authentication_callback_uri = local.webapp_auth_callback_url - routing_fqdn = var.is_exposed_externally ? azurerm_linux_web_app.guacamole.default_hostname : "" - web_apps_addresses = data.azurerm_subnet.web_apps.address_prefixes - }) +output "authentication_callback_uri" { + value = local.webapp_auth_callback_url +} + +output "routing_fqdn" { + value = var.is_exposed_externally ? azurerm_linux_web_app.guacamole.default_hostname : "" +} + +output "web_apps_addresses" { + value = jsonencode(data.azurerm_subnet.web_apps.address_prefixes) } output "admin_connection_uri" { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml index f36a668258..e00249ead9 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm -version: 0.6.9 +version: 0.7.0 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -101,6 +101,8 @@ parameters: - name: shared_storage_name type: string default: "vm-shared-storage" + - name: tre_url + type: string outputs: - name: ip @@ -146,6 +148,7 @@ install: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } @@ -170,6 +173,7 @@ upgrade: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } @@ -203,6 +207,7 @@ uninstall: shared_storage_access: ${ bundle.parameters.shared_storage_access } shared_storage_name: ${ bundle.parameters.shared_storage_name } image_gallery_id: ${ bundle.parameters.image_gallery_id } + tre_url: ${ bundle.parameters.tre_url } backendConfig: resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf index eb0ba0fac3..a37f47ab0c 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/main.tf @@ -60,11 +60,6 @@ data "azurerm_key_vault" "ws" { resource_group_name = data.azurerm_resource_group.ws.name } -data "azurerm_linux_web_app" "guacamole" { - name = "guacamole-${var.tre_id}-ws-${local.short_workspace_id}-svc-${local.short_parent_id}" - resource_group_name = data.azurerm_resource_group.ws.name -} - data "azurerm_public_ip" "app_gateway_ip" { name = "pip-agw-${var.tre_id}" resource_group_name = data.azurerm_resource_group.core.name diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/outputs.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/outputs.tf index 30a5a90a39..9453a165b5 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/outputs.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/outputs.tf @@ -11,7 +11,7 @@ output "azure_resource_id" { } output "connection_uri" { - value = "https://${data.azurerm_linux_web_app.guacamole.default_hostname}/?/client/${textencodebase64("${azurerm_linux_virtual_machine.linuxvm.name}\u0000c\u0000azuretre", "UTF-8")}" + value = "${var.tre_url}/${var.parent_service_id}/?/client/${textencodebase64("${azurerm_linux_virtual_machine.linuxvm.name}\u0000c\u0000azuretre", "UTF-8")}" } output "vm_username" { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf index 4908ae52a2..58eb2528c5 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/variables.tf @@ -26,3 +26,10 @@ variable "image_gallery_id" { type = string default = "" } +variable "tre_url" { + type = string + validation { + condition = startswith(var.tre_url, "http") && length(var.tre_url) > 10 + error_message = "Invalid tre_url. Must start with http or https." + } +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf index 8742e44891..58eb2528c5 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm/terraform/variables.tf @@ -28,4 +28,8 @@ variable "image_gallery_id" { } variable "tre_url" { type = string + validation { + condition = startswith(var.tre_url, "http") && length(var.tre_url) > 10 + error_message = "Invalid tre_url. Must start with http or https." + } } From 1f7a985c4e677f29db0d8dfd3ba19b6b64d5a529 Mon Sep 17 00:00:00 2001 From: Tamir Kamara <26870601+tamirkamara@users.noreply.github.com> Date: Sat, 7 Oct 2023 05:59:24 +0000 Subject: [PATCH 7/7] fix tf lock file --- core/terraform/.terraform.lock.hcl | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/core/terraform/.terraform.lock.hcl b/core/terraform/.terraform.lock.hcl index 851c069f78..f8c3f1b7c8 100644 --- a/core/terraform/.terraform.lock.hcl +++ b/core/terraform/.terraform.lock.hcl @@ -1,25 +1,6 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. -provider "registry.terraform.io/azure/azapi" { - version = "1.9.0" - hashes = [ - "h1:zaLH2Owmj61RX2G1Cy6VDy8Ttfzx+lDsSCyiu5cXkm4=", - "zh:349569471fbf387feaaf8b88da1690669e201147c342f905e5eb03df42b3cf87", - "zh:54346d5fb78cbad3eb7cfd96e1dd7ce4f78666cabaaccfec6ee9437476330018", - "zh:64b799da915ea3a9a58ac7a926c6a31c59fd0d911687804d8e815eda88c5580b", - "zh:9336ed9e112555e0fda8af6be9ba21478e30117d79ba662233311d9560d2b7c6", - "zh:a8aace9897b28ea0b2dbd7a3be3df033e158af40412c9c7670be0956f216ed7e", - "zh:ab23df7de700d9e785009a4ca9ceb38ae1ab894a13f5788847f15d018556f415", - "zh:b4f13f0b13560a67d427c71c85246f8920f98987120341830071df4535842053", - "zh:e58377bf36d8a14d28178a002657865ee17446182dac03525fd43435e41a1b5c", - "zh:ea5db4acc6413fd0fe6b35981e58cdc9850f5f3118031cc3d2581de511aee6aa", - "zh:f0b32c06c6bd4e4af2c02a62be07b947766aeeb09289a03f21aba16c2fd3c60f", - "zh:f1518e766a90c257d7eb36d360dafaf311593a4a9352ff8db0bcfe0ed8cf45ae", - "zh:fa89e84cff0776b5b61ff27049b1d8ed52040bd58c81c4628890d644a6fb2989", - ] -} - provider "registry.terraform.io/hashicorp/azurerm" { version = "3.74.0" constraints = ">= 3.8.0, >= 3.16.0, 3.74.0"