diff --git a/templates/workspace_services/azureml/porter.yaml b/templates/workspace_services/azureml/porter.yaml index 1d4b45d7b8..56aa900abb 100644 --- a/templates/workspace_services/azureml/porter.yaml +++ b/templates/workspace_services/azureml/porter.yaml @@ -1,7 +1,7 @@ --- schemaVersion: 1.0.0 name: tre-service-azureml -version: 0.8.10 +version: 0.9.0 description: "An Azure TRE service for Azure Machine Learning" registry: azuretre dockerfile: Dockerfile.tmpl @@ -75,6 +75,11 @@ outputs: applyTo: - install - upgrade + - name: azureml_acr_name + type: string + applyTo: + - install + - upgrade - name: azureml_storage_account_id type: string applyTo: @@ -117,6 +122,7 @@ outputs: - upgrade mixins: + - exec - terraform: clientVersion: 1.3.6 - az: @@ -137,6 +143,7 @@ install: auth_client_id: ${ bundle.credentials.auth_client_id } auth_client_secret: ${ bundle.credentials.auth_client_secret } auth_tenant_id: ${ bundle.credentials.auth_tenant_id } + public_access_enabled: true arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } backendConfig: @@ -147,18 +154,138 @@ install: outputs: - name: azureml_workspace_name - name: azureml_acr_id + - name: azureml_acr_name + - name: core_location - name: azureml_storage_account_id - name: connection_uri + - name: internal_connection_uri - name: workspace_address_spaces - name: aml_subnet_address_prefixes - name: storage_tag - name: batch_tag - name: mcr_tag + - name: azure_endpoint + - name: aml_fqdn + + - az: + description: "Login to Azure" + arguments: + - login + flags: + identity: + username: ${ bundle.credentials.azure_client_id } + + - az: + description: "Build and push private AML image via ACR Tasks" + arguments: + - acr + - build + - ./terraform/private_image/ + flags: + registry: ${ bundle.outputs.azureml_acr_name } + image: aml-tre-nexus-image + build-arg: "TRE_LOCATION=${ bundle.outputs.core_location } --build-arg TRE_ID=${ bundle.parameters.tre_id } --build-arg AZURE_ENDPOINT=${ bundle.outputs.azure_endpoint }" + + - terraform: + description: "Update ACR to close network" + vars: + workspace_id: ${ bundle.parameters.workspace_id } + tre_id: ${ bundle.parameters.tre_id } + tre_resource_id: ${ bundle.parameters.id } + display_name: ${ bundle.parameters.display_name } + description: ${ bundle.parameters.description } + address_space: ${ bundle.parameters.address_space } + is_exposed_externally: ${ bundle.parameters.is_exposed_externally } + arm_tenant_id: ${ bundle.credentials.azure_tenant_id } + auth_client_id: ${ bundle.credentials.auth_client_id } + auth_client_secret: ${ bundle.credentials.auth_client_secret } + auth_tenant_id: ${ bundle.credentials.auth_tenant_id } + public_access_enabled: false + arm_environment: ${ bundle.parameters.arm_environment } + azure_environment: ${ bundle.parameters.azure_environment } + backendConfig: + resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } + storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } + container_name: ${ bundle.parameters.tfstate_container_name } + key: tre-service-azureml-${ bundle.parameters.id } + outputs: + - name: azureml_workspace_name + - name: azureml_acr_id + - name: azureml_acr_name + - name: azureml_storage_account_id + - name: connection_uri + - name: workspace_address_spaces + - name: aml_subnet_address_prefixes + - name: storage_tag + - name: batch_tag + - name: mcr_tag + - name: azure_endpoint - name: aml_fqdn upgrade: - terraform: - description: "Upgrade Azure ML Service" + description: "Upgrade Azure ML Service, with open network" + vars: + workspace_id: ${ bundle.parameters.workspace_id } + tre_id: ${ bundle.parameters.tre_id } + tre_resource_id: ${ bundle.parameters.id } + display_name: ${ bundle.parameters.display_name } + description: ${ bundle.parameters.description } + address_space: ${ bundle.parameters.address_space } + is_exposed_externally: ${ bundle.parameters.is_exposed_externally } + arm_tenant_id: ${ bundle.credentials.azure_tenant_id } + auth_client_id: ${ bundle.credentials.auth_client_id } + auth_client_secret: ${ bundle.credentials.auth_client_secret } + auth_tenant_id: ${ bundle.credentials.auth_tenant_id } + public_access_enabled: true + arm_environment: ${ bundle.parameters.arm_environment } + azure_environment: ${ bundle.parameters.azure_environment } + backendConfig: + resource_group_name: ${ bundle.parameters.tfstate_resource_group_name } + storage_account_name: ${ bundle.parameters.tfstate_storage_account_name } + container_name: ${ bundle.parameters.tfstate_container_name } + key: tre-service-azureml-${ bundle.parameters.id } + outputs: + - name: azureml_workspace_name + - name: azureml_acr_id + - name: azureml_acr_name + - name: core_location + - name: azureml_storage_account_id + - name: connection_uri + - name: workspace_address_spaces + - name: aml_subnet_address_prefixes + - name: storage_tag + - name: batch_tag + - name: mcr_tag + - name: azure_endpoint + - name: aml_fqdn + + - exec: + command: sleep # wait for public network access to _actually_ take effect + arguments: + - "30" + + - az: + description: "Login to Azure" + arguments: + - login + flags: + identity: + username: ${ bundle.credentials.azure_client_id } + + - az: + description: "Build and push private AML image via ACR Tasks" + arguments: + - acr + - build + - ./terraform/private_image/ + flags: + registry: ${ bundle.outputs.azureml_acr_name } + image: aml-tre-nexus-image + build-arg: "TRE_LOCATION=${ bundle.outputs.core_location } --build-arg TRE_ID=${ bundle.parameters.tre_id } --build-arg AZURE_ENDPOINT=${ bundle.outputs.azure_endpoint }" + + - terraform: + description: "Update ACR to close network" vars: workspace_id: ${ bundle.parameters.workspace_id } tre_id: ${ bundle.parameters.tre_id } @@ -171,6 +298,7 @@ upgrade: auth_client_id: ${ bundle.credentials.auth_client_id } auth_client_secret: ${ bundle.credentials.auth_client_secret } auth_tenant_id: ${ bundle.credentials.auth_tenant_id } + public_access_enabled: false arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } backendConfig: @@ -181,13 +309,16 @@ upgrade: outputs: - name: azureml_workspace_name - name: azureml_acr_id + - name: azureml_acr_name - name: azureml_storage_account_id - name: connection_uri + - name: internal_connection_uri - name: workspace_address_spaces - name: aml_subnet_address_prefixes - name: storage_tag - name: batch_tag - name: mcr_tag + - name: azure_endpoint - name: aml_fqdn uninstall: @@ -205,6 +336,7 @@ uninstall: auth_client_id: ${ bundle.credentials.auth_client_id } auth_client_secret: ${ bundle.credentials.auth_client_secret } auth_tenant_id: ${ bundle.credentials.auth_tenant_id } + public_access_enabled: false arm_environment: ${ bundle.parameters.arm_environment } azure_environment: ${ bundle.parameters.azure_environment } backendConfig: diff --git a/templates/workspace_services/azureml/terraform/acr.tf b/templates/workspace_services/azureml/terraform/acr.tf index a0de2fca71..984d57820f 100644 --- a/templates/workspace_services/azureml/terraform/acr.tf +++ b/templates/workspace_services/azureml/terraform/acr.tf @@ -1,13 +1,14 @@ +resource "azurerm_container_registry" "acr" { + name = local.acr_name + location = data.azurerm_resource_group.ws.location + resource_group_name = data.azurerm_resource_group.ws.name + sku = "Premium" + admin_enabled = false + # Allows porter to run once with network open, upload an image, then run again to close the network + public_network_access_enabled = var.public_access_enabled -resource "azurerm_container_registry" "acr" { - name = local.acr_name - location = data.azurerm_resource_group.ws.location - resource_group_name = data.azurerm_resource_group.ws.name - sku = "Premium" - admin_enabled = false - public_network_access_enabled = false - tags = local.tre_workspace_service_tags + tags = local.tre_workspace_service_tags lifecycle { ignore_changes = [tags] } } @@ -37,6 +38,4 @@ resource "azurerm_private_endpoint" "acrpe" { is_manual_connection = false subresource_names = ["registry"] } - } - diff --git a/templates/workspace_services/azureml/terraform/data.tf b/templates/workspace_services/azureml/terraform/data.tf index 0612a9d634..05ad526866 100644 --- a/templates/workspace_services/azureml/terraform/data.tf +++ b/templates/workspace_services/azureml/terraform/data.tf @@ -2,6 +2,10 @@ data "azurerm_resource_group" "ws" { name = "rg-${var.tre_id}-ws-${local.short_workspace_id}" } +data "azurerm_resource_group" "core" { + name = "rg-${var.tre_id}" +} + data "azurerm_virtual_network" "ws" { name = "vnet-${var.tre_id}-ws-${local.short_workspace_id}" resource_group_name = data.azurerm_resource_group.ws.name diff --git a/templates/workspace_services/azureml/terraform/outputs.tf b/templates/workspace_services/azureml/terraform/outputs.tf index 48a152634f..fb64f8e723 100644 --- a/templates/workspace_services/azureml/terraform/outputs.tf +++ b/templates/workspace_services/azureml/terraform/outputs.tf @@ -6,6 +6,14 @@ output "azureml_acr_id" { value = azurerm_container_registry.acr.id } +output "azureml_acr_name" { + value = azurerm_container_registry.acr.name +} + +output "core_location" { + value = data.azurerm_resource_group.core.location +} + output "azureml_storage_account_id" { value = azurerm_storage_account.aml.id } @@ -55,3 +63,7 @@ output "mcr_tag" { output "batch_tag" { value = data.azurerm_network_service_tags.batch_tag.id } + +output "azure_endpoint" { + value = var.azure_environment == "AzureGovCloud" ? "cloudapp.usgovcloudapi.net" : "cloudapp.azure.com" +} diff --git a/templates/workspace_services/azureml/terraform/private_image/Dockerfile b/templates/workspace_services/azureml/terraform/private_image/Dockerfile new file mode 100644 index 0000000000..f38b0bd1c8 --- /dev/null +++ b/templates/workspace_services/azureml/terraform/private_image/Dockerfile @@ -0,0 +1,23 @@ +# https://github.com/Azure/AzureML-Containers/blob/master/base/cpu/openmpi4.1.0-ubuntu22.04/Dockerfile + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +FROM mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu22.04@sha256:2c217d40498433d578cd4ec6cc519b49b324da34aca1e0df1930e1552c89af7d + +ARG TRE_ID +ARG TRE_LOCATION +ARG AZURE_ENDPOINT +ENV NEXUS_PROXY_URL="https://nexus-${TRE_ID}.${TRE_LOCATION}.${AZURE_ENDPOINT}" + +# Set Nexus Conda +ENV PATH="/anaconda/condabin":$PATH +ENV PATH="/anaconda/bin":$PATH +ENV PATH="/anaconda/envs/py38_default/bin":$PATH + +RUN 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 + +# Set PyPi sources +RUN printf "[global]\nindex = %s/repository/pypi/pypi\nindex-url = %s/repository/pypi/simple\ntrusted-host = %s\n" "${NEXUS_PROXY_URL}" "${NEXUS_PROXY_URL}" "${NEXUS_PROXY_URL}" >> /etc/pip.conf diff --git a/templates/workspace_services/azureml/terraform/variables.tf b/templates/workspace_services/azureml/terraform/variables.tf index a47b5588ff..8a85f2d4d4 100644 --- a/templates/workspace_services/azureml/terraform/variables.tf +++ b/templates/workspace_services/azureml/terraform/variables.tf @@ -35,6 +35,10 @@ variable "auth_client_secret" { sensitive = true description = "Used to authenticate into the AAD Tenant to get app role members" } +variable "public_access_enabled" { + type = bool + default = false +} variable "arm_environment" { type = string