Skip to content

CR: Prod SSRS VNet Integration

Jira: TBD Status: Scheduled Scheduled: 2026-03-31, after 17:00 CDT (after school hours) Owner: Leon Geldenhuys Risk: LOW | Duration: ~30m | Rollback: ~5m

Summary

Enable VNet integration on wa-eshars-prod so the web app can reach vm-ssrs16-prod (SSRS) via its private IP (10.0.0.5) instead of the public IP (23.99.180.223). This removes the dependency on a public IP and is the prod equivalent of the nonprod change validated on 2026-03-25 across all wa-eshars-nonprod slots. Risk is low because the public IP remains in place as a fallback throughout execution — reports continue working at every point.

Background

The wa-eshars-nonprod App Service was previously reaching vm-sql16-np (SSRS, 10.1.0.4) via its public IP. When that public IP was removed on 2026-03-25, all report viewing broke. The fix was to:

  1. Create a dedicated subnet for App Service VNet integration
  2. Add VNet integration to each slot so traffic routes privately
  3. Update the two required app settings (dot-notation + camelCase — both must be set)

That fix was validated across all nonprod slots (dev, qa, regression, uat, trn). This change replicates the exact same pattern in prod.

Scope

ResourceChangeEnvironment
VNet rg-eshars-prodCreate subnet sn-webapp-eshars-prod (10.0.3.0/24) delegated to Microsoft.Web/serverFarmsprod
wa-eshars-prodAdd VNet integration → sn-webapp-eshars-prodprod
wa-eshars-prod app settingsMvcReportViewer.ReportServerUrlhttp://10.0.0.5/ReportServerprod
wa-eshars-prod app settingsMvcReportViewerReportServerUrlhttp://10.0.0.5/ReportServerprod
vm-ssrs16-prod(Optional, post-soak) Remove public IP 23.99.180.223prod

Prerequisites

  • Nonprod validated — all 5 slots working since 2026-03-25
  • Current app setting values documented (see Pre-checks)
  • After-hours window confirmed (after 5 PM CDT, avoid month-end billing window)
  • Azure portal access verified

Procedure

Pre-checks

  1. Note current values of both app settings on wa-eshars-prod:
    • MvcReportViewer.ReportServerUrl — current value: http://23.99.180.223/ReportServer
    • MvcReportViewerReportServerUrl — current value: (verify in portal before execution)
  2. Confirm vm-ssrs16-prod private IP is 10.0.0.5 (Azure Portal → vm-ssrs16-prod → Networking)
  3. Confirm VNet rg-eshars-prod/default has no existing subnet using 10.0.3.0/24

Execution Steps

  1. Create subnet in Azure Portal or CLI:

    • VNet: rg-eshars-prod → Subnets → Add
    • Name: sn-webapp-eshars-prod
    • CIDR: 10.0.3.0/24
    • Delegation: Microsoft.Web/serverFarms
  2. Add VNet integration to wa-eshars-prod:

    • App Service → Networking → VNet Integration → Add
    • Select VNet rg-eshars-prod, subnet sn-webapp-eshars-prod
  3. Update app settings on wa-eshars-prod (App Service → Configuration → Application settings):

    • Set MvcReportViewer.ReportServerUrlhttp://10.0.0.5/ReportServer
    • Set MvcReportViewerReportServerUrlhttp://10.0.0.5/ReportServer
    • Click Save
  4. App Service restarts automatically after saving settings.

Verification

  1. Wait ~60 seconds for restart to complete
  2. Log in to eSHARS prod and navigate to Historical Data → run any report
  3. Verify report renders correctly (no “Service unavailable” or “Unable to connect to remote server” error)
  4. Confirm VNet integration shows Connected in Azure Portal → wa-eshars-prod → Networking
  5. Check Application Insights (ai-eshars-prod) for any spike in errors on report endpoints

Optional: Remove Public IP (post-soak)

Only after 24-48 hours of confirmed stable operation:

  1. In Azure Portal, navigate to vm-ssrs16-prod → Networking → NIC → IP Configurations
  2. Disassociate the public IP 23.99.180.223
  3. Re-test reports end-to-end (should still work via private routing)
  4. Update VM SSRS16 (Production) to reflect removal

Rollback

Trigger: Any report fails to render after step 4 (restart), OR VNet integration status is not “Connected”.

  1. Revert MvcReportViewer.ReportServerUrlhttp://23.99.180.223/ReportServer
  2. Revert MvcReportViewerReportServerUrlhttp://23.99.180.223/ReportServer
  3. Click Save — app restarts automatically
  4. Verify reports work again via public IP

The subnet and VNet integration can remain in place — they cause no harm and save time on a retry.

Risk Assessment

RiskLikelihoodImpactMitigation
Reports fail via private IPLowMediumPublic IP still active — rollback is instant app setting revert (~5 min)
Subnet CIDR conflictVery LowLow10.0.3.0/24 mirrors nonprod pattern; prod VNet has only default (10.0.0.0/24) and AzureBastionSubnet (10.0.1.0/26) confirmed
App restart disruptionLowLowAfter-hours; minimal concurrent users
VNet integration takes effect slowlyLowLowStandard Azure propagation ~60s; extend soak before declaring success

Outcome

Executed:Result:Notes: