Skip to content

Commit 219b95d

Browse files
Merge pull request #99 from NHSDigital/DTOSS-12686-arc-resource-name-hospital-ods
[DTOSS-12686] - Change Arc-enabled server naming convention to include hospital name and ODS code
2 parents 60f85ee + 8910eb9 commit 219b95d

6 files changed

Lines changed: 97 additions & 45 deletions

File tree

docs/deployment/runbooks/onboard-hospital-vm.md

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
- `*.his.arc.azure.com`
1414
- `relay-manbrs-<env>.servicebus.windows.net`
1515
- [ ] Trust ODS code confirmed via the [ODS portal](https://odsportal.nhsbsa.nhs.uk/)
16-
- [ ] PACS vendor confirmed (`sectra` | `fujifilm` | `agfa` | `philips` | `carestream`)
1716
- [ ] NHS region confirmed (`nw` | `neyh` | `mids` | `eoe` | `lon` | `se` | `sw`)
1817
- [ ] Deployment ring agreed with the programme team
1918
- [ ] `arc-onboarding-spn-client-id` and `arc-onboarding-spn-client-secret` retrieved from Key Vault
@@ -22,15 +21,26 @@
2221

2322
## Step 1 — Determine site parameters
2423

24+
The Arc resource name is built automatically from `SiteName`, `ODSCode`, and `Instance`:
25+
26+
```text
27+
gw-<SiteName>-<ODSCode>-<Instance>
28+
```
29+
30+
All lowercase, hyphens only. Azure constraint: max 54 characters (`a-z A-Z 0-9 - _ .`).
31+
2532
| Parameter | Format | Example |
2633
|-----------|--------|---------|
27-
| `SiteCode` | `gw-<ODSCode>-<instance>` | `gw-RVJ-01` |
28-
| `SiteName` | Trust name, hyphen-separated, no spaces | `North-Bristol-NHS-Trust` |
29-
| `NHSRegion` | One of: `nw` `neyh` `mids` `eoe` `lon` `se` `sw` | `sw` |
30-
| `PacsVendor` | One of: `sectra` `fujifilm` `agfa` `philips` `carestream` | `sectra` |
34+
| `SiteName` | Trust name, hyphen-separated, no spaces | `Hull-University-Teaching-Hospitals-NHS-Trust` |
35+
| `ODSCode` | ODS code (uppercase input, lowercased in name) | `RWA` |
36+
| `Instance` | Zero-padded instance number | `01` |
37+
| `NHSRegion` | One of: `nw` `neyh` `mids` `eoe` `lon` `se` `sw` | `neyh` |
3138
| `SiteType` | `static` or `mobile` | `static` |
3239
| `DeploymentRing` | `ring1``ring4` (see below) | `ring1` |
3340

41+
> **Example**: `SiteName=Hull-University-Teaching-Hospitals-NHS-Trust`, `ODSCode=RWA`, `Instance=01`
42+
> → Arc resource name: `gw-hull-university-teaching-hospitals-nhs-trust-rwa-01` (54 chars — at the limit)
43+
3444
**Ring assignments:**
3545

3646
| Ring | Sites |
@@ -43,54 +53,66 @@
4353

4454
## Step 2 — Run Arc onboarding script on the gateway VM
4555

46-
Copy `scripts/powershell/arc-setup.ps1` to the VM and run from an **elevated PowerShell session**:
56+
Copy [`scripts/powershell/arc-setup.ps1`](../../../scripts/powershell/arc-setup.ps1) to the VM and run from an **elevated PowerShell session**.
57+
58+
If script execution is disabled on the VM, allow it for the current session first:
59+
60+
```powershell
61+
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
62+
```
63+
64+
> This only affects the current PowerShell process and does not change the machine-wide policy.
65+
> If the script was downloaded from the internet and is still blocked, see [Script execution blocked](#script-execution-blocked) in Troubleshooting.
4766
4867
```powershell
4968
.\arc-setup.ps1 `
5069
-SubscriptionId "<spoke-subscription-id>" `
5170
-TenantId "<tenant-id>" `
52-
-ResourceGroup "rg-manbgw-<env>-uks-arc-enabled-servers" `
71+
-ResourceGroup "rg-mbsgw-<env>-uks-arc-enabled-servers" `
5372
-Location "uksouth" `
5473
-ServicePrincipalId "<arc-onboarding-spn-client-id>" `
5574
-ServicePrincipalSecret "<arc-onboarding-spn-client-secret>" `
56-
-SiteCode "gw-RVJ-01" `
57-
-SiteName "North-Bristol-NHS-Trust" `
58-
-NHSRegion "sw" `
59-
-PacsVendor "sectra" `
75+
-SiteName "Hull-University-Teaching-Hospitals-NHS-Trust" `
76+
-ODSCode "RWA" `
77+
-Instance "01" `
78+
-NHSRegion "neyh" `
6079
-SiteType "static" `
6180
-DeploymentRing "ring1"
6281
```
6382

6483
The script will:
84+
6585
1. Install the Azure Arc agent (`azcmagent`) if not already present
66-
2. Stamp site metadata as tags on the Arc machine resource
67-
3. Connect the VM to Azure Arc with `--resource-name` set to `SiteCode`
86+
2. Build the Arc resource name: `gw-hull-university-teaching-hospitals-nhs-trust-rwa-01`
87+
3. Stamp site metadata as tags on the Arc machine resource
88+
4. Connect the VM to Azure Arc with `--resource-name` set to the built resource name
6889

6990
Logs are written to `C:\ArcSetup\ArcSetup.log`.
7091

71-
**Verify**: In the Azure portal, navigate to `rg-manbgw-<env>-uks-arc-enabled-servers` → Azure Arc machines → `gw-RVJ-01`. Status should be **Connected**.
92+
**Verify**: In the Azure portal, navigate to `rg-mbsgw-<env>-uks-arc-enabled-servers` → Azure Arc machines → `gw-hull-university-teaching-hospitals-nhs-trust-rwa-01`. Status should be **Connected**.
7293

7394
## Step 3 — Trigger Terraform to provision the Hybrid Connection
7495

7596
Run the ADO pipeline **Deploy Arc Infrastructure - \<env\>** manually. Terraform discovers the new Arc machine and creates:
7697

77-
- `hc-gw-RVJ-01` in the relay namespace (`relay-manbrs-<env>`)
98+
- `hc-gw-hull-university-teaching-hospitals-nhs-trust-rwa-01` in the relay namespace (`relay-manbrs-<env>`)
7899
- `listen` auth rule on that Hybrid Connection
79100

80-
**Verify**: In the Azure portal, navigate to `relay-manbrs-<env>` → Hybrid Connections → `hc-gw-RVJ-01` is present.
101+
**Verify**: In the Azure portal, navigate to `relay-manbrs-<env>` → Hybrid Connections → `hc-gw-hull-university-teaching-hospitals-nhs-trust-rwa-01` is present.
81102

82103
## Step 4 — Deploy the gateway application
83104

84105
Run the ADO pipeline **Deploy Gateway - \<env\>** with:
85106

86-
```
87-
targetSiteCode : gw-RVJ-01
107+
```text
108+
targetSiteCode : gw-hull-university-teaching-hospitals-nhs-trust-rwa-01
88109
releaseTag : latest (or a specific tag, e.g. v1.2.3)
89110
```
90111

91112
The pipeline:
92-
1. Retrieves the listen SAS key for `hc-gw-RVJ-01`
93-
2. Sends an Arc Run Command to `gw-RVJ-01` that writes `.env` and runs `deploy.ps1`
113+
114+
1. Retrieves the listen SAS key for `hc-gw-hull-university-teaching-hospitals-nhs-trust-rwa-01`
115+
2. Sends an Arc Run Command to `gw-hull-university-teaching-hospitals-nhs-trust-rwa-01` that writes `.env` and runs `deploy.ps1`
94116
3. Polls for completion and reports success or failure
95117

96118
## Step 5 — Smoke test
@@ -110,17 +132,17 @@ Check Log Analytics Workspace for an initial heartbeat within 5 minutes of servi
110132
## Parameters reference
111133

112134
| Parameter | Required | Default | Description |
113-
|-----------|----------|---------|-------------|
135+
| --------- | -------- | ------- | ----------- |
114136
| `-SubscriptionId` | Yes || Azure spoke subscription ID |
115137
| `-TenantId` | Yes || Azure Entra tenant ID |
116138
| `-ResourceGroup` | Yes || Arc-enabled servers resource group |
117139
| `-Location` | Yes || Azure region (always `uksouth`) |
118140
| `-ServicePrincipalId` | Yes || Arc onboarding SPN client ID |
119141
| `-ServicePrincipalSecret` | Yes || Arc onboarding SPN client secret |
120-
| `-SiteCode` | No | *(hostname)* | Arc resource name and tag; format `gw-<ODSCode>-<instance>` |
121-
| `-SiteName` | No | *(not set)* | Human-readable trust name; no spaces |
142+
| `-SiteName` | No | *(hostname)* | Trust name, hyphen-separated, no spaces; used to build Arc resource name |
143+
| `-ODSCode` | No | *(hostname)* | ODS code; used to build Arc resource name |
144+
| `-Instance` | No | `01` | Zero-padded instance number; used to build Arc resource name |
122145
| `-NHSRegion` | No | *(not set)* | NHS region code |
123-
| `-PacsVendor` | No | *(not set)* | PACS system vendor |
124146
| `-SiteType` | No | `static` | `static` or `mobile` |
125147
| `-DeploymentRing` | No | `ring0` | Rollout ring (`ring0``ring4`) |
126148

@@ -136,6 +158,26 @@ Check `C:\ArcSetup\ArcSetup.log` on the VM. Common causes:
136158
- **SPN credentials wrong** — verify client ID and secret from Key Vault are current
137159
- **VM already registered** — if the machine was previously connected under a different name, disconnect first: `azcmagent disconnect`
138160

161+
### Script execution blocked
162+
163+
If you see `running scripts is disabled on this system`, run this first in the same elevated session:
164+
165+
```powershell
166+
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
167+
```
168+
169+
If the script was downloaded from the internet and is still blocked (error: `file is not digitally signed`), unblock the zone restriction first:
170+
171+
```powershell
172+
Unblock-File -Path .\arc-setup.ps1
173+
```
174+
175+
If the script is still blocked after `Unblock-File` (e.g. due to a stricter machine policy), use `Unrestricted` instead — still scoped to the current process only:
176+
177+
```powershell
178+
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
179+
```
180+
139181
### Arc machine shows as Disconnected after onboarding
140182

141183
The agent may have lost connectivity. Check:

infrastructure/modules/arc-infra/outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ output "relay_namespace_hostname" {
2929
}
3030

3131
output "relay_listen_sas_keys" {
32-
description = "Per-machine relay listen SAS primary keys, keyed by Arc resource name (SiteCode). Used by the deploy pipeline to write .env files."
32+
description = "Per-machine relay listen SAS primary keys, keyed by Arc resource name. Used by the deploy pipeline to write .env files."
3333
sensitive = true
3434
value = var.enable_arc_servers ? {
3535
for k, rule in azurerm_relay_hybrid_connection_authorization_rule.per_machine_listen :

infrastructure/modules/arc-infra/relay.tf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# The relay namespace is owned by dtos-manage-breast-screening ("manbrs").
22
# This module creates one Hybrid Connection + listen-only auth rule per Arc-enabled
33
# machine, auto-discovered by querying the Arc resource group.
4-
# HC names are derived from the Arc resource name (= SiteCode set at onboarding).
4+
# HC names are derived from the Arc resource name set at onboarding
5+
# (e.g. hc-gw-hull-university-teaching-hospitals-nhs-trust-rwa-01).
56
#
67
# Trigger: run `terraform apply` after each Arc onboarding to pick up new machines.
78

@@ -11,7 +12,8 @@ locals {
1112
}
1213

1314
# Discover all Arc-enabled machines registered in the Arc resource group.
14-
# Each machine's name is the SiteCode set during onboarding (e.g. gw-RVJ-01).
15+
# Each machine's Arc resource name is set during onboarding
16+
# (e.g. gw-hull-university-teaching-hospitals-nhs-trust-rwa-01).
1517
data "azurerm_resources" "arc_machines" {
1618
count = var.enable_arc_servers ? 1 : 0
1719

@@ -33,7 +35,7 @@ locals {
3335
arc_machines = merge(local.arc_machines_discovered, local.arc_machines_static)
3436
}
3537

36-
# One Hybrid Connection per Arc machine (e.g. hc-gw-RVJ-01).
38+
# One Hybrid Connection per Arc machine (e.g. hc-gw-hull-university-teaching-hospitals-nhs-trust-rwa-01).
3739
resource "azurerm_relay_hybrid_connection" "per_machine" {
3840
for_each = local.arc_machines
3941

infrastructure/modules/gateway-test-vm/vm.tf

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,8 @@ resource "azurerm_virtual_machine_run_command" "arc_setup" {
125125

126126
# Site identity tags — stamped onto the Arc resource for Terraform HC discovery
127127
# and ADO pipeline ring targeting. ring0 = test VM only.
128-
parameter {
129-
name = "SiteCode"
130-
value = "${var.app_short_name}-${var.env_config}"
131-
}
132-
128+
# SiteName/ODSCode/Instance are not passed; the script falls back to the machine
129+
# hostname (computer_name = mbsgw-<env>) as the Arc resource name.
133130
parameter {
134131
name = "SiteType"
135132
value = "static"

infrastructure/terraform/outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ output "relay_namespace_hostname" {
44
}
55

66
output "relay_listen_sas_keys" {
7-
description = "Per-machine relay listen SAS primary keys, keyed by Arc resource name (SiteCode)"
7+
description = "Per-machine relay listen SAS primary keys, keyed by Arc resource name"
88
sensitive = true
99
value = module.arc_infra.relay_listen_sas_keys
1010
}

scripts/powershell/arc-setup.ps1

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ param(
88
[string]$ServicePrincipalId,
99
[string]$ServicePrincipalSecret,
1010
# Site identity - controls the Arc resource name and Azure tags.
11-
# SiteCode becomes the Arc machine name in Azure (e.g. gw-RVJ-01).
12-
# Defaults to the machine hostname when not supplied (test/dev use).
13-
[string]$SiteCode = "", # e.g. gw-RVJ-01 (ODS code + instance)
11+
# Resource name is built as gw-<SiteName>-<ODSCode>-<Instance> (all lowercase).
12+
# e.g. gw-north-bristol-nhs-trust-rvj-01
13+
# Defaults to the machine hostname when SiteName/ODSCode/Instance are not supplied (test/dev use).
1414
[string]$SiteName = "", # e.g. North-Bristol-NHS-Trust (no spaces)
15+
[string]$ODSCode = "", # e.g. RVJ
16+
[string]$Instance = "01", # zero-padded instance number
1517
[string]$NHSRegion = "", # nw|neyh|mids|eoe|lon|se|sw
16-
[string]$PacsVendor = "", # sectra|fujifilm|agfa|philips|carestream
1718
[string]$SiteType = "static", # static|mobile
1819
[string]$DeploymentRing = "ring0" # ring0|ring1|ring2|ring3|ring4
1920
)
@@ -35,10 +36,10 @@ try {
3536
Write-Log "=========================================" "INFO"
3637
Write-Log "Azure Arc Combined Setup Started" "INFO"
3738
Write-Log "=========================================" "INFO"
38-
Write-Log "SiteCode : $(if ($SiteCode) { $SiteCode } else { '(hostname)' })" "INFO"
3939
Write-Log "SiteName : $(if ($SiteName) { $SiteName } else { '(not set)' })" "INFO"
40+
Write-Log "ODSCode : $(if ($ODSCode) { $ODSCode } else { '(not set)' })" "INFO"
41+
Write-Log "Instance : $Instance" "INFO"
4042
Write-Log "NHSRegion : $(if ($NHSRegion) { $NHSRegion } else { '(not set)' })" "INFO"
41-
Write-Log "PacsVendor : $(if ($PacsVendor) { $PacsVendor } else { '(not set)' })" "INFO"
4243
Write-Log "SiteType : $SiteType" "INFO"
4344
Write-Log "DeploymentRing : $DeploymentRing" "INFO"
4445
Write-Log "=========================================" "INFO"
@@ -142,16 +143,26 @@ try {
142143
Write-Log "Resource Group: $ResourceGroup" "INFO"
143144
Write-Log "Location : $Location" "INFO"
144145

146+
# Build the Arc resource name from structured inputs (all lowercase).
147+
# Format: gw-<SiteName>-<ODSCode>-<Instance>, e.g. gw-hull-university-teaching-hospitals-nhs-trust-rwa-01
148+
# Azure constraint: a-z A-Z 0-9 - _ . and max 54 characters.
149+
# Falls back to the machine hostname when SiteName/ODSCode are not supplied (test/dev use).
150+
$ResourceName = if ($SiteName -and $ODSCode) {
151+
"gw-$($SiteName.ToLower())-$($ODSCode.ToLower())-$Instance"
152+
} else { "" }
153+
154+
if ($ResourceName) { Write-Log "ResourceName : $ResourceName" "INFO" }
155+
145156
# Build tags - all site metadata is stamped onto the Arc resource for Terraform
146157
# discovery and ADO pipeline targeting. SiteName must not contain spaces.
147158
$tags = "ArcSQLServerExtensionDeployment=Disabled"
148159
$tags += ",Programme=BreastScreening"
149160
$tags += ",SiteType=$SiteType"
150161
$tags += ",DeploymentRing=$DeploymentRing"
151-
if ($SiteCode) { $tags += ",SiteCode=$SiteCode" }
152-
if ($SiteName) { $tags += ",SiteName=$SiteName" }
153-
if ($NHSRegion) { $tags += ",NHSRegion=$NHSRegion" }
154-
if ($PacsVendor) { $tags += ",PacsVendor=$PacsVendor" }
162+
if ($SiteName) { $tags += ",SiteName=$SiteName" }
163+
if ($ODSCode) { $tags += ",ODSCode=$ODSCode" }
164+
if ($Instance) { $tags += ",Instance=$Instance" }
165+
if ($NHSRegion) { $tags += ",NHSRegion=$NHSRegion" }
155166

156167
# Build connect arguments. --resource-name sets the Azure resource name,
157168
# overriding the default (hostname). Required for meaningful HC naming in Terraform.
@@ -167,7 +178,7 @@ try {
167178
'--correlation-id', $CorrelationId,
168179
'--tags', $tags
169180
)
170-
if ($SiteCode) { $connectArgs += @('--resource-name', $SiteCode) }
181+
if ($ResourceName) { $connectArgs += @('--resource-name', $ResourceName) }
171182

172183
& "$azcmagentExe" @connectArgs
173184

0 commit comments

Comments
 (0)