Skip to content

Deployment

Vincent Balbarin edited this page May 5, 2025 · 26 revisions

What you'll need

You can use Azure Cloud Shell which comes preloaded with all necessary tools. If you prefer to use your own workstation.

Windows

  • Bicep

    Install Bicep using winget install -e -h -s winget --id Microsoft.Bicep.

  • VS Code, preferably with the Bicep and PowerShell extensions

    Recommended VS Code extensions:

    • Bicep
    • PowerShell

    Install VS Code using winget install -e -h -s winget --id Microsoft.VisualStudioCode --override '/SILENT /mergetasks="!runcode,addcontextmenufiles,addcontextmenufolders"'.

  • PowerShell 7

    Install PowerShell 7 using winget install -e -h -s winget --id Microsoft.PowerShell.

  • The Az PowerShell modules

    Install the Az modules using Install-Module Az.

Linux

  • Bicep
curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64
chmod +x ./bicep
sudo mv ./bicep /usr/local/bin/bicep
  • Powershell 7

Debian-based:

sudo apt-get update
sudo apt-get install -y wget
source /etc/os-release
wget -q https://packages.microsoft.com/config/debian/$VERSION_ID/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell

Fedora-based:

# Get version of RHEL
source /etc/os-release
if [ ${VERSION_ID%.*} -lt 8 ]
then majorver=7
elif [ ${VERSION_ID%.*} -lt 9 ]
then majorver=8
else majorver=9
fi

curl -sSL -O https://packages.microsoft.com/config/rhel/$majorver/packages-microsoft-prod.rpm
sudo rpm -i packages-microsoft-prod.rpm
rm packages-microsoft-prod.rpm
sudo dnf -y update
# Install PowerShell
sudo dnf -y install powershell
  • The Az PowerShell Modules

Launch a new PowerShell shell session

pwsh
Install-Module Az

Optional, but strongly recommended

Create a Key Vault to hold certain deployment time secrets, such as the usernames and passwords for VMs and domain.

Getting started

The simplest deployment of a hub and spoke secure research enclave is depicted below.

It implements research hub to which research spoke VNETs are peered. An Azure Firewall provides traffic control and routing for the peered spokes. The research hub virtual network is isolated from an enterprise network; if desired, its virtual network can be peered with the enterprise connectivity hub and use it transit over ExpressRoute or Site-to-Site VPN.

The research spoke workloads are hosted on Entra joined AVD session hosts for the researcher VMs and. hybrid AD/Entra identities for researchers and honest brokers (i.e., data custodians, data brokers, etc.).

(Please note, although line of site between the session hosts and a local Windows active directory is not required, one should create universal security groups for researchers and honest brokers and populate them with the domain/hybrid accounts on the on premise AD before synchronizing to Entra.)

The spoke contains the AirLock feature that allows approved data into the research environment and data transfer out after approval by a data custodian or honest broker.

HubAndSpokeSREEntraID

  1. Clone this repo; or fork it to your account and then clone.
  2. Open the cloned repo with VS Code. If using Cloud Shell, you don't need to open the entire repo.
  3. If using VS Code, open a PowerShell 7 (pwsh) terminal.

Gather info: network address space, security group, AD information (if using AD auth)

Deploying the hub

  1. Create a bicepparam file.
using './main.bicep'

/*
* A sample parameter file for Research Hub deployment using Entra ID for authentication.
*/

param sequence = 1
param environment = 'demo'
param namingConvention = '{workloadName}-{subWorkloadName}-{env}-{rtype}-{loc}-{seq}'
param workloadName = 'ResHub'
param logonType = 'entraID'

param tags = {
  'customer-reference': 'CustomerName'
  environment: 'demo'
}

param deployVpn = false
param researchVmsAreSessionHosts = true

param addAutoDateCreatedTag = false
param addDateModifiedTag = true

// Must be /23 or larger
param networkAddressSpace = '10.1.0.0/23'
param customDnsIPs = []

// Supernet to facilitate configuration of Azure firewall Rules
// This should contain the entire address space comprised by hub and all the spokes.
param ipAddressPool = ['10.1.0.0/16']

param enableAvmTelemetry = true
  1. Ensure you're logged in to Azure with an account with the appropriate permissions on your research hub subscription. Owner is the recommended role (because RBAC assignments are made), but User Access Administrator combined with Contributor also works.

  2. Execute the deployment using the deploy.ps1 file with the following required parameters:

    • -TemplateParameterFile
    • -TargetSubscriptionId
    • -Location

    The script supports the -WhatIf and -Verbose parameters.

Deploying a spoke

  1. Navigate to the research spoke directory.
pushd ./research-spoke
  1. Create a wrapper to facilitate deploying the spoke by creating a new file deploy.user.ps1 with the following contents:
// file: deploy.user.ps1
// Replace the values in <value>
$params = @{
    TemplateParameterFile = "./main.bicepparam"
    TargetSubscriptionId = "<value>"
    Location = "<value>"
}
./deploy.ps1 @params -verbose
  1. Create a new main.bicepparam file
using './main.bicep'
param sequence = 1

// For interactive deployments, replace <value> with the results of
// $(iwr 'https://ipecho.net/plain').Content
var myIpAddress = '<value>'

param debugMode = false
param debugRemoteIp = myIpAddress
param debugPrincipalId = ''

param publicStorageAccountAllowedIPs = [myIpAddress]

// Set these values based on the output of the hub deployment
param hubFirewallIp = '<value>'
param hubVNetResourceId = '<value>'
param hubPrivateDnsZonesResourceGroupId = '<value>'
//

param location = '<value>'
param workloadName = 'ResPrjA'
param environment = 'demo'
param tags = {environment: 'demo'}

param namingConvention = '{workloadName}-{subWorkloadName}-{env}-{rtype}-{loc}-{seq}'

param networkAddressSpaces = ['10.1.${sequence + 1}.0/24']
param customDnsIps = []

param researcherEntraIdObjectId = '<value>'
param adminEntraIdObjectId = '<value>'
param logonType = 'entraID'

param filesIdentityType = logonType == 'entraID' ? 'AADKERB' : 'None'

param desktopAppGroupFriendlyName = 'Research Spoke: ${workloadName} ${sequence}'
param workspaceFriendlyName = 'Research Spoke: ${workloadName} ${sequence}'
param useSessionHostAsResearchVm = true
param sessionHostCount = 1


// Because Research VMs are AVD session hosts in the spoke, the following are required.
param sessionHostLocalAdminUsername = 'srvadmin'
param sessionHostLocalAdminPassword = '<value>'

param sessionHostSize = 'Standard_D2as_v5'

// Optional filter to ignore files without the extensions listed when placed into the ingest blob container.
param allowedIngestFileExtensions = ['.zip', '.tar.gz']

param airlockApproverEmail = '<value>'

param isAirlockReviewCentralized = false
// Leave the next three parameter values empty if not using a centralized airlock review
param centralAirlockFileShareName = ''
param centralAirlockKeyVaultId = ''
param centralAirlockStorageAccountId = ''

// Because, sys.utcnow() Bicep function is not idempotent across deployments
// run the following snippet in Powershell to set the value:
//     Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%SZ' 
param encryptionKeyExpirySeed = '<value>'

Post-Deployment Manual Steps

A few manual steps that need to be performed to allow hybrid Entra users and the managed identities associated with the data airlock automation to access the storage accounts.

The multi-session Windows 11 AVD session hosts need to be configured to enable retrieval of Entra Kerberos

Clone this wiki locally