diff --git a/CHANGELOG.md b/CHANGELOG.md index 64cdb8bd18..5aa6fe9888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,11 @@ FEATURES: ENHANCEMENTS: BUG FIXES: +* Update Guacomole Linux VM Images to Ubuntu 22.04 LTS. Part of ([#3523](https://github.com/microsoft/AzureTRE/issues/3523)) +* Update Nexus Shared Service with new proxies. Part of ([#3523](https://github.com/microsoft/AzureTRE/issues/3523)) * Update to Resource Processor Image, now using Ubuntu 22.04 (jammy). Part of ([#3523](https://github.com/microsoft/AzureTRE/issues/3523)) -* Remove TLS1.0/1.1 support from Application Gateway +* Remove TLS1.0/1.1 support from Application Gateway ([#3914](https://github.com/microsoft/AzureTRE/issues/3914)) +* GitHub Actions version updates. ([#3847](https://github.com/microsoft/AzureTRE/issues/3847)) COMPONENTS: diff --git a/docs/tre-templates/shared-services/nexus.md b/docs/tre-templates/shared-services/nexus.md index 5869ae9693..3717f986e8 100644 --- a/docs/tre-templates/shared-services/nexus.md +++ b/docs/tre-templates/shared-services/nexus.md @@ -87,10 +87,12 @@ Nexus Shared Service requires access to resources outside of the Azure TRE VNET. | Ubuntu Security Packages | apt | [http://security.ubuntu.com/ubuntu/] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/ubuntu-security/` | Provide access to Ubuntu Security apt packages on Ubuntu systems. | | Almalinux | yum | [https://repo.almalinux.org] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/almalinux` | Install Almalinux packages | | R-Proxy | r | [https://cran.r-project.org/] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/r-proxy` | Provide access to CRAN packages for R | +| R-Studio Download | raw | [https://download1.rstudio.org] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/r-studio-download` | Provide access to download R Studio | | Fedora Project | yum | [https://download-ib01.fedoraproject.org] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/fedoraproject` | Install Fedora Project Linux packages | | Microsoft Apt | apt | [https://packages.microsoft.com] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/microsoft-apt` | Provide access to Microsoft Apt packages | | Microsoft Keys | raw | [https://packages.microsoft.com/keys/] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/microsoft-keys` | Provide access to Microsoft keys | | Microsoft Yum | yum | [https://packages.microsoft.com/yumrepos] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/microsoft-yum` | Provide access to Microsoft Yum packages | +| Microsoft Download | raw | [https://download.microsoft.com/download] | `https://nexus-{TRE_ID}.{LOCATION}.cloudapp.azure.com/repository/microsoft-download` | Provide access to Microsoft Downloads | ### Migrate from an existing V1 Nexus service (hosted on App Service) @@ -111,3 +113,20 @@ If you still have an existing Nexus installation based on App Service (from the The Nexus service checks Key Vault regularly for the latest certificate matching the name you passed on deploy (`nexus-ssl` by default). When approaching expiry, you can either provide an updated certificate into the TRE core KeyVault (with the name you specified when installing Nexus) if you brought your own, or if you used the certs shared service to generate one, just call the `renew` custom action on that service. This will generate a new certificate and persist it to the Key Vault, replacing the expired one. + +## Updating to v3.0.0 +The newest version of Nexus is a significant update for the service. +As a result, a new installation of Nexus will be necessary. + +We are currently in the process of developing an upgrade path for upcoming releases. + +## Using Docker Hub +When using Docker with a VM, the image URL should be constructed as follows: {NEXUS_URL}:{port}/docker-image + +```bash +sudo docker pull {NEXUS_URL}:8083/hello-world +``` + +the default port out of the box is 8083 + +Nexus will also need "Anonymous Access" set to "Enable". This can be done by logging into the Nexus Portal with the Admin user and following the prompts. diff --git a/docs/tre-templates/user-resources/custom.md b/docs/tre-templates/user-resources/custom.md new file mode 100644 index 0000000000..dfdfb136bd --- /dev/null +++ b/docs/tre-templates/user-resources/custom.md @@ -0,0 +1,62 @@ +# Guacamole User Resources + +- linuxvm - a Linux-based virtual machine +- windowsvm - A Windows-based virtual machine + +## Customising the user resources + +The `guacamole-azure-linuxvm` and `guacamole-azure-windowsvm` folders follow a consistent layout. +To update one of these templates (or to create a new template based on these folders) to use different image details or VM sizes, there are a few files that need to be updated: + +| File | Description | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `porter.yaml` | This file describes the template and the name should be updated when creating a template based on the folder.
This file also contains a `custom` data section that describes the VM properties.
Additionally, the version needs to be updated to deploy an updated version | +| `template_schema.json` | This file controls the validation applied to the template, for example specifying the valid options for fields such as size and image | + +### Configuration + +In `porter.yaml`, the `custom` section contains a couple of sub-sections (shown below) + +```yaml +custom: + vm_sizes: + "2 CPU | 8GB RAM": Standard_D2s_v5 + "4 CPU | 16GB RAM": Standard_D4s_v5 + "8 CPU | 32GB RAM": Standard_D8s_v5 + "16 CPU | 64GB RAM": Standard_D16s_v5 + image_options: + "Ubuntu 22.04 LTS": + source_image_reference: + publisher: canonical + offer: 0001-com-ubuntu-server-jammy + sku: 22_04-lts-gen2 + version: latest + apt_sku: 22.04 + install_ui: true + conda_config: false + # "Custom Image From Gallery": + # source_image_name: your-image + # install_ui: true + # conda_config: true +``` + +The `vm_sizes` section is a map of a custom SKU description to the SKU identifier. + +The `image_options` section defined the possible image choices for the template (note that the name of the image used here needs to be included in the corresponding enum in `template_schema.json`). + +Within the image definition in `image_options` there are a few properties that can be specified: + +| Name | Description | +| ------------------------ | -------------------------------------------------------------------------------------------------------- | +| `source_image_name` | Specify VM image to use by name (see notes below for identifying the image gallery containing the image) | +| `source_image_reference` | Specify VM image to use by `publisher`, `offer`, `sku` & `version` (e.g. for Azure Marketplace images) | +| `install_ui` | (Linux only) Set `true` to install desktop environment | +| `conda_config` | Set true to configure conda | + +When specifying images using `source_image_name`, the image must be stored in an [image gallery](https://learn.microsoft.com/en-us/azure/virtual-machines/azure-compute-gallery). +To enable re-using built user resource templates across environments where the image may vary, the image gallery is configured via the `RP_BUNDLE_VALUES` environment variable when deploying the TRE. +The `RP_BUNDLE_VALUES` variable is a JSON object, and the `image_gallery_id` property within it identifies the image gallery that contains the images specified by `source_image_name`: + +```bash +RP_BUNDLE_VALUES='{"image_gallery_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Compute/galleries/"} +``` diff --git a/docs/tre-templates/user-resources/guacamole-linux-vm.md b/docs/tre-templates/user-resources/guacamole-linux-vm.md index 8cf7b55906..31c08f55a0 100644 --- a/docs/tre-templates/user-resources/guacamole-linux-vm.md +++ b/docs/tre-templates/user-resources/guacamole-linux-vm.md @@ -7,3 +7,13 @@ It blocks all inbound and outbound traffic to the internet and allows only RDP c - [A base workspace bundle installed](../workspaces/base.md) - [A guacamole workspace service bundle installed](../workspace-services/guacamole.md) +- [A Nexus shared service has been deployed](../shared-services/nexus.md) + +## Notes + +- Nexus is a prerequisite of installing the Linux VMs given the additional commands in the bootstrap scripts. +- In production we recommend using VM images to avoid transient issues downloading and installing packages. The included user resource templates for VMs with bootstrap scripts should only be used for trial/demonstration purposes. More info can be found [here](./custom.md). +- Snap (app store for linux via [snapcraft.io](https://snapcraft.io)) hasn't been configured to work via the nexus proxy + +## Using Custom Images +For custom image usage, visit this [page](./custom.md). diff --git a/e2e_tests/test_performance.py b/e2e_tests/test_performance.py index 9f284fc235..6c6d836d9d 100644 --- a/e2e_tests/test_performance.py +++ b/e2e_tests/test_performance.py @@ -106,7 +106,7 @@ async def test_bulk_updates_to_ensure_each_resource_updated_in_series(verify) -> "properties": { "display_name": "Perf test VM", "description": "", - "os_image": "Ubuntu 18.04" + "os_image": "Ubuntu 22.04 LTS" } } diff --git a/templates/shared_services/sonatype-nexus-vm/porter.yaml b/templates/shared_services/sonatype-nexus-vm/porter.yaml index 307bee19bc..f46a419468 100644 --- a/templates/shared_services/sonatype-nexus-vm/porter.yaml +++ b/templates/shared_services/sonatype-nexus-vm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-shared-service-sonatype-nexus -version: 2.8.13 +version: 3.0.0 description: "A Sonatype Nexus shared service" dockerfile: Dockerfile.tmpl registry: azuretre diff --git a/templates/shared_services/sonatype-nexus-vm/scripts/nexus_realms_config.json b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_realms_config.json index 51fa1053e0..eeb2530e36 100644 --- a/templates/shared_services/sonatype-nexus-vm/scripts/nexus_realms_config.json +++ b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_realms_config.json @@ -1,5 +1,4 @@ [ - "NexusAuthenticatingRealm", - "NexusAuthorizingRealm", - "DockerToken" + "DockerToken", + "NexusAuthenticatingRealm" ] diff --git a/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/microsoft_download_conf.json b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/microsoft_download_conf.json new file mode 100644 index 0000000000..a153c626a9 --- /dev/null +++ b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/microsoft_download_conf.json @@ -0,0 +1,32 @@ +{ + "name": "microsoft-download", + "online": true, + "storage": { + "blobStoreName": "default", + "strictContentTypeValidation": true, + "write_policy": "ALLOW" + }, + "proxy": { + "remoteUrl": "https://download.microsoft.com/download", + "contentMaxAge": 1440, + "metadataMaxAge": 1440 + }, + "negativeCache": { + "enabled": true, + "timeToLive": 1440 + }, + "httpClient": { + "blocked": false, + "autoBlock": false, + "connection": { + "retries": 0, + "userAgentSuffix": "string", + "timeout": 60, + "enableCircularRedirects": false, + "enableCookies": false, + "useTrustStore": false + } + }, + "baseType": "raw", + "repoType": "proxy" + } \ No newline at end of file diff --git a/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/r_studio_download_conf.json b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/r_studio_download_conf.json new file mode 100644 index 0000000000..264deeeb36 --- /dev/null +++ b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/r_studio_download_conf.json @@ -0,0 +1,32 @@ +{ + "name": "r-studio-download", + "online": true, + "storage": { + "blobStoreName": "default", + "strictContentTypeValidation": true, + "write_policy": "ALLOW" + }, + "proxy": { + "remoteUrl": "https://download1.rstudio.org", + "contentMaxAge": 1440, + "metadataMaxAge": 1440 + }, + "negativeCache": { + "enabled": true, + "timeToLive": 1440 + }, + "httpClient": { + "blocked": false, + "autoBlock": false, + "connection": { + "retries": 0, + "userAgentSuffix": "string", + "timeout": 60, + "enableCircularRedirects": false, + "enableCookies": false, + "useTrustStore": false + } + }, + "baseType": "raw", + "repoType": "proxy" + } \ No newline at end of file diff --git a/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/snapcraft_conf.json b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/snapcraft_conf.json new file mode 100644 index 0000000000..33019c0a48 --- /dev/null +++ b/templates/shared_services/sonatype-nexus-vm/scripts/nexus_repos_config/snapcraft_conf.json @@ -0,0 +1,32 @@ +{ + "name": "snapcraft", + "online": true, + "storage": { + "blobStoreName": "default", + "strictContentTypeValidation": true, + "write_policy": "ALLOW" + }, + "proxy": { + "remoteUrl": "https://snapcraftcontent.com", + "contentMaxAge": 1440, + "metadataMaxAge": 1440 + }, + "negativeCache": { + "enabled": true, + "timeToLive": 1440 + }, + "httpClient": { + "blocked": false, + "autoBlock": false, + "connection": { + "retries": 0, + "userAgentSuffix": "string", + "timeout": 60, + "enableCircularRedirects": false, + "enableCookies": false, + "useTrustStore": false + } + }, + "baseType": "raw", + "repoType": "proxy" + } \ No newline at end of file diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf b/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf index c0484c712f..67cae90039 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/locals.tf @@ -1,7 +1,7 @@ locals { core_vnet = "vnet-${var.tre_id}" core_resource_group_name = "rg-${var.tre_id}" - nexus_allowed_fqdns = "pypi.org,*.pypi.org,files.pythonhosted.org,security.ubuntu.com,archive.ubuntu.com,keyserver.ubuntu.com,repo.anaconda.com,*.docker.com,*.docker.io,conda.anaconda.org,azure.archive.ubuntu.com,packages.microsoft.com,repo.almalinux.org,download-ib01.fedoraproject.org,cran.r-project.org,cloud.r-project.org" + nexus_allowed_fqdns = "pypi.org,*.pypi.org,files.pythonhosted.org,security.ubuntu.com,archive.ubuntu.com,keyserver.ubuntu.com,repo.anaconda.com,*.docker.com,*.docker.io,conda.anaconda.org,azure.archive.ubuntu.com,packages.microsoft.com,repo.almalinux.org,download-ib01.fedoraproject.org,cran.r-project.org,cloud.r-project.org,download1.rstudio.org,*.snapcraftcontent.com,download.microsoft.com" nexus_allowed_fqdns_list = distinct(compact(split(",", replace(local.nexus_allowed_fqdns, " ", "")))) workspace_vm_allowed_fqdns = "r3.o.lencr.org,x1.c.lencr.org" workspace_vm_allowed_fqdns_list = distinct(compact(split(",", replace(local.workspace_vm_allowed_fqdns, " ", "")))) diff --git a/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf b/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf index 27a6a3d04f..79dfa04472 100644 --- a/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf +++ b/templates/shared_services/sonatype-nexus-vm/terraform/vm.tf @@ -83,6 +83,7 @@ resource "azurerm_user_assigned_identity" "nexus_msi" { location = data.azurerm_resource_group.rg.location resource_group_name = local.core_resource_group_name tags = local.tre_shared_service_tags + lifecycle { ignore_changes = [tags] } } diff --git a/templates/workspace_services/guacamole/user_resources/README.md b/templates/workspace_services/guacamole/user_resources/README.md index c553e1673a..623098ad42 100644 --- a/templates/workspace_services/guacamole/user_resources/README.md +++ b/templates/workspace_services/guacamole/user_resources/README.md @@ -2,10 +2,9 @@ This folder contains user resources that can be deployed with the Guacamole workspace service: -- linuxvm - a Linux-based virtual machine (expects an Ubuntu 18.04-based VM) +- linuxvm - a Linux-based virtual machine - windowsvm - A Windows-based virtual machine - ## Customising the user resources The `guacamole-azure-linuxvm` and `guacamole-azure-windowsvm` folders follow a consistent layout. @@ -29,22 +28,15 @@ custom: "8 CPU | 32GB RAM": Standard_D8s_v5 "16 CPU | 64GB RAM": Standard_D16s_v5 image_options: - "Ubuntu 18.04": + "Ubuntu 22.04 LTS": source_image_reference: publisher: canonical - offer: ubuntuserver - sku: 18_04-lts-gen2 + offer: 0001-com-ubuntu-server-jammy + sku: 22_04-lts-gen2 version: latest + apt_sku: 22.04 install_ui: true conda_config: false - "Ubuntu 18.04 Data Science VM": - source_image_reference: - publisher: microsoft-dsvm - offer: ubuntu-1804 - sku: 1804-gen2 - version: latest - install_ui: false - conda_config: true # "Custom Image From Gallery": # source_image_name: your-image # install_ui: true @@ -68,8 +60,6 @@ When specifying images using `source_image_name`, the image must be stored in an To enable re-using built user resource templates across environments where the image may vary, the image gallery is configured via the `RP_BUNDLE_VALUES` environment variable when deploying the TRE. The `RP_BUNDLE_VALUES` variable is a JSON object, and the `image_gallery_id` property within it identifies the image gallery that contains the images specified by `source_image_name`: - ```bash RP_BUNDLE_VALUES='{"image_gallery_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//providers/Microsoft.Compute/galleries/"} ``` - diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml index f36a668258..cbd074d962 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-guacamole-linuxvm -version: 0.6.9 +version: 1.0.0 description: "An Azure TRE User Resource Template for Guacamole (Linux)" dockerfile: Dockerfile.tmpl registry: azuretre @@ -14,29 +14,21 @@ custom: "8 CPU | 32GB RAM": Standard_D8s_v5 "16 CPU | 64GB RAM": Standard_D16s_v5 image_options: - "Ubuntu 18.04": + "Ubuntu 22.04 LTS": source_image_reference: publisher: canonical - offer: ubuntuserver - sku: 18_04-lts-gen2 + offer: 0001-com-ubuntu-server-jammy + sku: 22_04-lts-gen2 version: latest + apt_sku: 22.04 install_ui: true conda_config: false - "Ubuntu 18.04 Data Science VM": - source_image_reference: - publisher: microsoft-dsvm - offer: ubuntu-1804 - sku: 1804-gen2 - version: latest - install_ui: false - conda_config: true # For information on using custom images, see README.me in the guacamole/user-resources folder # "Custom Image From Gallery": # source_image_name: your-image # install_ui: true # conda_config: true - credentials: - name: azure_tenant_id env: ARM_TENANT_ID @@ -91,7 +83,7 @@ parameters: default: "public" - name: os_image type: string - default: "Ubuntu 18.04 Data Science VM" + default: "Ubuntu 22.04 LTS" - name: vm_size type: string default: "2 CPU | 8GB RAM" diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/template_schema.json b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/template_schema.json index 9c7aec15a3..fc0bad231b 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/template_schema.json +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/template_schema.json @@ -16,8 +16,7 @@ "title": "Linux image", "description": "Select Linux image to use for VM", "enum": [ - "Ubuntu 18.04", - "Ubuntu 18.04 Data Science VM" + "Ubuntu 22.04 LTS" ] }, "vm_size": { diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/apt_sources_config.yml b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/apt_sources_config.yml index 22b3418d5b..35b5b5857b 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/apt_sources_config.yml +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/apt_sources_config.yml @@ -14,6 +14,8 @@ apt: deb [trusted=yes] $PRIMARY $RELEASE main restricted universe multiverse deb [trusted=yes] $PRIMARY $RELEASE-updates main restricted universe multiverse deb [trusted=yes] $SECURITY $RELEASE main restricted universe multiverse - deb [signed-by=/etc/apt/trusted.gpg.d/microsoft.gpg] ${nexus_proxy_url}/repository/microsoft-apt/ubuntu/18.04/prod $RELEASE main + deb [signed-by=/etc/apt/trusted.gpg.d/microsoft.gpg] ${nexus_proxy_url}/repository/microsoft-apt/ubuntu/${apt_sku}/prod $RELEASE main deb [signed-by=/etc/apt/trusted.gpg.d/microsoft.gpg] ${nexus_proxy_url}/repository/microsoft-apt/repos/edge stable main + deb [signed-by=/etc/apt/trusted.gpg.d/microsoft.gpg] ${nexus_proxy_url}/repository/microsoft-apt/repos/vscode stable main + deb [signed-by=/etc/apt/trusted.gpg.d/microsoft.gpg] ${nexus_proxy_url}/repository/microsoft-apt/repos/azure-cli $RELEASE main deb [signed-by=/etc/apt/trusted.gpg.d/docker-archive-keyring.gpg] ${nexus_proxy_url}/repository/docker/ $RELEASE stable diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/get_apt_keys.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/get_apt_keys.sh index 5849eaede3..6e69009525 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/get_apt_keys.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/get_apt_keys.sh @@ -6,6 +6,10 @@ set -o nounset # Uncomment this line to see each command for debugging (careful: this will show secrets!) # set -o xtrace +#remove key if they already exist +sudo rm -f /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg || true +sudo rm -f /etc/apt/trusted.gpg.d/microsoft.gpg || true + # Get Docker Public key from Nexus curl -fsSL "${NEXUS_PROXY_URL}"/repository/docker-public-key/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf index 247c4f77e0..8172ec77bb 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/linuxvm.tf @@ -110,6 +110,8 @@ data "template_file" "vm_config" { FILESHARE_NAME = var.shared_storage_access ? data.azurerm_storage_share.shared_storage[0].name : "" NEXUS_PROXY_URL = local.nexus_proxy_url CONDA_CONFIG = local.selected_image.conda_config ? 1 : 0 + VM_USER = random_string.username.result + APT_SKU = replace(local.apt_sku, ".", "") } } @@ -131,6 +133,7 @@ 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 } } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf index 43a6d5982b..e0281269fd 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/locals.tf @@ -15,7 +15,6 @@ locals { tre_user_resource_id = var.tre_resource_id } nexus_proxy_url = "https://nexus-${data.azurerm_public_ip.app_gateway_ip.fqdn}" - # Load VM SKU/image details from porter.yaml porter_yaml = yamldecode(file("${path.module}/../porter.yaml")) vm_sizes = local.porter_yaml["custom"]["vm_sizes"] @@ -26,4 +25,5 @@ locals { # selected_image_source_refs is an array to enable easy use of a dynamic block selected_image_source_refs = lookup(local.selected_image, "source_image_reference", null) == null ? [] : [local.selected_image.source_image_reference] selected_image_source_id = lookup(local.selected_image, "source_image_name", null) == null ? null : "${var.image_gallery_id}/images/${local.selected_image.source_image_name}" + apt_sku = local.selected_image_source_refs[0]["apt_sku"] } diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/pypi_sources_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/pypi_sources_config.sh index 6d70862655..9380cbc9e1 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/pypi_sources_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/pypi_sources_config.sh @@ -1,5 +1,5 @@ #!/bin/bash -sudo tee /etc/pip.conf > dev/null <<'EOF' +sudo tee /etc/pip.conf > /dev/null <<'EOF' [global] index = ${nexus_proxy_url}/repository/pypi/pypi index-url = ${nexus_proxy_url}/repository/pypi/simple diff --git a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/vm_config.sh b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/vm_config.sh index 7db5f89b82..71d7317545 100644 --- a/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/vm_config.sh +++ b/templates/workspace_services/guacamole/user_resources/guacamole-azure-linuxvm/terraform/vm_config.sh @@ -2,32 +2,94 @@ set -o errexit set -o pipefail -# set -o nounset +set -o nounset # Uncomment this line to see each command for debugging (careful: this will show secrets!) -# set -o xtrace +set -o xtrace # Remove apt sources not included in sources.list file sudo rm -f /etc/apt/sources.list.d/* # Update apt packages from configured Nexus sources -sudo apt-get update - -# Install xrdp so Guacamole can connect via RDP -sudo apt-get install xrdp -y +echo "init_vm.sh: START" +sudo apt update || true +sudo apt upgrade -y +sudo apt install -y gnupg2 software-properties-common apt-transport-https wget dirmngr gdebi-core +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 + +## 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 +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' -# Install desktop environment if image doesn't have one already -if [ "${INSTALL_UI}" -eq 1 ]; then - sudo apt-get install xorg xfce4 xfce4-goodies dbus-x11 x11-xserver-utils -y - echo xfce4-session > ~/.xsession -fi +# Make sure xrdp service starts up with the system +sudo systemctl enable xrdp +sudo service xrdp restart + +## Python 3.8 and Jupyter +sudo apt install -y jupyter-notebook microsoft-edge-dev + +## VS Code +echo "init_vm.sh: VS Code" +sudo apt install -y code +sudo apt install -y gvfs-bin || true + +echo "init_vm.sh: Folders" +sudo mkdir -p /opt/vscode/user-data +sudo mkdir -p /opt/vscode/extensions + +# echo "init_vm.sh: azure-cli" +sudo apt install azure-cli -y + +# TODO: need to look at proxy extentions +## VSCode Extensions +# echo "init_vm.sh: VSCode extensions" +# code --extensions-dir="/opt/vscode/extensions" --user-data-dir="/opt/vscode/user-data" --install-extension ms-python.python +# code --extensions-dir="/opt/vscode/extensions" --user-data-dir="/opt/vscode/user-data" --install-extension REditorSupport.r +# code --extensions-dir="/opt/vscode/extensions" --user-data-dir="/opt/vscode/user-data" --install-extension RDebugger.r-debugger + +# Azure Storage Explorer +sudo apt install gnome-keyring dotnet-sdk-7.0 -y +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 + +## R +echo "init_vm.sh: R Setup" +sudo apt install -y r-base + +# RStudio Desktop +echo "init_vm.sh: RStudio" +wget "${NEXUS_PROXY_URL}"/repository/r-studio-download/electron/jammy/amd64/rstudio-2023.12.1-402-amd64.deb -P /tmp/2204 +wget "${NEXUS_PROXY_URL}"/repository/r-studio-download/electron/focal/amd64/rstudio-2023.12.1-402-amd64.deb -P /tmp/2004 +sudo gdebi --non-interactive /tmp/"${APT_SKU}"/rstudio-2023.12.1-402-amd64.deb # 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 - if [ "${SHARED_STORAGE_ACCESS}" -eq 1 ]; then # Install required packages sudo apt-get install autofs -y @@ -75,6 +137,7 @@ fi ### Anaconda Config if [ "${CONDA_CONFIG}" -eq 1 ]; then + echo "init_vm.sh: Anaconda" export PATH="/anaconda/condabin":$PATH export PATH="/anaconda/bin":$PATH export PATH="/anaconda/envs/py38_default/bin":$PATH @@ -85,11 +148,42 @@ if [ "${CONDA_CONFIG}" -eq 1 ]; then fi # Docker install and config +sudo apt-get remove -y moby-tini || true +sudo apt-get install -y r-base-core sudo apt-get install -y ca-certificates curl gnupg lsb-release -sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin jq +sudo apt-get install -y docker-compose-plugin docker-ce-cli containerd.io jq +sudo apt-get install -y docker-ce jq -n --arg proxy "${NEXUS_PROXY_URL}:8083" '{"registry-mirrors": [$proxy]}' > /etc/docker/daemon.json sudo systemctl daemon-reload sudo systemctl restart docker # R config 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 + +# Jupiter Notebook Config +sudo sed -i -e 's/Terminal=true/Terminal=false/g' /usr/share/applications/jupyter-notebook.desktop + +# Default Browser +sudo update-alternatives --config x-www-browser + +## Cleanup +echo "init_vm.sh: Cleanup" +sudo shutdown -r now + +# Prevent screen timeout +echo "init_vm.sh: Preventing Timeout" +sudo touch /home/"${VM_USER}"/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml +sudo chmod 664 /home/"${VM_USER}"/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml +sudo chown "${VM_USER}":"${VM_USER}" /home/"${VM_USER}"/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml +sudo tee /home/"${VM_USER}"/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml << END + + + + + + + + + + +END