diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.dockerignore b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.dockerignore new file mode 100644 index 0000000000..28756cfe84 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.dockerignore @@ -0,0 +1,11 @@ +# Local .terraform directories +**/.terraform/* + +# TF backend files +**/*_backend.tf + +Dockerfile.tmpl + +.env* +terraform/deploy.sh +terraform/destroy.sh diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.env.sample b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.env.sample new file mode 100644 index 0000000000..c9ef2af4c2 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/.env.sample @@ -0,0 +1,5 @@ +# GUID to identify the workspace +WORKSPACE_ID=__CHANGE_ME__ + +# Unique identifier of the parent Guacamole service +PARENT_SERVICE_ID=__CHANGE_ME__ diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/Dockerfile.tmpl b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/Dockerfile.tmpl new file mode 100644 index 0000000000..34a5df4d66 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/Dockerfile.tmpl @@ -0,0 +1,41 @@ +FROM debian:buster-slim + +ARG BUNDLE_DIR + +ARG AZURE_TRE_VERSION="0.4.3" + +RUN apt-get update \ + && apt-get install --no-install-recommends jq ca-certificates curl patch -y \ + && apt-get clean -y && rm -rf /var/lib/apt/lists/* + +WORKDIR $BUNDLE_DIR + +RUN curl -o azuretre.tar.gz -L "https://github.com/microsoft/AzureTRE/archive/refs/tags/v${AZURE_TRE_VERSION}.tar.gz" \ + && tar -xzf azuretre.tar.gz "AzureTRE-${AZURE_TRE_VERSION}/templates/workspace_services/guacamole/user_resources/guacamole-azure-windowsvm" --strip-components=6 --skip-old-files \ + && rm -rf azuretre.tar.gz + +# This is a template Dockerfile for the bundle's invocation image +# You can customize it to use different base images, install tools and copy configuration files. +# +# Porter will use it as a template and append lines to it for the mixins +# and to set the CMD appropriately for the CNAB specification. +# +# Add the following line to porter.yaml to instruct Porter to use this template +# dockerfile: Dockerfile.tmpl + +# You can control where the mixin's Dockerfile lines are inserted into this file by moving "# PORTER_MIXINS" line +# another location in this file. If you remove that line, the mixins generated content is appended to this file. +# PORTER_MIXINS + +# Use the BUNDLE_DIR build argument to copy files into the bundle +COPY . $BUNDLE_DIR + +# Apply patch with the difference from the base workspace +RUN patch -p0 < $BUNDLE_DIR/windowsvm.diff + +# Mirror plugins to prevent network access at runtime +# Remove when available from https://github.com/getporter/terraform-mixin/issues/90 +WORKDIR $BUNDLE_DIR/terraform +RUN terraform init -backend=false \ + && rm -fr $BUNDLE_DIR/terraform/.terraform/providers \ + && terraform providers mirror /usr/local/share/terraform/plugins diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/parameters.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/parameters.json new file mode 100755 index 0000000000..3a3589dab6 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/parameters.json @@ -0,0 +1,62 @@ +{ + "schemaVersion": "1.0.0-DRAFT+TODO", + "name": "guacamole-win-import-reviewvm", + "created": "2021-06-03T11:54:54.0225968Z", + "modified": "2021-06-03T11:54:54.0225968Z", + "parameters": [ + { + "name": "workspace_id", + "source": { + "env": "WORKSPACE_ID" + } + }, + { + "name": "parent_service_id", + "source": { + "env": "PARENT_SERVICE_ID" + } + }, + { + "name": "tre_id", + "source": { + "env": "TRE_ID" + } + }, + { + "name": "tfstate_container_name", + "source": { + "env": "TERRAFORM_STATE_CONTAINER_NAME" + } + }, + { + "name": "tfstate_resource_group_name", + "source": { + "env": "MGMT_RESOURCE_GROUP_NAME" + } + }, + { + "name": "tfstate_storage_account_name", + "source": { + "env": "MGMT_STORAGE_ACCOUNT_NAME" + } + }, + { + "name": "id", + "source": { + "env": "ID" + } + }, + { + "name": "os_image", + "source": { + "env": "OS_IMAGE" + } + }, + { + "name": "vm_size", + "source": { + "env": "VM_SIZE" + } + } + ] +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/porter.yaml new file mode 100644 index 0000000000..43ee14df32 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/porter.yaml @@ -0,0 +1,237 @@ +--- +name: tre-service-guacamole-import-reviewvm +version: 0.0.2 +description: "An Azure TRE User Resource Template for reviewing Airlock import requests" +dockerfile: Dockerfile.tmpl +registry: azuretre + +credentials: + - name: azure_tenant_id + env: ARM_TENANT_ID + - name: azure_subscription_id + env: ARM_SUBSCRIPTION_ID + - name: azure_client_id + env: ARM_CLIENT_ID + - name: azure_client_secret + env: ARM_CLIENT_SECRET + +parameters: + - name: workspace_id + type: string + - name: tre_id + type: string + - name: parent_service_id + type: string + description: "Resource group containing the shared ACR" + env: PARENT_SERVICE_ID + - name: id + type: string + description: "An Id for this installation" + env: id + - name: tfstate_resource_group_name + type: string + description: "Resource group containing the Terraform state storage account" + - name: tfstate_storage_account_name + type: string + description: "The name of the Terraform state storage account" + - name: tfstate_container_name + env: tfstate_container_name + type: string + default: "tfstate" + description: "The name of the Terraform state storage container" + - name: arm_use_msi + env: ARM_USE_MSI + type: boolean + default: false + - name: os_image + type: string + default: "Windows 10" + - name: vm_size + type: string + default: "2 CPU | 8GB RAM" + +outputs: + - name: ip + type: string + applyTo: + - install + - name: hostname + type: string + applyTo: + - install + - name: connection_uri + type: string + applyTo: + - install + - name: azure_resource_id + type: string + applyTo: + - install + - start + - stop + - reset_password + +mixins: + - exec + - terraform: + clientVersion: 1.2.8 + - az + +install: + - terraform: + description: "Deploy Guacamole User Resource Service (Reviewer VM)" + vars: + workspace_id: "{{ bundle.parameters.workspace_id }}" + tre_id: "{{ bundle.parameters.tre_id }}" + parent_service_id: "{{ bundle.parameters.parent_service_id }}" + tre_resource_id: "{{ bundle.parameters.id }}" + image: "{{ bundle.parameters.os_image }}" + vm_size: "{{ bundle.parameters.vm_size }}" + shared_storage_access: "false" + shared_storage_name: "unused" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + outputs: + - name: ip + - name: hostname + - name: connection_uri + - name: azure_resource_id + +upgrade: + - terraform: + description: "Update Guacamole User Resource Service (Reviewer VM)" + vars: + workspace_id: "{{ bundle.parameters.workspace_id }}" + tre_id: "{{ bundle.parameters.tre_id }}" + parent_service_id: "{{ bundle.parameters.parent_service_id }}" + tre_resource_id: "{{ bundle.parameters.id }}" + image: "{{ bundle.parameters.os_image }}" + vm_size: "{{ bundle.parameters.vm_size }}" + shared_storage_access: "false" + shared_storage_name: "unused" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + outputs: + - name: ip + - name: hostname + - name: connection_uri + - name: azure_resource_id + +uninstall: + - exec: + description: "Delete the Extensions from the Terraform state manually" + command: ./delete_vm_extensions.sh + arguments: + - "{{ bundle.parameters.tfstate_resource_group_name }}" + - "{{ bundle.parameters.tfstate_storage_account_name }}" + - "{{ bundle.parameters.tfstate_container_name }}" + - "{{ bundle.parameters.id }}" + + - terraform: + description: "Delete the Guacamole User Resource Service" + vars: + workspace_id: "{{ bundle.parameters.workspace_id }}" + tre_id: "{{ bundle.parameters.tre_id }}" + parent_service_id: "{{ bundle.parameters.parent_service_id }}" + tre_resource_id: "{{ bundle.parameters.id }}" + image: "{{ bundle.parameters.os_image }}" + vm_size: "{{ bundle.parameters.vm_size }}" + shared_storage_access: "false" + shared_storage_name: "unused" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + +start: + - terraform: + arguments: + - "output" + description: "Get resource ID from Terraform outputs" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + outputs: + - name: azure_resource_id + - az: + description: "Login to Azure" + arguments: + - login + flags: + identity: + username: "{{ bundle.credentials.azure_client_id }}" + - az: + description: "Start the VM" + arguments: + - vm + - start + flags: + ids: "{{ bundle.outputs.azure_resource_id }}" + +stop: + - terraform: + arguments: + - "output" + description: "Get VM hostname and rg from Terraform outputs" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + outputs: + - name: azure_resource_id + - az: + description: "Login to Azure" + arguments: + - login + flags: + identity: + username: "{{ bundle.credentials.azure_client_id }}" + - az: + description: "Stop the VM" + arguments: + - vm + - deallocate + flags: + ids: "{{ bundle.outputs.azure_resource_id }}" + +reset_password: + - terraform: + arguments: + - "output" + description: "Get VM details from Terraform outputs" + backendConfig: + resource_group_name: "{{ bundle.parameters.tfstate_resource_group_name }}" + storage_account_name: "{{ bundle.parameters.tfstate_storage_account_name }}" + container_name: "{{ bundle.parameters.tfstate_container_name }}" + key: "{{ bundle.parameters.id }}" + outputs: + - name: azure_resource_id + - name: vm_username + - name: vm_password_secret_name + - name: keyvault_name + - az: + description: "Login to Azure" + arguments: + - login + flags: + identity: + username: "{{ bundle.credentials.azure_client_id }}" + - exec: + description: "Reset password and persist to keyvault" + suppress-output: true + command: ./reset_password.sh + arguments: + - "{{ bundle.outputs.vm_password_secret_name }}" + - "{{ bundle.outputs.keyvault_name }}" + - "{{ bundle.outputs.vm_username }}" + - "{{ bundle.outputs.azure_resource_id }}" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/template_schema.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/template_schema.json new file mode 100644 index 0000000000..b1b28948ff --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/template_schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://github.com/microsoft/AzureTRE/templates/workspace_services/guacamole/user_resources/guacamole-azure-import-reviewvm/template_schema.json", + "type": "object", + "title": "Import review Virtual Machine", + "description": "Windows virtual machine for import review", + "required": [ + ], + "authorizedRoles": [ + "AirlockManager" + ], + "properties": { + "os_image": { + "$id": "#/properties/os_image", + "type": "string", + "title": "Windows image", + "description": "Select Windows image to use for VM", + "enum": [ + "Server 2019 Data Science VM" + ] + }, + "vm_size": { + "$id": "#/properties/vm_size", + "type": "string", + "title": "VM Size", + "description": "Select size of VM", + "enum": [ + "2 CPU | 8GB RAM", + "4 CPU | 16GB RAM" + ], + "updateable": true + } + } +} diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/terraform/empty.txt b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/terraform/empty.txt new file mode 100644 index 0000000000..c77897746a --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/terraform/empty.txt @@ -0,0 +1 @@ +The porter terraform mixin requires this directory to exist in the local build context. diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/windowsvm.diff b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/windowsvm.diff new file mode 100644 index 0000000000..5b05f4c311 --- /dev/null +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-importreview-vm/windowsvm.diff @@ -0,0 +1,38 @@ +diff --git terraform/variables.tf ../guacamole-azure-windowsvm/terraform/variables.tf +index a5038c01..2fdb0f77 100644 +--- terraform/variables.tf ++++ ../guacamole-azure-windowsvm/terraform/variables.tf +@@ -4,5 +4,7 @@ variable "parent_service_id" {} + variable "tre_resource_id" {} + variable "image" {} + variable "vm_size" {} +-variable "shared_storage_access" {} ++variable "shared_storage_access" { ++ type = bool ++} + variable "shared_storage_name" {} +diff --git terraform/windowsvm.tf ../guacamole-azure-windowsvm/terraform/windowsvm.tf +index 3a083a71..5b58cc4a 100644 +--- terraform/windowsvm.tf ++++ ../guacamole-azure-windowsvm/terraform/windowsvm.tf +@@ -92,10 +92,10 @@ data "template_file" "vm_config" { + template = file("${path.module}/vm_config.ps1") + vars = { + nexus_proxy_url = local.nexus_proxy_url +- SharedStorageAccess = tobool(var.shared_storage_access) ? 1 : 0 ++ SharedStorageAccess = var.shared_storage_access ? 1 : 0 + StorageAccountName = data.azurerm_storage_account.stg.name + StorageAccountKey = data.azurerm_storage_account.stg.primary_access_key +- FileShareName = data.azurerm_storage_share.shared_storage.name ++ FileShareName = var.shared_storage_access ? data.azurerm_storage_share.shared_storage[0].name : "" + CondaConfig = local.image_ref[var.image].conda_config ? 1 : 0 + } + } +@@ -106,6 +106,7 @@ data "azurerm_storage_account" "stg" { + } + + data "azurerm_storage_share" "shared_storage" { ++ count = var.shared_storage_access ? 1 : 0 + name = var.shared_storage_name + storage_account_name = data.azurerm_storage_account.stg.name + }