From 90164b833bff9bbe00373d1f107a6ad0145db01e Mon Sep 17 00:00:00 2001 From: JaimieWi <92854957+JaimieWi@users.noreply.github.com> Date: Wed, 5 Nov 2025 08:39:13 +0000 Subject: [PATCH 01/26] Upgrade TRE to tvstre-prod-main-v0.23.0 (#60) * Update workspace template readme * MERGE TEST: Upgrade TRE to tvstre-prod-main-v0.23.1 (#61) * Changes pulled in from upstream deployment repo * Test fix lint error * FIX implemented: Update devcontainer configuration for improved setup --- .devcontainer/devcontainer.json | 2 +- .../devcontainer_run_command/action.yml | 27 +++++++++ .github/workflows/deploy_tre.yml | 3 +- .github/workflows/deploy_tre_branch.yml | 1 + .github/workflows/deploy_tre_reusable.yml | 31 ++++++++-- .github/workflows/register_tre_bundle.yml | 60 +++++-------------- config.sample.yaml | 25 ++++++++ templates/workspaces/README.md | 6 +- 8 files changed, 99 insertions(+), 56 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 136706f..971ed60 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.22.0", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.23.1", "GITHUB_TOKEN": "" } }, diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index 36290e6..8a474e4 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -145,6 +145,26 @@ inputs: description: "The Azure Resource ID for an external key store to use for CMK" required: false default: "" + USER_MANAGEMENT_ENABLED: + description: "If set to true TRE Admins are able to assign and de-assign users to workspaces via the UI" + required: false + default: "false" + PRIVATE_AGENT_SUBNET_ID: + description: Enables vnet exception for the subnet to access private resources + required: false + default: "" + UI_SITE_NAME: + description: "Product name shown in top left corner of TRE portal" + required: false + default: "Azure TRE" + UI_FOOTER_TEXT: + description: "Text shown in bottom left corner of TRE portal" + required: false + default: "Azure Trusted Research Environment" + AUTO_GRANT_WORKSPACE_CONSENT: + description: "When set to true removes the need for users to manually grant consent when creating new workspaces" + required: false + default: "false" DOCKER_USERNAME: description: "Docker Hub username" required: true @@ -272,6 +292,8 @@ runs: && inputs.WORKSPACE_APP_SERVICE_PLAN_SKU) || 'P1v2' }}" \ -e TF_VAR_rp_bundle_values='${{ (toJson(inputs.RP_BUNDLE_VALUES) != '""' && inputs.RP_BUNDLE_VALUES) || '{}' }}' \ + -e UI_SITE_NAME="${{ inputs.UI_SITE_NAME }}" \ + -e UI_FOOTER_TEXT="${{ inputs.UI_FOOTER_TEXT }}" \ -e TF_VAR_resource_processor_number_processes_per_instance="${{ (inputs.RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE != '' && inputs.RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE) || 5 }}" \ -e TF_VAR_firewall_sku=${{ inputs.FIREWALL_SKU }} \ @@ -280,6 +302,11 @@ runs: && inputs.ENABLE_CMK_ENCRYPTION) || 'false' }}" \ -e TF_VAR_encryption_kv_name="${{ inputs.ENCRYPTION_KV_NAME }}" \ -e TF_VAR_external_key_store_id="${{ inputs.EXTERNAL_KEY_STORE_ID }}" \ + -e TF_VAR_user_management_enabled="${{ (inputs.USER_MANAGEMENT_ENABLED != '' && inputs.USER_MANAGEMENT_ENABLED) || 'false' }}" \ + -e USER_MANAGEMENT_ENABLED="${{ inputs.USER_MANAGEMENT_ENABLED }}" \ + -e PRIVATE_AGENT_SUBNET_ID=${{ inputs.PRIVATE_AGENT_SUBNET_ID }} \ + -e TF_VAR_private_agent_subnet_id=${{ inputs.PRIVATE_AGENT_SUBNET_ID }} \ + -e TF_VAR_auto_grant_workspace_consent="${{ (inputs.AUTO_GRANT_WORKSPACE_CONSENT != '' && inputs.AUTO_GRANT_WORKSPACE_CONSENT) || 'false' }}" \ -e DOCKER_USERNAME="${{ inputs.DOCKER_USERNAME }}" \ -e DOCKER_TOKEN="${{ inputs.DOCKER_TOKEN }}" \ -e E2E_TESTS_NUMBER_PROCESSES="${{ inputs.E2E_TESTS_NUMBER_PROCESSES }}" \ diff --git a/.github/workflows/deploy_tre.yml b/.github/workflows/deploy_tre.yml index 0f3f090..7540f29 100644 --- a/.github/workflows/deploy_tre.yml +++ b/.github/workflows/deploy_tre.yml @@ -36,7 +36,7 @@ jobs: || 'extended or extended_aad or shared_services or airlock' }} environmentName: ${{ github.event.inputs.environment || 'CICD' }} E2E_TESTS_NUMBER_PROCESSES: 1 - DEVCONTAINER_TAG: 'latest' + DEVCONTAINER_TAG: "latest" secrets: AAD_TENANT_ID: ${{ secrets.AAD_TENANT_ID }} ACR_NAME: ${{ secrets.ACR_NAME }} @@ -57,5 +57,6 @@ jobs: CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} ENCRYPTION_KV_NAME: ${{ secrets.ENCRYPTION_KV_NAME }} EXTERNAL_KEY_STORE_ID: ${{ secrets.EXTERNAL_KEY_STORE_ID }} + PRIVATE_AGENT_SUBNET_ID: ${{ secrets.PRIVATE_AGENT_SUBNET_ID }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} diff --git a/.github/workflows/deploy_tre_branch.yml b/.github/workflows/deploy_tre_branch.yml index ac8c014..f652ca6 100644 --- a/.github/workflows/deploy_tre_branch.yml +++ b/.github/workflows/deploy_tre_branch.yml @@ -89,5 +89,6 @@ jobs: CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME }} ENCRYPTION_KV_NAME: ${{ format('tre{0}mgmt', needs.prepare-not-main.outputs.refid) }} EXTERNAL_KEY_STORE_ID: ${{ secrets.EXTERNAL_KEY_STORE_ID }} + PRIVATE_AGENT_SUBNET_ID: ${{ secrets.PRIVATE_AGENT_SUBNET_ID }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} diff --git a/.github/workflows/deploy_tre_reusable.yml b/.github/workflows/deploy_tre_reusable.yml index f8bc3ed..2005075 100644 --- a/.github/workflows/deploy_tre_reusable.yml +++ b/.github/workflows/deploy_tre_reusable.yml @@ -1,7 +1,7 @@ --- name: Deploy Azure TRE Reusable -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy workflow_call: inputs: prRef: @@ -35,6 +35,16 @@ on: # yamllint disable-line rule:truthy description: "" type: string required: true + UI_SITE_NAME: + description: Change the header text in the TRE portal + type: string + default: "" + required: false + UI_FOOTER_TEXT: + description: Change the footer text in the TRE portal + type: string + default: "" + required: false secrets: AAD_TENANT_ID: description: "" @@ -93,6 +103,9 @@ on: # yamllint disable-line rule:truthy EXTERNAL_KEY_STORE_ID: description: "" required: false + PRIVATE_AGENT_SUBNET_ID: + description: "" + required: false DOCKER_USERNAME: description: "Docker Hub username" required: true @@ -208,7 +221,7 @@ jobs: environment: ${{ (vars.AZURE_ENVIRONMENT != '' && vars.AZURE_ENVIRONMENT) || 'AzureCloud' }} - name: ACR Login - id: ci_cache_cr_login + id: ci_cache_acr_login # will fail if this is a new env which is expected continue-on-error: true run: az acr login --name "${{ secrets.CI_CACHE_ACR_NAME }}" @@ -226,7 +239,7 @@ jobs: echo "CI_CACHE_ACR_URI=$CI_CACHE_ACR_URI" >> "$GITHUB_ENV" docker_cache=() - if [ "${{ steps.ci_cache_cr_login.outcome }}" = "success" ]; then + if [ "${{ steps.ci_cache_acr_login.outcome }}" = "success" ]; then docker_cache+=(--cache-from "$CI_CACHE_ACR_URI/tredev:${{ inputs.DEVCONTAINER_TAG }}") docker_cache+=(--cache-from "$CI_CACHE_ACR_URI/tredev:latest") fi @@ -255,17 +268,21 @@ jobs: ENABLE_CMK_ENCRYPTION: ${{ vars.ENABLE_CMK_ENCRYPTION }} ENCRYPTION_KV_NAME: ${{ secrets.ENCRYPTION_KV_NAME }} EXTERNAL_KEY_STORE_ID: ${{ secrets.EXTERNAL_KEY_STORE_ID }} + PRIVATE_AGENT_SUBNET_ID: ${{ secrets.PRIVATE_AGENT_SUBNET_ID }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} - name: ACR Login # failure in the first attempt indicates a new ACR, so we need to try again after it's been created - if: steps.ci_cache_cr_login.outcome != 'success' + if: steps.ci_cache_acr_login.outcome != 'success' run: | # shellcheck disable=SC2034,SC2015,SC2125 for i in {1..3}; do az acr login --name "${{ secrets.CI_CACHE_ACR_NAME }}" && ec=0 && break || ec="$?" && sleep 10 done + if [ "$ec" != 0 ]; then + echo "::error::Failed to login to ACR after 3 attempts. Make sure to run the pipleline on the main branch first." + fi # shellcheck disable=SC2242 (exit "$ec") @@ -386,6 +403,9 @@ jobs: ENABLE_CMK_ENCRYPTION: ${{ vars.ENABLE_CMK_ENCRYPTION }} ENCRYPTION_KV_NAME: ${{ secrets.ENCRYPTION_KV_NAME }} EXTERNAL_KEY_STORE_ID: ${{ secrets.EXTERNAL_KEY_STORE_ID }} + USER_MANAGEMENT_ENABLED: ${{ vars.USER_MANAGEMENT_ENABLED }} + PRIVATE_AGENT_SUBNET_ID: ${{ secrets.PRIVATE_AGENT_SUBNET_ID }} + AUTO_GRANT_WORKSPACE_CONSENT: ${{ vars.AUTO_GRANT_WORKSPACE_CONSENT }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} @@ -819,5 +839,8 @@ 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 }}" + USER_MANAGEMENT_ENABLED: ${{ vars.USER_MANAGEMENT_ENABLED }} + UI_SITE_NAME: "${{ inputs.UI_SITE_NAME || vars.UI_SITE_NAME }}" + UI_FOOTER_TEXT: "${{ inputs.UI_FOOTER_TEXT || vars.UI_FOOTER_TEXT }}" DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} diff --git a/.github/workflows/register_tre_bundle.yml b/.github/workflows/register_tre_bundle.yml index 3c9cb58..16b86df 100644 --- a/.github/workflows/register_tre_bundle.yml +++ b/.github/workflows/register_tre_bundle.yml @@ -29,10 +29,6 @@ on: description: The name of the workspace service to register user resources for type: string required: false - prRef: - description: The git ref to checkout - type: string - required: false jobs: deploy_management: @@ -50,7 +46,6 @@ jobs: echo "prRHeadSha : ${{ github.sha }}" echo "ciGitRef : ${{ github.ref }}" echo "environment : ${{ inputs.environmentName || 'CICD'}}" - echo "prRef : ${{ inputs.prRef }}" echo AAD_TENANT_ID: ${{ secrets.AAD_TENANT_ID }} echo ACR_NAME: ${{ secrets.ACR_NAME }} echo API_CLIENT_ID: ${{ secrets.API_CLIENT_ID }} @@ -92,21 +87,19 @@ jobs: echo "Missing secret: AZURE_CREDENTIALS" && exit 1 fi - bundle_name="${{ inputs.bundle_name }}" - bundle_type="${{ inputs.bundle_type }}" - workspace_service_name="${{ inputs.workspace_service_name }}" - # if bundle_name is not set, exit with error - if [ -z "${bundle_name}" ]; then + if [ -z "${{ inputs.bundle_name }}" ]; then echo "Missing input: bundle_name" && exit 1 fi - if [ -z "${bundle_type}" ]; then + # if bundle_type is not set, exit with error + if [ -z "${{ inputs.bundle_type }}" ]; then echo "Missing input: bundle_type" && exit 1 fi - if [ $bundle_type = "user_resource" ]; then - if [ -z "${workspace_service_name}" ]; then + # if bundle_type is user_resource, then workspace_service_name is required, if not set, exit with error + if [ "${{ inputs.bundle_type }}" = "user_resource" ]; then + if [ -z "${{ inputs.workspace_service_name }}" ]; then echo "Missing input: workspace_service_name" && exit 1 fi fi @@ -126,7 +119,7 @@ jobs: persist-credentials: false # if the following values are missing (i.e. not triggered via comment workflow) # then the default checkout will apply - ref: ${{ inputs.prRef }} + ref: ${{ github.ref }} - name: Set up Docker BuildKit uses: docker/setup-buildx-action@v3 @@ -176,11 +169,13 @@ jobs: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} AZURE_ENVIRONMENT: ${{ vars.AZURE_ENVIRONMENT }} TRE_ID: ${{ secrets.TRE_ID }} - LOCATION: "uksouth" + LOCATION: ${{ vars.LOCATION }} ACR_NAME: ${{ secrets.ACR_NAME }} 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 }} + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} - name: ACR Login # failure in the first attempt indicates a new ACR, so we need to try again after it's been created @@ -234,42 +229,15 @@ jobs: - name: Register Bundle uses: ./.github/actions/devcontainer_run_command with: - COMMAND: | - echo "Starting bundle registration" - bundle_name="${{ inputs.bundle_name }}" - bundle_type="${{ inputs.bundle_type }}" - workspace_service_name="${{ inputs.workspace_service_name }}" - - if [ $bundle_type = "workspace" ]; then - echo "Registering workspace bundle $bundle_name of type $bundle_type" - make workspace_bundle BUNDLE="${bundle_name}" - fi - - if [ $bundle_type = "workspace_service" ]; then - echo "Registering workspace service bundle $bundle_name of type $bundle_type" - make workspace_service_bundle BUNDLE="${bundle_name}" WORKSPACE_SERVICE="${workspace_service_name}" - fi - - if [ $bundle_type = "shared_service" ]; then - echo "Registering shared service bundle $bundle_name of type $bundle_type" - make shared_service_bundle BUNDLE="${bundle_name}" - fi - - if [ $bundle_type = "user_resource" ]; then - echo "Registering user resource bundle $bundle_name of type $bundle_type into workspace service $workspace_service_name" - make user_resource_bundle BUNDLE="${bundle_name}" WORKSPACE_SERVICE="${workspace_service_name}" - fi - - echo "Finished bundle registration" - DEVCONTAINER_TAG: ${{ needs.prepare-not-main.outputs.refid }} + COMMAND: "make bundle BUNDLE=${{ inputs.bundle_name }} BUNDLE_TYPE=${{ inputs.bundle_type }} WORKSPACE_SERVICE=${{ inputs.workspace_service_name }}" + DEVCONTAINER_TAG: 'latest' AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} AZURE_ENVIRONMENT: ${{ vars.AZURE_ENVIRONMENT }} CI_CACHE_ACR_NAME: ${{ secrets.ACR_NAME}} ACR_NAME: ${{ secrets.ACR_NAME }} 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 }} + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} diff --git a/config.sample.yaml b/config.sample.yaml index 009f017..ccac3d2 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -8,6 +8,8 @@ management: mgmt_storage_account_name: __CHANGE_ME__ terraform_state_container_name: tfstate acr_name: __CHANGE_ME__ + # Set this to true if you want to disable public access to mgmt acr + disable_acr_public_access: true # ID of external Key Vault to store CMKs in (only required if enable_cmk_encryption is true) # external_key_store_id: __CHANGE_ME__ # Name of Key Vault for encryption, required if enable_cmk_encryption is true and external_key_store_id is not set @@ -49,6 +51,20 @@ tre: # firewall_force_tunnel_ip: __CHANGE_ME__ firewall_sku: Standard app_gateway_sku: Standard_v2 + deploy_bastion: true + # See https://learn.microsoft.com/en-us/azure/bastion/bastion-overview#sku + # Set to Basic if wish to connect to VMs in workspaces. + bastion_sku: Basic + + # Set to true if TreAdmins should be able to assign and de-assign users to workspaces via the UI + user_management_enabled: false + + # Uncomment to enable DNS Security policy on the system, and add any known DNS names that you need to allow + # DNS queries on, in addition to those in the core list in core/terraform/allowed-dns.json + # Note, these need to be fully qualified, i.e. they end in a dot(.) + # enable_dns_policy: true + # allowed_dns: + # - mydomain.com. # Uncomment to deploy to a custom domain # custom_domain: __CHANGE_ME__ @@ -63,6 +79,9 @@ authentication: auto_workspace_app_registration: true # Setting AUTO_WORKSPACE_GROUP_CREATION to true will create an identity with `Group.ReadWrite.All` auto_workspace_group_creation: false + # Setting this to true will remove the need for users to manually grant consent when creating new workspaces. + # The identity will be granted Application.ReadWrite.All and DelegatedPermissionGrant.ReadWrite.All permissions. + auto_grant_workspace_consent: false resource_processor: # The number of processes to start in the resource processor VMSS image @@ -74,6 +93,12 @@ resource_processor: # yamllint disable-line rule:line-length # rp_bundle_values: '{"custom_key_1":"custom_value_1","image_gallery_id":"/subscriptions//resourceGroups//providers/Microsoft.Compute/galleries/"}' +ui_config: + # Product name shown in the top left hand corner of the TRE portal + ui_site_name: "Azure TRE" + # Footer text shown in the bottom left hand corner of the TRE portal + ui_footer_text: "Azure Trusted Research Environment" + developer_settings: # Locks will not be added to stateful resources so they can be easily removed # stateful_resources_locked: false diff --git a/templates/workspaces/README.md b/templates/workspaces/README.md index 3813039..96c6563 100644 --- a/templates/workspaces/README.md +++ b/templates/workspaces/README.md @@ -1,10 +1,8 @@ # Workspace Templates -OUH do not have custom workspace templates at this time. - -Workspace Templates are located in this folder. These Templates are for the Composition Service to make instances of. +Workspace Templates are located in this folder. | Template name | Description | | --- | --- | -We have custom changes to the base workspace template to enforce tags to be created against the relevant resources for achiving. For more detail on the Archive process, see SOP019 Archival of Projects in the Analysis Environment \ No newline at end of file +We have custom changes to the base workspace template to enforce tags to be created against the relevant resources for achiving. For more detail on the Archive process, see SOP019 Archival of Projects in the Analysis Environment. From d8565cf2770b493dc8e6d2d7004811cc6a60e4f6 Mon Sep 17 00:00:00 2001 From: Jaimie Withers Date: Thu, 12 Mar 2026 08:40:15 +0000 Subject: [PATCH 02/26] TRE Upgrade - Initial feature branch commit for PR --- vm-images/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vm-images/README.md b/vm-images/README.md index ac523c4..6dd0b56 100644 --- a/vm-images/README.md +++ b/vm-images/README.md @@ -1,3 +1,5 @@ +This process is being replaced - ReadMe will remain but may be archived. + # Custom Virtual Machine Images This folder contains files that deploy the infrastructre used to create and publish custom virtual machine (VM) images in Azure. From d1382bcf3615ebd337b07f3c5b961cca0de5ba64 Mon Sep 17 00:00:00 2001 From: Jaimie Withers Date: Thu, 12 Mar 2026 12:24:46 +0000 Subject: [PATCH 03/26] TRE Upgrade v0.25.0 Custom and upstream changes --- .../devcontainer_run_command/action.yml | 13 +- .github/workflows/deploy_tre_reusable.yml | 7 +- .../guacamole-azure-linuxvm-ouh2/porter.yaml | 21 +- .../template_schema.json | 164 +++++++++++--- .../terraform/main.tf | 8 +- .../terraform/vm_config.sh | 139 +++--------- .../porter.yaml | 43 +++- .../template_schema.json | 200 +++++++++++++++++- .../terraform/main.tf | 4 +- .../terraform/variables.tf | 11 + .../terraform/vm_config.ps1 | 74 ++----- .../terraform/windowsvm.tf | 13 ++ 12 files changed, 465 insertions(+), 232 deletions(-) diff --git a/.github/actions/devcontainer_run_command/action.yml b/.github/actions/devcontainer_run_command/action.yml index 8a474e4..ef17627 100644 --- a/.github/actions/devcontainer_run_command/action.yml +++ b/.github/actions/devcontainer_run_command/action.yml @@ -1,6 +1,7 @@ --- name: "run_command" description: "Run a command in a devcontainer" +# yamllint disable rule:line-length inputs: COMMAND: description: "The command you want to run in the Devcontainer." @@ -165,6 +166,14 @@ inputs: description: "When set to true removes the need for users to manually grant consent when creating new workspaces" required: false default: "false" + ENABLE_DNS_POLICY: + description: "Enable the DNS security policy" + required: false + default: "false" + ALLOWED_DNS: + description: "Add allowed domain name to the DNS security policy" + required: false + default: "[]" DOCKER_USERNAME: description: "Docker Hub username" required: true @@ -296,7 +305,7 @@ runs: -e UI_FOOTER_TEXT="${{ inputs.UI_FOOTER_TEXT }}" \ -e TF_VAR_resource_processor_number_processes_per_instance="${{ (inputs.RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE != '' && inputs.RESOURCE_PROCESSOR_NUMBER_PROCESSES_PER_INSTANCE) || 5 }}" \ - -e TF_VAR_firewall_sku=${{ inputs.FIREWALL_SKU }} \ + -e TF_VAR_firewall_sku=${{ inputs.FIREWALL_SKU != '' && inputs.FIREWALL_SKU || 'Standard' }} \ -e TF_VAR_app_gateway_sku=${{ inputs.APP_GATEWAY_SKU }} \ -e TF_VAR_enable_cmk_encryption="${{ (inputs.ENABLE_CMK_ENCRYPTION != '' && inputs.ENABLE_CMK_ENCRYPTION) || 'false' }}" \ @@ -307,6 +316,8 @@ runs: -e PRIVATE_AGENT_SUBNET_ID=${{ inputs.PRIVATE_AGENT_SUBNET_ID }} \ -e TF_VAR_private_agent_subnet_id=${{ inputs.PRIVATE_AGENT_SUBNET_ID }} \ -e TF_VAR_auto_grant_workspace_consent="${{ (inputs.AUTO_GRANT_WORKSPACE_CONSENT != '' && inputs.AUTO_GRANT_WORKSPACE_CONSENT) || 'false' }}" \ + -e TF_VAR_enable_dns_policy="${{ (inputs.ENABLE_DNS_POLICY != '' && inputs.ENABLE_DNS_POLICY) || 'false' }}" \ + -e TF_VAR_allowed_dns='${{ (toJson(inputs.ALLOWED_DNS) != '""' && inputs.ALLOWED_DNS) || '[]' }}' \ -e DOCKER_USERNAME="${{ inputs.DOCKER_USERNAME }}" \ -e DOCKER_TOKEN="${{ inputs.DOCKER_TOKEN }}" \ -e E2E_TESTS_NUMBER_PROCESSES="${{ inputs.E2E_TESTS_NUMBER_PROCESSES }}" \ diff --git a/.github/workflows/deploy_tre_reusable.yml b/.github/workflows/deploy_tre_reusable.yml index 2005075..2327479 100644 --- a/.github/workflows/deploy_tre_reusable.yml +++ b/.github/workflows/deploy_tre_reusable.yml @@ -1,5 +1,6 @@ --- name: Deploy Azure TRE Reusable +# yamllint disable rule:line-length rule:comments-indentation on: # yamllint disable-line rule:truthy workflow_call: @@ -281,7 +282,8 @@ jobs: az acr login --name "${{ secrets.CI_CACHE_ACR_NAME }}" && ec=0 && break || ec="$?" && sleep 10 done if [ "$ec" != 0 ]; then - echo "::error::Failed to login to ACR after 3 attempts. Make sure to run the pipleline on the main branch first." + echo "::error::Failed to login to ACR after 3 attempts. Make sure to run the" \ + "pipleline on the main branch first." fi # shellcheck disable=SC2242 (exit "$ec") @@ -406,6 +408,8 @@ jobs: USER_MANAGEMENT_ENABLED: ${{ vars.USER_MANAGEMENT_ENABLED }} PRIVATE_AGENT_SUBNET_ID: ${{ secrets.PRIVATE_AGENT_SUBNET_ID }} AUTO_GRANT_WORKSPACE_CONSENT: ${{ vars.AUTO_GRANT_WORKSPACE_CONSENT }} + ENABLE_DNS_POLICY: ${{ vars.ENABLE_DNS_POLICY }} + ALLOWED_DNS: ${{ vars.ALLOWED_DNS }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} @@ -781,7 +785,6 @@ jobs: TEST_ACCOUNT_CLIENT_SECRET: "${{ secrets.TEST_ACCOUNT_CLIENT_SECRET }}" TRE_ID: ${{ secrets.TRE_ID }} LOCATION: ${{ vars.LOCATION }} - FIREWALL_SKU: ${{ vars.FIREWALL_SKU}} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index dda3610..2d313a5 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm-ouh2 -version: 1.1.8 +version: 1.1.9 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -44,20 +44,17 @@ custom: secure_boot_enabled: true vtpm_enabled: true "OUH Ubuntu 22.04 Data Science VM": - source_image_name: imgdef-linux-vm-custom + source_image_name: imgdef-linux-vm-custom-gen2 install_ui: true conda_config: true r_config: true docker_config: true - secure_boot_enabled: true - vtpm_enabled: 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 - # install_ui: true - # conda_config: true - # secure_boot_enabled: false - # vtpm_enabled: false + # secure_boot and vtpm are disabled because the image was captured from a Standard + # security type build VM. The image definition does not have SecurityType=TrustedLaunchSupported + # and enabling these flags would cause a validation error on deployment. + # Revisit when rebuilding from a Trusted Launch build VM. + secure_boot_enabled: false + vtpm_enabled: false credentials: @@ -413,4 +410,4 @@ reset_password: - ${ bundle.outputs.vm_password_secret_name } - ${ bundle.outputs.keyvault_name } - ${ bundle.outputs.vm_username } - - ${ bundle.outputs.azure_resource_id } + - ${ bundle.outputs.azure_resource_id } \ No newline at end of file diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/template_schema.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/template_schema.json index 0cad594..1ebd444 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/template_schema.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/template_schema.json @@ -83,7 +83,14 @@ "title": "Enable Shutdown Schedule", "default": false, "description": "Enable automatic shutdown schedule for the VM" - } + }, + "assign_to_another_user": { + "type": "boolean", + "title": "Assign this VM to another user", + "description": "Check this box if you want to assign this VM to another user.", + "default": false, + "updateable": false + } }, "allOf": [ { @@ -112,31 +119,112 @@ "description": "Timezone for the shutdown schedule", "default": "UTC", "enum": [ - "UTC -12", - "UTC -11", - "UTC -10", - "UTC -9", - "UTC -8", - "UTC -7", - "UTC -6", - "UTC -5", - "UTC -4", - "UTC -3", - "UTC -2", - "UTC -1", + "Afghanistan Standard Time", + "Alaskan Standard Time", + "Arab Standard Time", + "Arabian Standard Time", + "Arabic Standard Time", + "Argentina Standard Time", + "Atlantic Standard Time", + "AUS Central Standard Time", + "AUS Eastern Standard Time", + "Azerbaijan Standard Time", + "Azores Standard Time", + "Bahia Standard Time", + "Bangladesh Standard Time", + "Belarus Standard Time", + "Canada Central Standard Time", + "Cape Verde Standard Time", + "Caucasus Standard Time", + "Cen. Australia Standard Time", + "Central America Standard Time", + "Central Asia Standard Time", + "Central Brazilian Standard Time", + "Central Europe Standard Time", + "Central European Standard Time", + "Central Pacific Standard Time", + "Central Standard Time (Mexico)", + "Central Standard Time", + "China Standard Time", + "Dateline Standard Time", + "E. Africa Standard Time", + "E. Australia Standard Time", + "E. Europe Standard Time", + "E. South America Standard Time", + "Eastern Standard Time (Mexico)", + "Eastern Standard Time", + "Egypt Standard Time", + "Ekaterinburg Standard Time", + "Fiji Standard Time", + "FLE Standard Time", + "Georgian Standard Time", + "GMT Standard Time", + "Greenland Standard Time", + "Greenwich Standard Time", + "GTB Standard Time", + "Hawaiian Standard Time", + "India Standard Time", + "Iran Standard Time", + "Israel Standard Time", + "Jordan Standard Time", + "Kaliningrad Standard Time", + "Korea Standard Time", + "Libya Standard Time", + "Line Islands Standard Time", + "Magadan Standard Time", + "Mauritius Standard Time", + "Middle East Standard Time", + "Montevideo Standard Time", + "Morocco Standard Time", + "Mountain Standard Time (Mexico)", + "Mountain Standard Time", + "Myanmar Standard Time", + "N. Central Asia Standard Time", + "Namibia Standard Time", + "Nepal Standard Time", + "New Zealand Standard Time", + "Newfoundland Standard Time", + "North Asia East Standard Time", + "North Asia Standard Time", + "Pacific SA Standard Time", + "Pacific Standard Time (Mexico)", + "Pacific Standard Time", + "Pakistan Standard Time", + "Paraguay Standard Time", + "Romance Standard Time", + "Russia Time Zone 10", + "Russia Time Zone 11", + "Russia Time Zone 3", + "Russian Standard Time", + "SA Eastern Standard Time", + "SA Pacific Standard Time", + "SA Western Standard Time", + "Samoa Standard Time", + "SE Asia Standard Time", + "Singapore Standard Time", + "South Africa Standard Time", + "Sri Lanka Standard Time", + "Syria Standard Time", + "Taipei Standard Time", + "Tasmania Standard Time", + "Tokyo Standard Time", + "Tonga Standard Time", + "Turkey Standard Time", + "Ulaanbaatar Standard Time", + "US Eastern Standard Time", + "US Mountain Standard Time", "UTC", - "UTC +1", - "UTC +2", - "UTC +3", - "UTC +4", - "UTC +5", - "UTC +6", - "UTC +7", - "UTC +8", - "UTC +9", - "UTC +10", - "UTC +11", - "UTC +12" + "UTC+12", + "UTC-02", + "UTC-11", + "Venezuela Standard Time", + "Vladivostok Standard Time", + "W. Australia Standard Time", + "W. Central Africa Standard Time", + "W. Europe Standard Time", + "West Asia Standard Time", + "West Pacific Standard Time", + "Yakutsk Standard Time" ] } }, @@ -145,6 +233,32 @@ "shutdown_timezone" ] } + }, + { + "if": { + "properties": { + "assign_to_another_user": { + "const": true + } + }, + "required": [ + "assign_to_another_user" + ] + }, + "then": { + "properties": { + "owner_id": { + "type": "string", + "title": "Owner ID", + "description": "Enter the Object ID of the user you want to assign this VM to.", + "default": false, + "updateable": false + } + }, + "required": [ + "owner_id" + ] + } } ], "uiSchema": { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf index daf9bb6..3aa4c0e 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf @@ -3,19 +3,19 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "=3.117.0" + version = "= 3.117.0" } template = { source = "hashicorp/template" - version = "=2.2.0" + version = "= 2.2.0" } random = { source = "hashicorp/random" - version = "=3.4.3" + version = "= 3.7.2" } azuread = { source = "hashicorp/azuread" - version = "3.1.0" + version = "3.3.0" } } backend "azurerm" { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh index 280622c..7f68f1a 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh @@ -6,70 +6,27 @@ set -o nounset # Uncomment this line to see each command for debugging (careful: this will show secrets!) # set -o xtrace -# Remove apt sources not included in sources.list file -sudo rm -f /etc/apt/sources.list.d/* - -# # Fix sources.list file to all be [trusted=yes] -# sudo sed -i 's|\[signed-by=[^]]*\]|[trusted=yes]|g' /etc/apt/sources.list - -# Update apt packages from configured Nexus sources -echo "init_vm.sh: START" -sudo apt update || true -sudo apt upgrade -y -sudo apt install -y gnupg software-properties-common apt-transport-https wget dirmngr gdebi-core debconf-utils -sudo apt-get update || true - -## Desktop -echo "init_vm.sh: Desktop" -sudo systemctl start gdm3 || true -DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true dpkg-reconfigure gdm3 || true -sudo apt install -y xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils -echo /usr/sbin/gdm3 > /etc/X11/default-display-manager - -## Python 3.8 and Jupyter -sudo apt install -y jupyter-notebook microsoft-edge-dev - -# Azure Storage Explorer -sudo apt-get remove -y dotnet-host-7.0 -sudo apt-get remove -y dotnet-sdk-7.0 -sudo apt-get install -y dotnet-sdk-8.0 -sudo apt install gnome-keyring -y - -sudo chmod 666 /etc/profile - -echo "export DOTNET_ROOT=/usr/share/dotnet -export PATH=$PATH:/usr/share/dotnet -" | sudo tee -a /etc/profile - -sudo chmod 644 /etc/profile - -wget -q "${NEXUS_PROXY_URL}"/repository/microsoft-download/A/E/3/AE32C485-B62B-4437-92F7-8B6B2C48CB40/StorageExplorer-linux-x64.tar.gz -P /tmp -sudo mkdir /opt/storage-explorer -sudo tar xvf /tmp/StorageExplorer-linux-x64.tar.gz -C /opt/storage-explorer -sudo chmod +x /opt/storage-explorer/* - -sudo tee /usr/share/applications/storage-explorer.desktop << END -[Desktop Entry] -Name=Storage Explorer -Comment=Azure Storage Explorer -Exec=/opt/storage-explorer/StorageExplorer -Icon=/opt/storage-explorer/resources/app/out/app/icon.png -Terminal=false -Type=Application -StartupNotify=false -StartupWMClass=Code -Categories=Development; -END - - -# Make sure xrdp service starts up with the system -# sudo systemctl enable xrdp - +# --------------------------------------------------------------------------- +# NOTE: The following are pre-configured in the VM image and are NOT repeated here: +# - apt sources (Nexus proxied repositories) +# - Base package installs (gnupg, wget, gdebi-core, etc.) +# - Desktop environment (XFCE, xorg, dbus-x11) +# - Azure Storage Explorer (installed at /opt/storage-explorer with desktop entry) +# - pip (/etc/pip.conf) → Nexus PyPI proxy +# - conda channels → Nexus conda proxy +# - R repo (/etc/R/Rprofile.site) → Nexus R proxy +# - Docker daemon (/etc/docker/daemon.json) → Nexus registry mirror +# - Chrome (replaces Edge) +# - Jupyter (available via VS Code Jupyter extension) +# - xfce4-screensaver disabled via XFCE settings +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# Shared storage mount (per-workspace credentials, autofs/CIFS) +# --------------------------------------------------------------------------- if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then - # Install required packages sudo apt-get install -y autofs cifs-utils - # Pass in required variables storageAccountName="${STORAGE_ACCOUNT_NAME}" storageAccountKey="${STORAGE_ACCOUNT_KEY}" httpEndpoint="${HTTP_ENDPOINT}" @@ -82,13 +39,10 @@ if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then smbPath=$(echo "$httpEndpoint" | cut -c7-"$(expr length "$httpEndpoint")")$fileShareName smbCredentialFile="$credentialRoot/$storageAccountName.cred" - # Create required file paths sudo mkdir -p "$mntPath" sudo mkdir -p "/etc/smbcredentials" sudo mkdir -p $mntRoot - ### Auto FS to persist storage - # Create credential file if [ ! -f "$smbCredentialFile" ]; then echo "username=$storageAccountName" | sudo tee "$smbCredentialFile" > /dev/null echo "password=$storageAccountKey" | sudo tee -a "$smbCredentialFile" > /dev/null @@ -96,66 +50,31 @@ if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then echo "The credential file $smbCredentialFile already exists, and was not modified." fi - # Change permissions on the credential file so only root can read or modify the password file. sudo chmod 600 "$smbCredentialFile" - # Configure autofs echo "$fileShareName -fstype=cifs,rw,file_mode=0777,dir_mode=0777,credentials=$smbCredentialFile :$smbPath" | sudo tee /etc/auto.fileshares > /dev/null echo "$mntRoot /etc/auto.fileshares --timeout=60" | sudo tee /etc/auto.master > /dev/null - # Restart service to register changes sudo systemctl restart autofs - # Autofs mounts when accessed for 60 seconds. Folder created for constant visible mount + # Symlink for constant visible mount point sudo ln -s "$mntPath" "/$fileShareName" fi -# R config -if [ "${R_CONFIG}" == "true" ]; then - sudo echo -e "local({\n r <- getOption(\"repos\")\n r[\"Nexus\"] <- \"""${NEXUS_PROXY_URL}/repository/r-proxy/\"\n options(repos = r)\n})" | sudo tee /etc/R/Rprofile.site -fi - -### Anaconda Config -if [ "${CONDA_CONFIG}" == "true" ]; then - export PATH="/opt/anaconda/condabin":$PATH - export PATH="/opt/anaconda/bin":$PATH - export PATH="/opt/anaconda/envs/py38_default/bin":$PATH - conda config - conda config --add channels "${NEXUS_PROXY_URL}"/repository/conda-mirror/main/ --system - conda config --add channels "${NEXUS_PROXY_URL}"/repository/conda-repo/main/ --system - conda config --remove channels defaults --system - conda config --set channel_alias "${NEXUS_PROXY_URL}"/repository/conda-mirror/ --system -fi - -# Docker config -if [ "${DOCKER_CONFIG}" == "true" ]; then - # Create Docker config directory if it doesn't exist - sudo mkdir -p /etc/docker/ - # Configure Docker registry mirrors - jq -n --arg proxy "${NEXUS_PROXY_URL}:8083" '{"registry-mirrors": [$proxy]}' | sudo tee /etc/docker/daemon.json > /dev/null - # Restart Docker service to apply configuration - sudo systemctl restart docker -fi - -## Prevent screen timeout and lock screen -echo "init_vm.sh: Disabling lock screen" -# Remove xfce4-screensaver (to disable screen saver) -sudo apt-get remove xfce4-screensaver -y - -## Install xrdp so Guacamole can connect via RDP -echo "init_vm.sh: xrdp" -sudo apt install -y xrdp xorgxrdp xfce4-session -sudo adduser xrdp ssl-cert +# --------------------------------------------------------------------------- +# Per-user xrdp / session setup +# --------------------------------------------------------------------------- sudo -u "${VM_USER}" -i bash -c 'echo xfce4-session > ~/.xsession' sudo -u "${VM_USER}" -i bash -c 'echo xset s off >> ~/.xsession' sudo -u "${VM_USER}" -i bash -c 'echo xset -dpms >> ~/.xsession' -# Fix for blank screen on DSVM (/sh -> /bash due to conflict with profile.d scripts) -sudo sed -i 's|!/bin/sh|!/bin/bash|g' /etc/xrdp/startwm.sh - -# Make sure xrdp service starts up with the system sudo systemctl enable xrdp sudo service xrdp restart -## Cleanup -echo "init_vm.sh: Cleanup" +# --------------------------------------------------------------------------- +# Docker — restart to ensure service is running +# daemon.json (Nexus registry mirror) is already written in the image +# --------------------------------------------------------------------------- +if [ "${DOCKER_CONFIG}" == "true" ]; then + sudo systemctl restart docker +fi \ No newline at end of file diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml index 558a0d8..77ad597 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml @@ -1,8 +1,8 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm-ouh2 -version: 1.1.5 -description: "An Azure TRE User Resource Template for Guacamole (Windows 10)" +version: 1.1.6 +description: "An Azure TRE User Resource Template for Guacamole (Windows)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -49,15 +49,14 @@ custom: secure_boot_enabled: true vtpm_enabled: true "OUH Server 2019 Data Science VM": - source_image_name: OUHWindowsImage - install_ui: true + source_image_name: imgdef-windows-vm-custom-gen2 conda_config: true - secure_boot_enabled: false # dsvm-win-2019 is not a gen2 image + # secure_boot and vtpm are disabled because the image was captured from a Standard + # security type build VM. The image definition does not have SecurityType=TrustedLaunchSupported + # and enabling these flags would cause a validation error on deployment. + # Revisit when rebuilding from a Trusted Launch build VM. + secure_boot_enabled: false vtpm_enabled: false - # For information on using custom images, see README.me in the guacamole/user-resources folder - # "Custom Image From Gallery": - # source_image_name: your-image - # conda_config: true credentials: - name: azure_tenant_id @@ -114,7 +113,7 @@ parameters: default: false - name: os_image type: string - default: "Windows 10" + default: "OUH Server 2019 Data Science VM" - name: admin_username type: string default: "" @@ -137,6 +136,19 @@ parameters: - name: key_store_id type: string default: "" + - name: enable_shutdown_schedule + type: boolean + default: false + description: "Enable automatic shutdown schedule for the VM" + - name: shutdown_time + default: "" + type: string + description: "Time of day to shutdown the VM (HHmm format)" + pattern: "^([01]?[0-9]|2[0-3])[0-5][0-9]$" + - name: shutdown_timezone + type: string + description: "Timezone for the shutdown schedule" + default: "UTC" outputs: - name: ip @@ -183,6 +195,9 @@ 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 } + enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } + shutdown_time: ${ bundle.parameters.shutdown_time } + shutdown_timezone: ${ bundle.parameters.shutdown_timezone } owner_id: ${ bundle.parameters.owner_id } enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } @@ -216,6 +231,9 @@ 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 } + enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } + shutdown_time: ${ bundle.parameters.shutdown_time } + shutdown_timezone: ${ bundle.parameters.shutdown_timezone } owner_id: ${ bundle.parameters.owner_id } enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } @@ -261,6 +279,9 @@ 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 } + enable_shutdown_schedule: ${ bundle.parameters.enable_shutdown_schedule } + shutdown_time: ${ bundle.parameters.shutdown_time } + shutdown_timezone: ${ bundle.parameters.shutdown_timezone } owner_id: ${ bundle.parameters.owner_id } enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption } key_store_id: ${ bundle.parameters.key_store_id } @@ -386,4 +407,4 @@ reset_password: - ${ bundle.outputs.vm_password_secret_name } - ${ bundle.outputs.keyvault_name } - ${ bundle.outputs.vm_username } - - ${ bundle.outputs.azure_resource_id } + - ${ bundle.outputs.azure_resource_id } \ No newline at end of file diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/template_schema.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/template_schema.json index 4816993..c75cbc4 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/template_schema.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/template_schema.json @@ -7,7 +7,8 @@ "required": [ ], "authorizedRoles": [ - "WorkspaceOwner", "WorkspaceResearcher" + "WorkspaceOwner", + "WorkspaceResearcher" ], "properties": { "display_name": { @@ -70,16 +71,199 @@ "updateable": true }, "shared_storage_access": { - "$id": "#/properties/shared_storage_access", - "type": "boolean", - "title": "Shared storage", - "default": true, - "description": "Enable access to shared storage" + "$id": "#/properties/shared_storage_access", + "type": "boolean", + "title": "Shared storage", + "default": true, + "description": "Enable access to shared storage" + }, + "enable_shutdown_schedule": { + "$id": "#/properties/enable_shutdown_schedule", + "type": "boolean", + "title": "Enable Shutdown Schedule", + "default": false, + "description": "Enable automatic shutdown schedule for the VM" + }, + "assign_to_another_user": { + "type": "boolean", + "title": "Assign this VM to another user", + "description": "Check this box if you want to assign this VM to another user.", + "default": false, + "updateable": false + } + }, + "allOf": [ + { + "if": { + "properties": { + "enable_shutdown_schedule": { + "const": true + } + }, + "required": [ + "enable_shutdown_schedule" + ] + }, + "then": { + "properties": { + "shutdown_time": { + "type": "string", + "title": "Shutdown Time", + "description": "Time of day to shutdown the VM (HHmm format), e.g. 1800", + "pattern": "^([01]?[0-9]|2[0-3])[0-5][0-9]$", + "default": "1800" + }, + "shutdown_timezone": { + "type": "string", + "title": "Shutdown Timezone", + "description": "Timezone for the shutdown schedule", + "default": "UTC", + "enum": [ + "Afghanistan Standard Time", + "Alaskan Standard Time", + "Arab Standard Time", + "Arabian Standard Time", + "Arabic Standard Time", + "Argentina Standard Time", + "Atlantic Standard Time", + "AUS Central Standard Time", + "AUS Eastern Standard Time", + "Azerbaijan Standard Time", + "Azores Standard Time", + "Bahia Standard Time", + "Bangladesh Standard Time", + "Belarus Standard Time", + "Canada Central Standard Time", + "Cape Verde Standard Time", + "Caucasus Standard Time", + "Cen. Australia Standard Time", + "Central America Standard Time", + "Central Asia Standard Time", + "Central Brazilian Standard Time", + "Central Europe Standard Time", + "Central European Standard Time", + "Central Pacific Standard Time", + "Central Standard Time (Mexico)", + "Central Standard Time", + "China Standard Time", + "Dateline Standard Time", + "E. Africa Standard Time", + "E. Australia Standard Time", + "E. Europe Standard Time", + "E. South America Standard Time", + "Eastern Standard Time (Mexico)", + "Eastern Standard Time", + "Egypt Standard Time", + "Ekaterinburg Standard Time", + "Fiji Standard Time", + "FLE Standard Time", + "Georgian Standard Time", + "GMT Standard Time", + "Greenland Standard Time", + "Greenwich Standard Time", + "GTB Standard Time", + "Hawaiian Standard Time", + "India Standard Time", + "Iran Standard Time", + "Israel Standard Time", + "Jordan Standard Time", + "Kaliningrad Standard Time", + "Korea Standard Time", + "Libya Standard Time", + "Line Islands Standard Time", + "Magadan Standard Time", + "Mauritius Standard Time", + "Middle East Standard Time", + "Montevideo Standard Time", + "Morocco Standard Time", + "Mountain Standard Time (Mexico)", + "Mountain Standard Time", + "Myanmar Standard Time", + "N. Central Asia Standard Time", + "Namibia Standard Time", + "Nepal Standard Time", + "New Zealand Standard Time", + "Newfoundland Standard Time", + "North Asia East Standard Time", + "North Asia Standard Time", + "Pacific SA Standard Time", + "Pacific Standard Time (Mexico)", + "Pacific Standard Time", + "Pakistan Standard Time", + "Paraguay Standard Time", + "Romance Standard Time", + "Russia Time Zone 10", + "Russia Time Zone 11", + "Russia Time Zone 3", + "Russian Standard Time", + "SA Eastern Standard Time", + "SA Pacific Standard Time", + "SA Western Standard Time", + "Samoa Standard Time", + "SE Asia Standard Time", + "Singapore Standard Time", + "South Africa Standard Time", + "Sri Lanka Standard Time", + "Syria Standard Time", + "Taipei Standard Time", + "Tasmania Standard Time", + "Tokyo Standard Time", + "Tonga Standard Time", + "Turkey Standard Time", + "Ulaanbaatar Standard Time", + "US Eastern Standard Time", + "US Mountain Standard Time", + "UTC", + "UTC+12", + "UTC-02", + "UTC-11", + "Venezuela Standard Time", + "Vladivostok Standard Time", + "W. Australia Standard Time", + "W. Central Africa Standard Time", + "W. Europe Standard Time", + "West Asia Standard Time", + "West Pacific Standard Time", + "Yakutsk Standard Time" + ] + } + }, + "required": [ + "shutdown_time", + "shutdown_timezone" + ] } }, - "uiSchema": { + { + "if": { + "properties": { + "assign_to_another_user": { + "const": true + } + }, + "required": [ + "assign_to_another_user" + ] + }, + "then": { + "properties": { + "owner_id": { + "type": "string", + "title": "Owner ID", + "description": "Enter the Object ID of the user you want to assign this VM to.", + "default": false, + "updateable": false + } + }, + "required": [ + "owner_id" + ] + } + } + ], + "uiSchema": { "admin_username": { "classNames": "tre-hidden" } - } + } } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf index 0d9ac14..3036251 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf @@ -7,11 +7,11 @@ terraform { } random = { source = "hashicorp/random" - version = "=3.5.1" + version = "= 3.7.2" } azuread = { source = "hashicorp/azuread" - version = "3.1.0" + version = "= 3.3.0" } } backend "azurerm" { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/variables.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/variables.tf index 82c3403..871fa39 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/variables.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/variables.tf @@ -26,6 +26,17 @@ variable "image_gallery_id" { type = string default = "" } +variable "enable_shutdown_schedule" { + type = bool + default = false +} +variable "shutdown_time" { + type = string +} +variable "shutdown_timezone" { + type = string + default = "UTC" +} variable "owner_id" { type = string } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/vm_config.ps1 b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/vm_config.ps1 index aa82710..c0afcae 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/vm_config.ps1 +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/vm_config.ps1 @@ -1,59 +1,19 @@ -Remove-Item -LiteralPath "C:\AzureData" -Force -Recurse $ErrorActionPreference = "Stop" -if( ${SharedStorageAccess} -eq 1 ) -{ - $Command = "net use z: \\${StorageAccountFileHost}\${FileShareName} /u:AZURE\${StorageAccountName} ${StorageAccountKey}" - $Command | Out-File "C:\ProgramData\Start Menu\Programs\StartUp\attach_storage.cmd" -encoding ascii -} - -$PipConfigFolderPath = "C:\ProgramData\pip\" -If(!(Test-Path $PipConfigFolderPath)) -{ - New-Item -ItemType Directory -Force -Path $PipConfigFolderPath -} - -$PipConfigFilePath = $PipConfigFolderPath + "pip.ini" - -$ConfigBody = @" -[global] -index = ${nexus_proxy_url}/repository/pypi/pypi -index-url = ${nexus_proxy_url}/repository/pypi/simple -trusted-host = ${nexus_proxy_url} -"@ - -# We need to write the ini file in UTF8 (No BOM) as pip won't understand Powershell's default encoding (unicode) -$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False -[System.IO.File]::WriteAllLines($PipConfigFilePath, $ConfigBody, $Utf8NoBomEncoding) - -### Anaconda Config -if( ${CondaConfig} -eq 1 ) -{ - conda config --add channels ${nexus_proxy_url}/repository/conda-mirror/main/ --system - conda config --add channels ${nexus_proxy_url}/repository/conda-repo/main/ --system - conda config --remove channels defaults --system - conda config --set channel_alias ${nexus_proxy_url}/repository/conda-mirror/ --system -} - -# Docker proxy config -$DaemonConfig = @" -{ -"registry-mirrors": ["${nexus_proxy_url}:8083"] -} -"@ -$DaemonConfig | Out-File -Encoding Ascii ( New-Item -Path $env:ProgramData\docker\config\daemon.json -Force ) - -# R config -# $RconfigFilePathWindows = C:\Progra~1\R\4.1.2\etc\Rprofile.site -#Add-Content $RconfigFilePathWindows "local({`n r <- getOption(`"repos`")`n r[`"Nexus`"] <- `"${nexus_proxy_url}/repository/r-proxy/`"`n options(repos = r)`n})" -# echo "local({`n r <- getOption(`"repos`")`n r[`"Nexus`"] <- `"${nexus_proxy_url}/repository/r-proxy/`"`n options(repos = r)`n})" > $RconfigFilePathWindows -$RConfig = @" -local({ - r <- getOption("repos") - r["Nexus"] <- "${nexus_proxy_url}/repository/r-proxy/" - options(repos = r) -}) - -Sys.setenv(R_LIBCURL_SSL_REVOKE_BEST_EFFORT=TRUE) -"@ -$RConfig | Out-File -Encoding Ascii ( New-Item -Path $Env:C:\Software\R\etc\Rprofile.site -Force ) +# --------------------------------------------------------------------------- +# NOTE: The following are pre-configured in the VM image and are NOT repeated here: +# - pip (C:\ProgramData\pip\pip.ini) → Nexus PyPI proxy +# - conda (system .condarc) → Nexus conda proxy +# - R (Rprofile.site, wininet method) → Nexus R proxy +# - Anaconda PATH set at Machine scope → C:\tools\Anaconda3 +# - Docker not installed (WSL2/Hyper-V incompatible with Windows Server 2019) +# --------------------------------------------------------------------------- + +# Remove Azure provisioning artefact +Remove-Item -LiteralPath "C:\AzureData" -Force -Recurse -ErrorAction SilentlyContinue + +# Shared storage — write a startup script that maps the share at logon +if ( ${SharedStorageAccess} -eq 1 ) { + $Command = "net use z: \\${StorageAccountFileHost}\${FileShareName} /u:AZURE\${StorageAccountName} ${StorageAccountKey}" + $Command | Out-File "C:\ProgramData\Start Menu\Programs\StartUp\attach_storage.cmd" -Encoding Ascii +} \ No newline at end of file diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/windowsvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/windowsvm.tf index 21d76f9..6a9e90c 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/windowsvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/windowsvm.tf @@ -128,4 +128,17 @@ resource "azurerm_key_vault_secret" "windowsvm_password" { tags = local.tre_user_resources_tags lifecycle { ignore_changes = [tags] } +} + +resource "azurerm_dev_test_global_vm_shutdown_schedule" "shutdown_schedule" { + count = var.enable_shutdown_schedule ? 1 : 0 + + location = data.azurerm_resource_group.ws.location + virtual_machine_id = azurerm_windows_virtual_machine.windowsvm.id + daily_recurrence_time = var.shutdown_time + timezone = var.shutdown_timezone + enabled = var.enable_shutdown_schedule + notification_settings { + enabled = false + } } \ No newline at end of file From 3099b9cc6c995da23f9e7de6edfe2b51309810b0 Mon Sep 17 00:00:00 2001 From: Jaimie Withers Date: Thu, 12 Mar 2026 12:55:45 +0000 Subject: [PATCH 04/26] Add in new tag version v0.25.0 --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 971ed60..c365424 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.23.1", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.0", "GITHUB_TOKEN": "" } }, From ab8c1f53e46c897fc1c7f513a67b81e67b7f4bbf Mon Sep 17 00:00:00 2001 From: Jaimie Date: Fri, 13 Mar 2026 10:29:04 +0000 Subject: [PATCH 05/26] Update terraform lock files --- config.sample.yaml | 3 ++ .../terraform/.terraform.lock.hcl | 48 +++++++++++++------ .../terraform/.terraform.lock.hcl | 48 +++++++++++++------ 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/config.sample.yaml b/config.sample.yaml index ccac3d2..1d27f4a 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -68,6 +68,9 @@ tre: # Uncomment to deploy to a custom domain # custom_domain: __CHANGE_ME__ + + # Uncomment to enable vnet exception for the subnet to access private resources like TRE key vault and management storage account. + # private_agent_subnet_id: __CHANGE_ME__ authentication: aad_tenant_id: __CHANGE_ME__ # Setting AUTO_WORKSPACE_APP_REGISTRATION to false will: diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl index 2724e7a..808d125 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl @@ -1,6 +1,26 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/hashicorp/azuread" { + version = "3.3.0" + constraints = "3.3.0" + hashes = [ + "h1:CmjUkS5xnsVJ6QHzooWNYg2iowb++EcGIWSCoMiUlbM=", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:2cb6dcfa5a3fd04f14b1976455b73f14a15f9f45069fa5fa198f87625df5751a", + "zh:3de1c29f4eb1a176a7f3039a470f26281228f9527a81ebedb86820dd9d5b0007", + "zh:498ef951e158caf10365b39cd95789f5a034c3ef6fca288b37520af0cc2f81e5", + "zh:7b8c8bda91a2b28b9371ac60c2c87a3967d0ca232ab868203062599fca4c832f", + "zh:9b109748e2ccad027d710548491bc8cc0399b69a9b779ac59d53745a95129e3a", + "zh:9d38831a614f67e09ca4bf2377a06e6dda9130a60437f4d73aa422d982b9f17f", + "zh:b6fa6920334e7495118784d15500d676fda4e9c924a03fb5e333faf6646fd15f", + "zh:c01171e3c1b1a6bcc9516f5fc44e4880c67a30541ae66ecf18d3aa0eb92457ad", + "zh:cd3bda1e87953a5288808a10ca9383baa14b4dee623e21a43048f95179bf0323", + "zh:df06f222c38fc37a074e00650e7699927b11a64b1f4170bfa7d823029662a778", + "zh:df502d004558a92808450fc9a7b6f17700d918e3037d21cba73d61e56466e785", + ] +} + provider "registry.terraform.io/hashicorp/azurerm" { version = "3.117.0" constraints = "3.117.0" @@ -22,22 +42,22 @@ provider "registry.terraform.io/hashicorp/azurerm" { } provider "registry.terraform.io/hashicorp/random" { - version = "3.4.3" - constraints = "3.4.3" + version = "3.7.2" + constraints = "3.7.2" hashes = [ - "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=", - "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752", - "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b", - "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53", + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3", - "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5", - "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda", - "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6", - "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1", - "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d", - "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8", - "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl index 37741e4..af6c704 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl @@ -1,6 +1,26 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/hashicorp/azuread" { + version = "3.3.0" + constraints = "3.3.0" + hashes = [ + "h1:CmjUkS5xnsVJ6QHzooWNYg2iowb++EcGIWSCoMiUlbM=", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:2cb6dcfa5a3fd04f14b1976455b73f14a15f9f45069fa5fa198f87625df5751a", + "zh:3de1c29f4eb1a176a7f3039a470f26281228f9527a81ebedb86820dd9d5b0007", + "zh:498ef951e158caf10365b39cd95789f5a034c3ef6fca288b37520af0cc2f81e5", + "zh:7b8c8bda91a2b28b9371ac60c2c87a3967d0ca232ab868203062599fca4c832f", + "zh:9b109748e2ccad027d710548491bc8cc0399b69a9b779ac59d53745a95129e3a", + "zh:9d38831a614f67e09ca4bf2377a06e6dda9130a60437f4d73aa422d982b9f17f", + "zh:b6fa6920334e7495118784d15500d676fda4e9c924a03fb5e333faf6646fd15f", + "zh:c01171e3c1b1a6bcc9516f5fc44e4880c67a30541ae66ecf18d3aa0eb92457ad", + "zh:cd3bda1e87953a5288808a10ca9383baa14b4dee623e21a43048f95179bf0323", + "zh:df06f222c38fc37a074e00650e7699927b11a64b1f4170bfa7d823029662a778", + "zh:df502d004558a92808450fc9a7b6f17700d918e3037d21cba73d61e56466e785", + ] +} + provider "registry.terraform.io/hashicorp/azurerm" { version = "3.117.0" constraints = "3.117.0" @@ -22,21 +42,21 @@ provider "registry.terraform.io/hashicorp/azurerm" { } provider "registry.terraform.io/hashicorp/random" { - version = "3.5.1" - constraints = "3.5.1" + version = "3.7.2" + constraints = "3.7.2" hashes = [ - "h1:VSnd9ZIPyfKHOObuQCaKfnjIHRtR7qTw19Rz8tJxm+k=", - "zh:04e3fbd610cb52c1017d282531364b9c53ef72b6bc533acb2a90671957324a64", - "zh:119197103301ebaf7efb91df8f0b6e0dd31e6ff943d231af35ee1831c599188d", - "zh:4d2b219d09abf3b1bb4df93d399ed156cadd61f44ad3baf5cf2954df2fba0831", - "zh:6130bdde527587bbe2dcaa7150363e96dbc5250ea20154176d82bc69df5d4ce3", - "zh:6cc326cd4000f724d3086ee05587e7710f032f94fc9af35e96a386a1c6f2214f", + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:b6d88e1d28cf2dfa24e9fdcc3efc77adcdc1c3c3b5c7ce503a423efbdd6de57b", - "zh:ba74c592622ecbcef9dc2a4d81ed321c4e44cddf7da799faa324da9bf52a22b2", - "zh:c7c5cde98fe4ef1143bd1b3ec5dc04baf0d4cc3ca2c5c7d40d17c0e9b2076865", - "zh:dac4bad52c940cd0dfc27893507c1e92393846b024c5a9db159a93c534a3da03", - "zh:de8febe2a2acd9ac454b844a4106ed295ae9520ef54dc8ed2faf29f12716b602", - "zh:eab0d0495e7e711cca367f7d4df6e322e6c562fc52151ec931176115b83ed014", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", ] } From a702521bb5adee283a12c0234de0e7d82330d814 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Fri, 13 Mar 2026 10:32:24 +0000 Subject: [PATCH 06/26] lint updates --- .../user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml | 2 +- .../user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index 2d313a5..b77f408 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -410,4 +410,4 @@ reset_password: - ${ bundle.outputs.vm_password_secret_name } - ${ bundle.outputs.keyvault_name } - ${ bundle.outputs.vm_username } - - ${ bundle.outputs.azure_resource_id } \ No newline at end of file + - ${ bundle.outputs.azure_resource_id } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml index 77ad597..248f662 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml @@ -407,4 +407,4 @@ reset_password: - ${ bundle.outputs.vm_password_secret_name } - ${ bundle.outputs.keyvault_name } - ${ bundle.outputs.vm_username } - - ${ bundle.outputs.azure_resource_id } \ No newline at end of file + - ${ bundle.outputs.azure_resource_id } From 038ba541d04658d3f1cd753859bbf4c67c0c6336 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Fri, 13 Mar 2026 10:38:33 +0000 Subject: [PATCH 07/26] Lint update --- vm-images/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm-images/README.md b/vm-images/README.md index 6dd0b56..1dd7b52 100644 --- a/vm-images/README.md +++ b/vm-images/README.md @@ -1,7 +1,7 @@ -This process is being replaced - ReadMe will remain but may be archived. - # Custom Virtual Machine Images +**This process is being replaced - ReadMe will remain but may be archived.** + This folder contains files that deploy the infrastructre used to create and publish custom virtual machine (VM) images in Azure. ## Folder Structure From 9c518b2aa5053295288c8b0615c2fe68489996d1 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Fri, 13 Mar 2026 12:39:10 +0000 Subject: [PATCH 08/26] Hot fix upgrade to 25.1 --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c365424..e5e4b53 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.0", + "UPSTREAM_REPO_VERSION": "tvstre-v0.25.1", "GITHUB_TOKEN": "" } }, From fdc2d0f9961053af50454dad3b7ad3e328e82f80 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Fri, 13 Mar 2026 15:52:18 +0000 Subject: [PATCH 09/26] Update with required rp version --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e5e4b53..862d6b6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-v0.25.1", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.2", "GITHUB_TOKEN": "" } }, From adda2e6c98958f64ff92227262ab7b56fe37a2c6 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Mon, 16 Mar 2026 11:55:56 +0000 Subject: [PATCH 10/26] bump UPSTREAM_REPO_VERSION to tvstre-prod-main-v0.25.3 --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 862d6b6..5ae9973 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.2", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.3", "GITHUB_TOKEN": "" } }, From fcf183533fd5dbfbb69e0720bfb2760adf38e650 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Mon, 16 Mar 2026 13:34:08 +0000 Subject: [PATCH 11/26] Update to 25.4 for required updates --- .devcontainer/devcontainer.json | 2 +- .../user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml | 6 +++--- .../guacamole-azure-windowsvm-ouh2/porter.yaml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5ae9973..38443ad 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.3", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.4", "GITHUB_TOKEN": "" } }, diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index b77f408..a2ab51d 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -326,7 +326,7 @@ start: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - az: description: "Start the VM" arguments: @@ -362,7 +362,7 @@ stop: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - az: description: "Stop the VM" arguments: @@ -401,7 +401,7 @@ reset_password: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - exec: description: "Reset password and persist to keyvault" suppress-output: true diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml index 248f662..845c3c8 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml @@ -323,7 +323,7 @@ start: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - az: description: "Start the VM" arguments: @@ -359,7 +359,7 @@ stop: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - az: description: "Stop the VM" arguments: @@ -398,7 +398,7 @@ reset_password: - login flags: identity: - username: ${ bundle.credentials.azure_client_id } + client-id: ${ bundle.credentials.azure_client_id } - exec: description: "Reset password and persist to keyvault" suppress-output: true From 7579fc32ad1b302c38ade008d54d597a2412fa6c Mon Sep 17 00:00:00 2001 From: Jaimie Date: Mon, 16 Mar 2026 14:53:50 +0000 Subject: [PATCH 12/26] fix: install yarn explicitly as it was removed from base devcontainer image --- .devcontainer/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ce8b76d..f0a55f2 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -87,6 +87,9 @@ RUN curl -L --fail -o /tmp/azcopy.tar.gz "https://aka.ms/downloadazcopy-v10-linu ARG PAJV_VERSION="1.2.0" RUN npm install -g pajv@${PAJV_VERSION} +# Install yarn (removed from base image) +RUN npm install -g yarn + # Install git - required for terraform's git modules RUN if [ "${INTERACTIVE}" = "false" ]; then \ apt-get update && apt-get install --no-install-recommends -y git \ From 584e6e9afae63fc7a7d474d29ab60eb4a7cd1218 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Mon, 16 Mar 2026 14:58:16 +0000 Subject: [PATCH 13/26] pin yarn version and lint error fix --- .devcontainer/Dockerfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f0a55f2..ec3e945 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -85,10 +85,8 @@ RUN curl -L --fail -o /tmp/azcopy.tar.gz "https://aka.ms/downloadazcopy-v10-linu && chmod +x /usr/local/bin/azcopy ARG PAJV_VERSION="1.2.0" -RUN npm install -g pajv@${PAJV_VERSION} - -# Install yarn (removed from base image) -RUN npm install -g yarn +RUN npm install -g pajv@${PAJV_VERSION} \ + && npm install -g yarn@1.22.22 # Install git - required for terraform's git modules RUN if [ "${INTERACTIVE}" = "false" ]; then \ From 003c80105148778a5553ea80bfc75bdd0f83eccc Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 08:29:35 +0000 Subject: [PATCH 14/26] fix: hashicorp/template to cloudinit provider, update provider versions and Terraform/Azure CLI versions --- .devcontainer/devcontainer.json | 2 +- .../guacamole-azure-linuxvm-ouh2/porter.yaml | 8 +- .../terraform/.terraform.lock.hcl | 106 ++++++++---------- .../terraform/data.tf | 24 +--- .../terraform/linuxvm.tf | 30 +---- .../terraform/locals.tf | 27 +++++ .../terraform/main.tf | 12 +- .../terraform/vm_config.sh | 4 +- .../porter.yaml | 10 +- .../terraform/.terraform.lock.hcl | 58 +++++----- .../terraform/main.tf | 11 +- 11 files changed, 129 insertions(+), 163 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 38443ad..eed7dd5 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.4", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.5", "GITHUB_TOKEN": "" } }, diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index a2ab51d..0f671eb 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm-ouh2 -version: 1.1.9 +version: 1.1.10 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -99,7 +99,7 @@ parameters: default: "" type: string description: "Time of day to shutdown the VM (HHmm format)" - pattern: "^([01]?[0-9]|2[0-3])[0-5][0-9]$" + pattern: "^([01]?[0-9]|2[0-3])[0-5][0-9]?$" - name: shutdown_timezone type: string description: "Timezone for the shutdown schedule" @@ -180,9 +180,9 @@ outputs: mixins: - exec - terraform: - clientVersion: 1.9.8 + clientVersion: 1.14.3 - az: - clientVersion: 2.67.0 + clientVersion: 2.81.0 install: - terraform: diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl index 808d125..a4e9591 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/.terraform.lock.hcl @@ -2,79 +2,61 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azuread" { - version = "3.3.0" - constraints = "3.3.0" + version = "3.7.0" + constraints = "3.7.0" hashes = [ - "h1:CmjUkS5xnsVJ6QHzooWNYg2iowb++EcGIWSCoMiUlbM=", + "h1:xUoYzyYNcneRJDN8rlJ4tT+ZjebaDqvuNm6eMxKCeX4=", + "zh:01114beb07eb8415a563ca80a513e7fd11fd6f0670bdd960e9092e58464ab2b7", + "zh:1460c790ca28cc11c3efd4abec076fc5cdd4ae1cc654a45c69e10ca064e0a611", + "zh:161b6dd82cf279e7ac7a31c404f2ace491a5a9e7ec382ace91de2fd18f8c190b", "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", - "zh:2cb6dcfa5a3fd04f14b1976455b73f14a15f9f45069fa5fa198f87625df5751a", - "zh:3de1c29f4eb1a176a7f3039a470f26281228f9527a81ebedb86820dd9d5b0007", - "zh:498ef951e158caf10365b39cd95789f5a034c3ef6fca288b37520af0cc2f81e5", - "zh:7b8c8bda91a2b28b9371ac60c2c87a3967d0ca232ab868203062599fca4c832f", - "zh:9b109748e2ccad027d710548491bc8cc0399b69a9b779ac59d53745a95129e3a", - "zh:9d38831a614f67e09ca4bf2377a06e6dda9130a60437f4d73aa422d982b9f17f", - "zh:b6fa6920334e7495118784d15500d676fda4e9c924a03fb5e333faf6646fd15f", - "zh:c01171e3c1b1a6bcc9516f5fc44e4880c67a30541ae66ecf18d3aa0eb92457ad", - "zh:cd3bda1e87953a5288808a10ca9383baa14b4dee623e21a43048f95179bf0323", - "zh:df06f222c38fc37a074e00650e7699927b11a64b1f4170bfa7d823029662a778", - "zh:df502d004558a92808450fc9a7b6f17700d918e3037d21cba73d61e56466e785", + "zh:2eff0bea92c48be0221863ebf7752f491232088f4ec3cbe4da2ebf9f478fed1f", + "zh:69a689198fcac054da30fea6a8abce2f12b667f6f327c9bb388f2c307ee782fd", + "zh:6f5acf42d71a2f5157c54e67b2db9b080c4ebb27b812112c0c84241e66d94803", + "zh:8e0a58ff2c21aff372c66c679db48578be48e99f5cf6727f082cf4b629dbda6c", + "zh:9c88cc06ba7ee1f6e6b43af7e223c4d107fb77e5a984f1441fffb00c3693537f", + "zh:e8656e8143baac71029857c72899f8503cede41f2559c89ce29d21c0436c96fc", + "zh:e8e21913956a3f043c0e65cc95278bdc82f62ff33fd75a56b1919bd63fd14f8a", + "zh:f7f213dd61d1c75b8397d97660cf329870a241e88ec6e0dc07c60725d975252e", ] } provider "registry.terraform.io/hashicorp/azurerm" { - version = "3.117.0" - constraints = "3.117.0" + version = "4.57.0" + constraints = "4.57.0" hashes = [ - "h1:Ynfg+Iy7x6K8M6W1AhqXCe3wkoiqIQhROlca7C3KC3w=", - "zh:2e25f47492366821a786762369f0e0921cc9452d64bfd5075f6fdfcf1a9c6d70", - "zh:41eb34f2f7469bf3eb1019dfb0e7fc28256f809824016f4f8b9d691bf473b2ac", - "zh:48bb9c87b3d928da1abc1d3db75453c9725de4674c612daf3800160cc7145d30", - "zh:5d6b0de0bbd78943fcc65c53944ef4496329e247f434c6eab86ed051c5cea67b", - "zh:78c9f6fdb1206a89cf0e6706b4f46178169a93b6c964a4cad8a321058ccbd9b4", - "zh:793b702c352589d4360b580d4a1cf654a7439d2ad6bdb7bfea91de07bc4b0fac", - "zh:7ed687ff0a5509463a592f97431863574fe5cc80a34e395be06766215b8c6285", - "zh:955ba18789bd15592824eb426a8d0f38595bd09fffc6939c1c58933489c1a71e", - "zh:bf5949a55be0714cd9c8815d472eae4baa48ba06d0f6bf2b96775869acda8a54", - "zh:da5d31f635abd2c645ffc76d6176d73f646128e73720cc368247cc424975c127", - "zh:eed5a66d59883c9c56729b0a964a2b60d758ea7489ef3e920a6fbd48518ce5f5", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - ] -} - -provider "registry.terraform.io/hashicorp/random" { - version = "3.7.2" - constraints = "3.7.2" - hashes = [ - "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", - "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", - "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", - "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", - "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", - "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", - "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "h1:NhgHn/RyZRDXMa7pEQlGv/9B+wjk48E+lvgq4asFKHs=", + "zh:05e1cc7fee7829919b772ca6ce893d9c2abb3535ebff172df38f7358cdaf8f9e", + "zh:30122203abc381660582f989c9e53874bd9ff93e25476a5536ea0ae37dd51f4b", + "zh:4a90f008f7707d95f8f9aca90f140a9ca0e9506b0a6d436fe516de4026cacd86", + "zh:6d9e114b8aed06454b71fe91a0591cc6a16cd7acde3cb36a96e4aeaec06a315a", + "zh:7145c50facd9d40615fc63561ec21962feae3fa262239f9f1f1339581226104b", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", - "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", - "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", - "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", - "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + "zh:95f60557f1bc4210ecc3c11e2f86fe983ed7e4af19036616b605887c1195f2ac", + "zh:9722b3ab879a3457588af5f0dcd65e997263affe4b829e60ecd59dbef6239e70", + "zh:b891f295b018d058e8c6f841d923d5b30ba13b8208f2c20aacc70ba48c5cc0da", + "zh:cb7ff113ca0bd91ab76f9f7a492d6ce9c911d6c4deb8c8e263e38322b5ff861e", + "zh:ec2950bf003d29bee3fa87ab073d57fe14a4da52e9fc646fec27798b700cc8af", + "zh:f69899d9e1d570a560cfa97aebec3edc2b106f2ebc15dfdee473294dd8756deb", ] } -provider "registry.terraform.io/hashicorp/template" { - version = "2.2.0" - constraints = "2.2.0" +provider "registry.terraform.io/hashicorp/cloudinit" { + version = "2.3.5" + constraints = "2.3.5" hashes = [ - "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=", - "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386", - "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53", - "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603", - "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16", - "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776", - "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451", - "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae", - "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde", - "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d", - "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2", + "h1:HCoabXm6NQwCivl1q24+l9VUufc2mFqNeulsQBA9iFg=", + "zh:17c20574de8eb925b0091c9b6a4d859e9d6e399cd890b44cfbc028f4f312ac7a", + "zh:348664d9a900f7baf7b091cf94d657e4c968b240d31d9e162086724e6afc19d5", + "zh:5a876a468ffabff0299f8348e719cb704daf81a4867f8c6892f3c3c4add2c755", + "zh:6ef97ee4c8c6a69a3d36746ba5c857cf4f4d78f32aa3d0e1ce68f2ece6a5dba5", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:8283e5a785e3c518a440f6ac6e7cc4fc07fe266bf34974246f4e2ef05762feda", + "zh:a44eb5077950168b571b7eb65491246c00f45409110f0f172cc3a7605f19dba9", + "zh:aa0806cbff72b49c1b389c0b8e6904586e5259c08dabb7cb5040418568146530", + "zh:bec4613c3beaad9a7be7ca99cdb2852073f782355b272892e6ee97a22856aec1", + "zh:d7fe368577b6c8d1ae44c751ed42246754c10305c7f001cc0109833e95aa107d", + "zh:df2409fc6a364b1f0a0f8a9cd8a86e61e80307996979ce3790243c4ce88f2915", + "zh:ed3c263396ff1f4d29639cc43339b655235acf4d06296a7c120a80e4e0fd6409", ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/data.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/data.tf index 07b1b70..cd3162a 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/data.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/data.tf @@ -44,28 +44,6 @@ data "azurerm_user_assigned_identity" "ws_encryption_identity" { resource_group_name = data.azurerm_resource_group.ws.name } -data "template_file" "get_apt_keys" { - template = file("${path.module}/get_apt_keys.sh") - vars = { - NEXUS_PROXY_URL = local.nexus_proxy_url - } -} - -data "template_file" "pypi_sources_config" { - template = file("${path.module}/pypi_sources_config.sh") - vars = { - nexus_proxy_url = local.nexus_proxy_url - } -} - -data "template_file" "apt_sources_config" { - template = file("${path.module}/apt_sources_config.yml") - vars = { - nexus_proxy_url = local.nexus_proxy_url - apt_sku = local.apt_sku - } -} - data "azurerm_storage_account" "stg" { name = local.storage_name resource_group_name = data.azurerm_resource_group.ws.name @@ -74,4 +52,4 @@ data "azurerm_storage_account" "stg" { data "azuread_user" "user" { object_id = var.owner_id count = var.admin_username == "" ? 1 : 0 -} \ No newline at end of file +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/linuxvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/linuxvm.tf index b876291..2606c6e 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/linuxvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/linuxvm.tf @@ -37,7 +37,7 @@ resource "azurerm_linux_virtual_machine" "linuxvm" { secure_boot_enabled = local.secure_boot_enabled vtpm_enabled = local.vtpm_enabled - custom_data = data.template_cloudinit_config.config.rendered + custom_data = data.cloudinit_config.config.rendered # set source_image_id/reference depending on the config for the selected image source_image_id = local.selected_image_source_id @@ -91,46 +91,28 @@ resource "azurerm_disk_encryption_set" "linuxvm_disk_encryption" { } } -data "template_cloudinit_config" "config" { +data "cloudinit_config" "config" { gzip = true base64_encode = true part { content_type = "text/x-shellscript" - content = data.template_file.get_apt_keys.rendered + content = local.get_apt_keys_content } part { content_type = "text/cloud-config" - content = data.template_file.apt_sources_config.rendered + content = local.apt_sources_config_content } part { content_type = "text/x-shellscript" - content = data.template_file.pypi_sources_config.rendered + content = local.pypi_sources_config_content } part { content_type = "text/x-shellscript" - content = data.template_file.vm_config.rendered - } -} - -data "template_file" "vm_config" { - template = file("${path.module}/vm_config.sh") - vars = { - INSTALL_UI = local.selected_image.install_ui ? 1 : 0 - SHARED_STORAGE_ACCESS = tobool(var.shared_storage_access) ? 1 : 0 - STORAGE_ACCOUNT_NAME = data.azurerm_storage_account.stg.name - STORAGE_ACCOUNT_KEY = data.azurerm_storage_account.stg.primary_access_key - HTTP_ENDPOINT = data.azurerm_storage_account.stg.primary_file_endpoint - FILESHARE_NAME = var.shared_storage_access ? var.shared_storage_name : "" - NEXUS_PROXY_URL = local.nexus_proxy_url - CONDA_CONFIG = local.selected_image.conda_config ? 1 : 0 - R_CONFIG = local.selected_image.r_config ? 1 : 0 - DOCKER_CONFIG = local.selected_image.docker_config ? 1 : 0 - VM_USER = local.admin_username - APT_SKU = replace(local.apt_sku, ".", "") + content = local.vm_config_content } } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/locals.tf index 6e41e82..11c702e 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/locals.tf @@ -40,4 +40,31 @@ locals { apt_sku = length(local.selected_image_source_refs) > 0 ? local.selected_image_source_refs[0]["apt_sku"] : "22.04" cmk_name = "tre-encryption-${local.workspace_resource_name_suffix}" encryption_identity_name = "id-encryption-${var.tre_id}-${local.short_workspace_id}" + + get_apt_keys_content = templatefile("${path.module}/get_apt_keys.sh", { + NEXUS_PROXY_URL = local.nexus_proxy_url + }) + + pypi_sources_config_content = templatefile("${path.module}/pypi_sources_config.sh", { + nexus_proxy_url = local.nexus_proxy_url + }) + + apt_sources_config_content = templatefile("${path.module}/apt_sources_config.yml", { + nexus_proxy_url = local.nexus_proxy_url + apt_sku = local.apt_sku + }) + + vm_config_content = templatefile("${path.module}/vm_config.sh", { + INSTALL_UI = local.selected_image.install_ui ? 1 : 0 + SHARED_STORAGE_ACCESS = tobool(var.shared_storage_access) ? 1 : 0 + STORAGE_ACCOUNT_NAME = data.azurerm_storage_account.stg.name + STORAGE_ACCOUNT_KEY = data.azurerm_storage_account.stg.primary_access_key + HTTP_ENDPOINT = data.azurerm_storage_account.stg.primary_file_endpoint + FILESHARE_NAME = var.shared_storage_access ? var.shared_storage_name : "" + NEXUS_PROXY_URL = local.nexus_proxy_url + CONDA_CONFIG = local.selected_image.conda_config ? 1 : 0 + VM_USER = local.admin_username + APT_SKU = replace(local.apt_sku, ".", "") + }) + } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf index 3aa4c0e..0c697e6 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/main.tf @@ -3,11 +3,11 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "= 3.117.0" + version = "= 4.57.0" } - template = { - source = "hashicorp/template" - version = "= 2.2.0" + cloudinit = { + source = "hashicorp/cloudinit" + version = "= 2.3.5" } random = { source = "hashicorp/random" @@ -15,7 +15,7 @@ terraform { } azuread = { source = "hashicorp/azuread" - version = "3.3.0" + version = "= 3.7.0" } } backend "azurerm" { @@ -49,4 +49,4 @@ provider "azuread" { client_id = var.auth_client_id client_secret = var.auth_client_secret tenant_id = var.auth_tenant_id -} \ No newline at end of file +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh index 7f68f1a..b4e2ab6 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh @@ -75,6 +75,4 @@ sudo service xrdp restart # Docker — restart to ensure service is running # daemon.json (Nexus registry mirror) is already written in the image # --------------------------------------------------------------------------- -if [ "${DOCKER_CONFIG}" == "true" ]; then - sudo systemctl restart docker -fi \ No newline at end of file +sudo systemctl restart docker diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml index 845c3c8..5bb6418 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm-ouh2 -version: 1.1.6 +version: 1.1.7 description: "An Azure TRE User Resource Template for Guacamole (Windows)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -43,7 +43,7 @@ custom: source_image_reference: publisher: microsoftwindowsdesktop offer: windows-11 - sku: win11-24h2-pro + sku: win11-25h2-pro version: latest conda_config: false secure_boot_enabled: true @@ -144,7 +144,7 @@ parameters: default: "" type: string description: "Time of day to shutdown the VM (HHmm format)" - pattern: "^([01]?[0-9]|2[0-3])[0-5][0-9]$" + pattern: "^([01]?[0-9]|2[0-3])[0-5][0-9]?$" - name: shutdown_timezone type: string description: "Timezone for the shutdown schedule" @@ -177,9 +177,9 @@ outputs: mixins: - exec - terraform: - clientVersion: 1.9.8 + clientVersion: 1.14.3 - az: - clientVersion: 2.67.0 + clientVersion: 2.81.0 install: - terraform: diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl index af6c704..d4a09cc 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/.terraform.lock.hcl @@ -2,42 +2,42 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azuread" { - version = "3.3.0" - constraints = "3.3.0" + version = "3.7.0" + constraints = "3.7.0" hashes = [ - "h1:CmjUkS5xnsVJ6QHzooWNYg2iowb++EcGIWSCoMiUlbM=", + "h1:xUoYzyYNcneRJDN8rlJ4tT+ZjebaDqvuNm6eMxKCeX4=", + "zh:01114beb07eb8415a563ca80a513e7fd11fd6f0670bdd960e9092e58464ab2b7", + "zh:1460c790ca28cc11c3efd4abec076fc5cdd4ae1cc654a45c69e10ca064e0a611", + "zh:161b6dd82cf279e7ac7a31c404f2ace491a5a9e7ec382ace91de2fd18f8c190b", "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", - "zh:2cb6dcfa5a3fd04f14b1976455b73f14a15f9f45069fa5fa198f87625df5751a", - "zh:3de1c29f4eb1a176a7f3039a470f26281228f9527a81ebedb86820dd9d5b0007", - "zh:498ef951e158caf10365b39cd95789f5a034c3ef6fca288b37520af0cc2f81e5", - "zh:7b8c8bda91a2b28b9371ac60c2c87a3967d0ca232ab868203062599fca4c832f", - "zh:9b109748e2ccad027d710548491bc8cc0399b69a9b779ac59d53745a95129e3a", - "zh:9d38831a614f67e09ca4bf2377a06e6dda9130a60437f4d73aa422d982b9f17f", - "zh:b6fa6920334e7495118784d15500d676fda4e9c924a03fb5e333faf6646fd15f", - "zh:c01171e3c1b1a6bcc9516f5fc44e4880c67a30541ae66ecf18d3aa0eb92457ad", - "zh:cd3bda1e87953a5288808a10ca9383baa14b4dee623e21a43048f95179bf0323", - "zh:df06f222c38fc37a074e00650e7699927b11a64b1f4170bfa7d823029662a778", - "zh:df502d004558a92808450fc9a7b6f17700d918e3037d21cba73d61e56466e785", + "zh:2eff0bea92c48be0221863ebf7752f491232088f4ec3cbe4da2ebf9f478fed1f", + "zh:69a689198fcac054da30fea6a8abce2f12b667f6f327c9bb388f2c307ee782fd", + "zh:6f5acf42d71a2f5157c54e67b2db9b080c4ebb27b812112c0c84241e66d94803", + "zh:8e0a58ff2c21aff372c66c679db48578be48e99f5cf6727f082cf4b629dbda6c", + "zh:9c88cc06ba7ee1f6e6b43af7e223c4d107fb77e5a984f1441fffb00c3693537f", + "zh:e8656e8143baac71029857c72899f8503cede41f2559c89ce29d21c0436c96fc", + "zh:e8e21913956a3f043c0e65cc95278bdc82f62ff33fd75a56b1919bd63fd14f8a", + "zh:f7f213dd61d1c75b8397d97660cf329870a241e88ec6e0dc07c60725d975252e", ] } provider "registry.terraform.io/hashicorp/azurerm" { - version = "3.117.0" - constraints = "3.117.0" + version = "4.57.0" + constraints = "4.57.0" hashes = [ - "h1:Ynfg+Iy7x6K8M6W1AhqXCe3wkoiqIQhROlca7C3KC3w=", - "zh:2e25f47492366821a786762369f0e0921cc9452d64bfd5075f6fdfcf1a9c6d70", - "zh:41eb34f2f7469bf3eb1019dfb0e7fc28256f809824016f4f8b9d691bf473b2ac", - "zh:48bb9c87b3d928da1abc1d3db75453c9725de4674c612daf3800160cc7145d30", - "zh:5d6b0de0bbd78943fcc65c53944ef4496329e247f434c6eab86ed051c5cea67b", - "zh:78c9f6fdb1206a89cf0e6706b4f46178169a93b6c964a4cad8a321058ccbd9b4", - "zh:793b702c352589d4360b580d4a1cf654a7439d2ad6bdb7bfea91de07bc4b0fac", - "zh:7ed687ff0a5509463a592f97431863574fe5cc80a34e395be06766215b8c6285", - "zh:955ba18789bd15592824eb426a8d0f38595bd09fffc6939c1c58933489c1a71e", - "zh:bf5949a55be0714cd9c8815d472eae4baa48ba06d0f6bf2b96775869acda8a54", - "zh:da5d31f635abd2c645ffc76d6176d73f646128e73720cc368247cc424975c127", - "zh:eed5a66d59883c9c56729b0a964a2b60d758ea7489ef3e920a6fbd48518ce5f5", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "h1:NhgHn/RyZRDXMa7pEQlGv/9B+wjk48E+lvgq4asFKHs=", + "zh:05e1cc7fee7829919b772ca6ce893d9c2abb3535ebff172df38f7358cdaf8f9e", + "zh:30122203abc381660582f989c9e53874bd9ff93e25476a5536ea0ae37dd51f4b", + "zh:4a90f008f7707d95f8f9aca90f140a9ca0e9506b0a6d436fe516de4026cacd86", + "zh:6d9e114b8aed06454b71fe91a0591cc6a16cd7acde3cb36a96e4aeaec06a315a", + "zh:7145c50facd9d40615fc63561ec21962feae3fa262239f9f1f1339581226104b", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:95f60557f1bc4210ecc3c11e2f86fe983ed7e4af19036616b605887c1195f2ac", + "zh:9722b3ab879a3457588af5f0dcd65e997263affe4b829e60ecd59dbef6239e70", + "zh:b891f295b018d058e8c6f841d923d5b30ba13b8208f2c20aacc70ba48c5cc0da", + "zh:cb7ff113ca0bd91ab76f9f7a492d6ce9c911d6c4deb8c8e263e38322b5ff861e", + "zh:ec2950bf003d29bee3fa87ab073d57fe14a4da52e9fc646fec27798b700cc8af", + "zh:f69899d9e1d570a560cfa97aebec3edc2b106f2ebc15dfdee473294dd8756deb", ] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf index 3036251..6593bd2 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf @@ -2,16 +2,15 @@ terraform { required_providers { azurerm = { - source = "hashicorp/azurerm" - version = "=3.117.0" + source = "hashicorp/azurerm" + version = "= 4.57.0" + configuration_aliases = [azurerm.core] } random = { - source = "hashicorp/random" - version = "= 3.7.2" } azuread = { source = "hashicorp/azuread" - version = "= 3.3.0" + version = "= 3.7.0" } } backend "azurerm" { @@ -43,4 +42,4 @@ provider "azuread" { client_id = var.auth_client_id client_secret = var.auth_client_secret tenant_id = var.auth_tenant_id -} \ No newline at end of file +} From afca88a2b4f107206d9dd5bec5d859f58275a109 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 08:35:10 +0000 Subject: [PATCH 15/26] return random provider --- .../guacamole-azure-windowsvm-ouh2/terraform/main.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf index 6593bd2..33d38c6 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf @@ -7,6 +7,8 @@ terraform { configuration_aliases = [azurerm.core] } random = { + source = "hashicorp/random" + version = "= 3.7.2" } azuread = { source = "hashicorp/azuread" From f4ed21d1ab9bf00117b24356b4ebec63f662bea1 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 09:36:23 +0000 Subject: [PATCH 16/26] Point to updated version --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index eed7dd5..c8d6ee9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.5", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.6", "GITHUB_TOKEN": "" } }, From 7dc37a25ff50b5a8b7eaba462b2d00181f017dbb Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 10:30:06 +0000 Subject: [PATCH 17/26] Point to new updates --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c8d6ee9..ad9503e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.6", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.7", "GITHUB_TOKEN": "" } }, From 441fe367e29da074f69eed2500962bb8d10d8dc9 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 11:56:02 +0000 Subject: [PATCH 18/26] Updated version fix --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ad9503e..cf1c169 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.7", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.8", "GITHUB_TOKEN": "" } }, From 0c728a710cccee692d871f8830f9796b93e16991 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 13:22:43 +0000 Subject: [PATCH 19/26] Update to new version --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cf1c169..23a5dbe 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.8", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.9", "GITHUB_TOKEN": "" } }, From 26a5f15ca86b356c9f3d940f5f83bc69fe47e000 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 14:34:18 +0000 Subject: [PATCH 20/26] Update to new version --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 23a5dbe..d3048a1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.9", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.10", "GITHUB_TOKEN": "" } }, From 5ec155e460174277e761c4c47c07e5c3f615684c Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 17 Mar 2026 19:49:19 +0000 Subject: [PATCH 21/26] Update version - rp changes --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d3048a1..72d0fdc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.10", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.11", "GITHUB_TOKEN": "" } }, From b399c7b572645552be9d3c99d2e9dd1a4ba048c5 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Wed, 18 Mar 2026 10:39:17 +0000 Subject: [PATCH 22/26] Updates to WIndows and Linux Windows - Fundamental fix to deployment (issue with provider reference) Linux - Fix to remove lock screen enabled --- .../guacamole-azure-linuxvm-ouh2/porter.yaml | 2 +- .../terraform/vm_config.sh | 15 ++++++++++++--- .../guacamole-azure-windowsvm-ouh2/porter.yaml | 2 +- .../terraform/main.tf | 5 ++--- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index 0f671eb..2a4be33 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm-ouh2 -version: 1.1.10 +version: 1.1.11 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh index b4e2ab6..ab9e03a 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh @@ -67,9 +67,18 @@ fi sudo -u "${VM_USER}" -i bash -c 'echo xfce4-session > ~/.xsession' sudo -u "${VM_USER}" -i bash -c 'echo xset s off >> ~/.xsession' sudo -u "${VM_USER}" -i bash -c 'echo xset -dpms >> ~/.xsession' - -sudo systemctl enable xrdp -sudo service xrdp restart +sudo -u "${VM_USER}" -i bash -c 'mkdir -p ~/.config/xfce4/xfconf/xfce-perchannel-xml' +sudo -u "${VM_USER}" -i bash -c 'cat > ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml << EOF + + + + + + + + + +EOF' # --------------------------------------------------------------------------- # Docker — restart to ensure service is running diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml index 5bb6418..b038f30 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-windowsvm-ouh2 -version: 1.1.7 +version: 1.1.8 description: "An Azure TRE User Resource Template for Guacamole (Windows)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf index 33d38c6..2a5393d 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf @@ -2,9 +2,8 @@ terraform { required_providers { azurerm = { - source = "hashicorp/azurerm" - version = "= 4.57.0" - configuration_aliases = [azurerm.core] + source = "hashicorp/azurerm" + version = "= 4.57.0" } random = { source = "hashicorp/random" From aaae4264cc4f58490be5b67a87f442ee88b61afb Mon Sep 17 00:00:00 2001 From: Jaimie Date: Wed, 18 Mar 2026 10:45:26 +0000 Subject: [PATCH 23/26] Lint error --- .../guacamole-azure-windowsvm-ouh2/terraform/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf index 2a5393d..e6e0d3e 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm-ouh2/terraform/main.tf @@ -2,8 +2,8 @@ terraform { required_providers { azurerm = { - source = "hashicorp/azurerm" - version = "= 4.57.0" + source = "hashicorp/azurerm" + version = "= 4.57.0" } random = { source = "hashicorp/random" From e2e6e10410258369169de758cd8f0f1d851d3dc4 Mon Sep 17 00:00:00 2001 From: Jaimie Date: Wed, 18 Mar 2026 11:55:26 +0000 Subject: [PATCH 24/26] Linux VM updates for lock screen --- .../guacamole-azure-linuxvm-ouh2/porter.yaml | 2 +- .../terraform/vm_config.sh | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index 2a4be33..46f9632 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm-ouh2 -version: 1.1.11 +version: 1.1.12 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh index ab9e03a..6e0c262 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh @@ -1,11 +1,9 @@ #!/bin/bash - set -o errexit set -o pipefail set -o nounset # Uncomment this line to see each command for debugging (careful: this will show secrets!) # set -o xtrace - # --------------------------------------------------------------------------- # NOTE: The following are pre-configured in the VM image and are NOT repeated here: # - apt sources (Nexus proxied repositories) @@ -18,49 +16,39 @@ set -o nounset # - Docker daemon (/etc/docker/daemon.json) → Nexus registry mirror # - Chrome (replaces Edge) # - Jupyter (available via VS Code Jupyter extension) -# - xfce4-screensaver disabled via XFCE settings +# - xfce4-screensaver lock screen disabled via per-user xfconf XML (see Per-user xrdp / session setup below) # --------------------------------------------------------------------------- - # --------------------------------------------------------------------------- # Shared storage mount (per-workspace credentials, autofs/CIFS) # --------------------------------------------------------------------------- if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then sudo apt-get install -y autofs cifs-utils - storageAccountName="${STORAGE_ACCOUNT_NAME}" storageAccountKey="${STORAGE_ACCOUNT_KEY}" httpEndpoint="${HTTP_ENDPOINT}" fileShareName="${FILESHARE_NAME}" mntRoot="/fileshares" credentialRoot="/etc/smbcredentials" - mntPath="$mntRoot/$fileShareName" # shellcheck disable=SC2308 smbPath=$(echo "$httpEndpoint" | cut -c7-"$(expr length "$httpEndpoint")")$fileShareName smbCredentialFile="$credentialRoot/$storageAccountName.cred" - sudo mkdir -p "$mntPath" sudo mkdir -p "/etc/smbcredentials" sudo mkdir -p $mntRoot - if [ ! -f "$smbCredentialFile" ]; then echo "username=$storageAccountName" | sudo tee "$smbCredentialFile" > /dev/null echo "password=$storageAccountKey" | sudo tee -a "$smbCredentialFile" > /dev/null else echo "The credential file $smbCredentialFile already exists, and was not modified." fi - sudo chmod 600 "$smbCredentialFile" - echo "$fileShareName -fstype=cifs,rw,file_mode=0777,dir_mode=0777,credentials=$smbCredentialFile :$smbPath" | sudo tee /etc/auto.fileshares > /dev/null echo "$mntRoot /etc/auto.fileshares --timeout=60" | sudo tee /etc/auto.master > /dev/null - sudo systemctl restart autofs - # Symlink for constant visible mount point sudo ln -s "$mntPath" "/$fileShareName" fi - # --------------------------------------------------------------------------- # Per-user xrdp / session setup # --------------------------------------------------------------------------- @@ -76,10 +64,11 @@ sudo -u "${VM_USER}" -i bash -c 'cat > ~/.config/xfce4/xfconf/xfce-perchannel-xm + + EOF' - # --------------------------------------------------------------------------- # Docker — restart to ensure service is running # daemon.json (Nexus registry mirror) is already written in the image From 721fc8bd144161917f86430057e3ba20ae60a71a Mon Sep 17 00:00:00 2001 From: Jaimie Date: Thu, 19 Mar 2026 09:56:57 +0000 Subject: [PATCH 25/26] Nexus upgrade - new tag --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 72d0fdc..1635194 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ "DOCKER_GROUP_ID": "${localEnv:DOCKER_GROUP_ID}", "INTERACTIVE": "true", "UPSTREAM_REPO": "OxBRCInformatics/AzureTRE", - "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.11", + "UPSTREAM_REPO_VERSION": "tvstre-prod-main-v0.25.12", "GITHUB_TOKEN": "" } }, From 134a8fe069cf8508b7b2dc6c210566f56eba50df Mon Sep 17 00:00:00 2001 From: Jaimie Date: Tue, 31 Mar 2026 20:47:17 +0100 Subject: [PATCH 26/26] Update to Linux vm_config.sh --- .../guacamole-azure-linuxvm-ouh2/porter.yaml | 2 +- .../terraform/vm_config.sh | 30 ++++--------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml index 46f9632..c70ddea 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm-ouh2 -version: 1.1.12 +version: 1.2.0 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh index 6e0c262..ff36c16 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm-ouh2/terraform/vm_config.sh @@ -6,8 +6,8 @@ set -o nounset # set -o xtrace # --------------------------------------------------------------------------- # NOTE: The following are pre-configured in the VM image and are NOT repeated here: -# - apt sources (Nexus proxied repositories) -# - Base package installs (gnupg, wget, gdebi-core, etc.) +# - apt sources (Nexus proxied repositories only — no direct internet sources) +# - Base package installs (gnupg, wget, gdebi-core, autofs, cifs-utils, etc.) # - Desktop environment (XFCE, xorg, dbus-x11) # - Azure Storage Explorer (installed at /opt/storage-explorer with desktop entry) # - pip (/etc/pip.conf) → Nexus PyPI proxy @@ -16,13 +16,13 @@ set -o nounset # - Docker daemon (/etc/docker/daemon.json) → Nexus registry mirror # - Chrome (replaces Edge) # - Jupyter (available via VS Code Jupyter extension) -# - xfce4-screensaver lock screen disabled via per-user xfconf XML (see Per-user xrdp / session setup below) +# - xrdp session defaults (/etc/skel/.xsession) +# - xfce4-screensaver lock screen disabled (/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml) # --------------------------------------------------------------------------- # --------------------------------------------------------------------------- # Shared storage mount (per-workspace credentials, autofs/CIFS) # --------------------------------------------------------------------------- if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then - sudo apt-get install -y autofs cifs-utils storageAccountName="${STORAGE_ACCOUNT_NAME}" storageAccountKey="${STORAGE_ACCOUNT_KEY}" httpEndpoint="${HTTP_ENDPOINT}" @@ -50,27 +50,7 @@ if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then sudo ln -s "$mntPath" "/$fileShareName" fi # --------------------------------------------------------------------------- -# Per-user xrdp / session setup -# --------------------------------------------------------------------------- -sudo -u "${VM_USER}" -i bash -c 'echo xfce4-session > ~/.xsession' -sudo -u "${VM_USER}" -i bash -c 'echo xset s off >> ~/.xsession' -sudo -u "${VM_USER}" -i bash -c 'echo xset -dpms >> ~/.xsession' -sudo -u "${VM_USER}" -i bash -c 'mkdir -p ~/.config/xfce4/xfconf/xfce-perchannel-xml' -sudo -u "${VM_USER}" -i bash -c 'cat > ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml << EOF - - - - - - - - - - - -EOF' -# --------------------------------------------------------------------------- # Docker — restart to ensure service is running # daemon.json (Nexus registry mirror) is already written in the image # --------------------------------------------------------------------------- -sudo systemctl restart docker +sudo systemctl restart docker \ No newline at end of file