Provisions an Azure Health Data Services workspace — the parent container and HIPAA / HITRUST compliance boundary for FHIR, DICOM, and MedTech service instances. Targets
hashicorp/azurerm ~> 4.0.
- 🏥 Creates a single
azurerm_healthcare_workspace— the logical container for all your Azure Health Data Services instances. - 🛡️ Establishes the HIPAA / HITRUST compliance boundary within which protected health information (PHI) travels.
- 🧱 Keeps the workspace deliberately minimal: FHIR, DICOM, and MedTech services are separate sibling modules created inside this workspace.
- 🔗 Emits the workspace
idfirst so child service modules, private endpoints, diagnostics, and role assignments can wire to it. - 🏷️ Carries the universal
tagsandtimeoutstail, and nothing else — there are no exposure knobs to misconfigure.
💡 Why it matters: In Azure Health Data Services the workspace must exist before any FHIR/DICOM/MedTech service can be created, and it is the boundary that regulators care about. Getting the workspace right — correct region, correct resource group, consistent tagging — is the foundation every downstream health-data service inherits.
If this module saves you time, please consider supporting its continued development:
- ⭐ Star the repository on GitHub.
- 🤝 Connect on LinkedIn: linkedin.com/in/microsoftexpert
- ☕ Buy me a coffee: buymeacoffee.com/microsoftexpert
flowchart LR
rg["terraform-azurerm-resource-group"]
ws["terraform-azurerm-healthcare-workspace: the family keystone for Health Data Services"]
fhir["terraform-azurerm-healthcare-fhir-service: the clinical data store"]
dicom["terraform-azurerm-healthcare-dicom-service: imaging studies, DICOMweb"]
medtech["terraform-azurerm-healthcare-medtech-service: device telemetry to FHIR, owns its FHIR destinations"]
legacy["terraform-azurerm-healthcare-service: DEPRECATED Azure API for FHIR, retires 2026-09-30, NOT in a workspace"]
ehns["terraform-azurerm-eventhub-namespace: device messages, consumed BY NAME"]
kv["terraform-azurerm-key-vault: customer-managed keys"]
sa["terraform-azurerm-storage-account: DICOM bring-your-own storage, and FHIR export"]
acr["terraform-azurerm-container-registry: convert-data templates"]
ra["terraform-azurerm-role-assignments: the grants each service identity needs, plus FHIR and DICOM data roles"]
pe["terraform-azurerm-private-endpoint: private ingress. REQUIRED once public access is closed."]
rg -->|"resource_group_name, location"| ws
ws -->|"id, BY ID"| fhir
ws -->|"id, BY ID"| dicom
ws -->|"id, BY ID"| medtech
ehns -->|"namespace, hub and consumer group BY NAME"| medtech
fhir -->|"id as a destination_fhir_service_id"| medtech
kv -->|"encryption_key_url"| dicom
kv -->|"VERSIONLESS key id"| legacy
sa -->|"bring-your-own storage BY ID"| dicom
sa -->|"export account BY NAME"| fhir
acr -->|"login server for convert-data"| fhir
fhir -->|"identity_principal_id"| ra
dicom -->|"identity_principal_id"| ra
medtech -->|"identity_principal_id"| ra
ra -->|"Event Hubs Data Receiver plus FHIR Data Writer"| medtech
ra -->|"AcrPull plus Storage Blob Data Contributor"| fhir
ra -->|"key and storage grants"| dicom
pe -->|"reach the service privately"| fhir
pe -->|"reach the service privately"| dicom
legacy -->|"MIGRATE TO: workspace plus fhir-service"| ws
classDef me fill:#0078D4,stroke:#004578,color:#fff;
classDef keystone fill:#004578,stroke:#001f3f,color:#fff;
classDef dep fill:#8a1c1c,stroke:#5c1010,color:#fff;
classDef sib fill:#eef2f7,stroke:#b8c4d0,color:#1b1b1b;
class ws keystone;
class fhir,dicom,medtech me;
class legacy dep;
class rg,ehns,kv,sa,acr,ra,pe sib;
The workspace is the parent container. FHIR, DICOM, and MedTech services are separate modules that reference this workspace by id; the workspace itself owns none of them.
flowchart LR
subgraph inputs["Inputs"]
n["name"]
rgn["resource_group_name"]
loc["location"]
tg["tags"]
to["timeouts"]
end
ws["azurerm_healthcare_workspace.this"]
subgraph outputs["Outputs"]
oid["id"]
onm["name"]
org["resource_group_name"]
oloc["location"]
opec["private_endpoint_connections"]
end
n -->|"name"| ws
rgn -->|"resource_group_name"| ws
loc -->|"location"| ws
tg -->|"tags"| ws
to -->|"timeouts"| ws
ws -->|"id"| oid
ws -->|"name"| onm
ws -->|"resource_group_name"| org
ws -->|"location"| oloc
ws -->|"private_endpoint_connection"| opec
classDef keystone fill:#004578,stroke:#002b4d,color:#fff;
classDef io fill:#eef2f7,stroke:#b8c4d0,color:#1b2733;
class ws keystone;
class n,rgn,loc,tg,to,oid,onm,org,oloc,opec io;
Resource inventory
| Resource | Count | Role |
|---|---|---|
azurerm_healthcare_workspace.this |
1 | The keystone workspace / compliance boundary. |
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
| azurerm provider | ~> 4.0 |
| Provider block | None in this module — the caller configures provider "azurerm" { features {} }, auth, and subscription. |
Schema notes that bite (verified against the live provider schema):
nameis force-new — renaming the workspace destroys and recreates it (and requires every child service to be gone first).resource_group_nameis force-new — moving the workspace to another resource group replaces it.locationis force-new — the region is fixed at creation; child services must live in the same region.- The workspace exposes no
public_network_access_enabled, customer-managed-key, oridentity {}arguments. Those data-plane controls belong to the child FHIR/DICOM/MedTech services, not the workspace. - 🔴
private_endpoint_connectionis computed (read-only) and never populated at azurerm 4.81.0 -- the provider's flatten builds each entry and then discards it without appending, so the attribute is always an empty set however many private endpoints are approved. Nothing errors; an empty value simply reads as "none exist". Private endpoints are still created by a sibling module and still work; only this attribute is blind to them.
Contributoron the target resource group, or a custom role withMicrosoft.HealthcareApis/workspaces/*plus the resource-group read actions, scoped to the resource group. This covers create, update, and delete of the workspace.- Data-plane roles for the child services (for example
FHIR Data Contributor,DICOM Data Owner) are assigned separately against the child service scopes and are out of scope for this module.
- An existing resource group in a supported US Azure region.
- The
Microsoft.HealthcareApisresource provider registered on the target subscription. - The caller configures the
provider "azurerm" { features {} }block, authentication, and subscription; this module declares none of them.
terraform-azurerm-healthcare-workspace/
├── providers.tf # required_version >= 1.12.0; azurerm ~> 4.0; no provider block
├── variables.tf # name, resource_group_name, location + tags/timeouts tail
├── main.tf # keystone azurerm_healthcare_workspace.this
├── outputs.tf # id first, then name, resource_group_name, location, connections
├── README.md # this document
├── SCOPE.md # the cross-module contract
├── LICENSE # MIT
└── .gitignore
provider "azurerm" {
features {}
}
module "healthcare_workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
tags = {
environment = "prod"
data_class = "phi"
}
}ℹ️ The caller owns the provider: authentication, subscription, and the mandatory
features {}block all live in the root module. Pin the module with?ref=v1.0.0, never a branch.
Consumes
| Input | Type | Source module |
|---|---|---|
resource_group_name |
string |
terraform-azurerm-resource-group (name) |
location |
string |
caller / terraform-azurerm-resource-group (location) |
Emits
| Output | Description | Consumed by |
|---|---|---|
id |
Workspace Resource ID (first) | child FHIR / DICOM / MedTech modules, private endpoints, diagnostics, role assignments |
name |
Workspace name | diagnostics / tagging |
resource_group_name |
Resource group holding the workspace | compositions wiring child services |
location |
Workspace region | child service placement (must match) |
private_endpoint_connections |
🔴 Always an empty set at azurerm 4.81.0 — the provider's flatten discards every entry. | do not use for topology documentation |
The examples below reference existing resources by ID or name rather than creating them; this module owns only its own resource. Those references are declared inputs:
variable "logs_id" {
description = "id of an existing logs that these examples reference but do not create."
type = string
}
variable "network_subnet_ids" {
description = "subnet ids of an existing network that these examples reference but do not create."
type = map(string)
}1 · Minimal workspace (the smallest real call)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}💡 The empty call already produces the compliance boundary. There is nothing to lock down on the workspace itself — data-plane security lives on the child services.
2 · Workspace with governance tags
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
tags = {
environment = "prod"
data_class = "phi"
cost_center = "clinical-platform"
compliance = "hipaa-hitrust"
}
}🔒 Tag PHI-bearing resources consistently — downstream policy and cost reporting rely on it.
3 · Custom operation timeouts
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
timeouts = {
create = "30m"
delete = "30m"
}
}ℹ️ Deleting a workspace can be slow when child services were only recently removed; a longer
deletetimeout avoids spurious failures.
4 · A second workspace in a paired region
module "workspace_primary" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophieast"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
module "workspace_secondary" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophiwest"
resource_group_name = "rg-health-westus2"
location = "westus2"
}
⚠️ Region is immutable. Model multi-region topologies as separate workspace instances, never by changinglocationon an existing one.
5 · One workspace per environment with for_each
locals {
workspaces = {
dev = { name = "contosophidev", rg = "rg-health-dev", location = "eastus2" }
test = { name = "contosophitest", rg = "rg-health-test", location = "eastus2" }
prod = { name = "contosophiprod", rg = "rg-health-prod", location = "eastus" }
}
}
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
for_each = local.workspaces
name = each.value.name
resource_group_name = each.value.rg
location = each.value.location
tags = {
environment = each.key
data_class = "phi"
}
}💡 Keying by a stable environment name means adding or removing one environment never re-indexes the others.
6 · Naming convention at scale
variable "workspaces" {
type = map(object({
location = string
}))
default = {
clinical = { location = "eastus" }
research = { location = "eastus2" }
imaging = { location = "centralus" }
}
}
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
for_each = var.workspaces
name = "phi${each.key}01"
resource_group_name = "rg-health-${each.key}"
location = each.value.location
}ℹ️ Workspace names are 1-24 characters, lowercase letters and digits only (the provider's validator is
^[a-z0-9]{1,24}$). Uppercase is rejected, and one- and two-character names are legal. No hyphens or underscores. Compose names accordingly.
7 · Attaching a FHIR service (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# FHIR service is a SEPARATE module — it lives inside this workspace by id.
# module "fhir" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-fhir-service.git?ref=v1.0.0"
# workspace_id = module.workspace.id
# location = module.workspace.location
# ...
# }ℹ️ The FHIR service is created inside the workspace and consumes
module.workspace.id. Deploy the workspace first.
8 · Attaching a DICOM service (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# DICOM service is a SEPARATE module.
# module "dicom" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-dicom-service.git?ref=v1.0.0"
# workspace_id = module.workspace.id
# location = module.workspace.location
# ...
# }ℹ️ DICOM medical-imaging endpoints are also workspace children; they must be created in the workspace's region.
9 · Attaching a MedTech service (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# MedTech (IoT device data -> FHIR) is a SEPARATE module.
# module "medtech" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-medtech-service.git?ref=v1.0.0"
# workspace_id = module.workspace.id
# ...
# }💡 MedTech ingests device telemetry and maps it into a FHIR service within the same workspace.
10 · Private access via a private endpoint (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# Private connectivity is owned by the private-endpoint module and targets the workspace id.
# module "workspace_pe" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-private-endpoint.git?ref=v1.0.0"
# private_connection_resource_id = module.workspace.id
# subresource_names = ["healthcareworkspace"]
# subnet_id = var.network_subnet_ids["health"]
# ...
# }🔴 Established connections do not appear on the workspace's
private_endpoint_connectionsoutput: it is never populated at azurerm 4.81.0 -- the provider's flatten builds each entry and then discards it without appending, so the attribute is always an empty set however many private endpoints are approved. Nothing errors; an empty value simply reads as "none exist". Read the private endpoints themselves instead.
11 · Diagnostic settings (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# Route platform logs/metrics with the diagnostic-setting module, targeting the workspace id.
# module "workspace_diag" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-monitor-diagnostic-setting.git?ref=v1.0.0"
# target_resource_id = module.workspace.id
# log_analytics_workspace_id = var.logs_id
# ...
# }ℹ️ Application monitoring is a workspace-level configuration; a dedicated module keeps the diagnostics contract reusable.
12 · Entra RBAC data-plane assignment (sibling module)
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
}
# Grant least-privilege data-plane roles with the role-assignments module, scoped to the workspace id.
# module "workspace_rbac" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-role-assignments.git?ref=v1.0.0"
# scope = module.workspace.id
# assignments = {
# fhir_reader = { role_definition_name = "FHIR Data Reader", principal_id = var.app_object_id }
# }
# }🔒 Access to PHI is Entra-based; there are no keys. Assign the smallest role that works at the smallest scope.
13 · Consuming a resource-group module's outputs
module "rg" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-resource-group.git?ref=v1.0.0"
name = "rg-health-eastus"
location = "eastus"
}
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophi01"
resource_group_name = module.rg.name
location = module.rg.location
}💡 Wiring the resource group's
nameandlocationin keeps the workspace inside the group's lifecycle and region.
14 · 🏗️ End-to-end composition
provider "azurerm" {
features {}
}
# 1) Resource group
module "rg" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-resource-group.git?ref=v1.0.0"
name = "rg-health-prod-eastus"
location = "eastus"
tags = {
environment = "prod"
data_class = "phi"
}
}
# 2) Health Data Services workspace (this module) — the compliance boundary
module "workspace" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-workspace.git?ref=v1.0.0"
name = "contosophiprod"
resource_group_name = module.rg.name
location = module.rg.location
tags = {
environment = "prod"
data_class = "phi"
compliance = "hipaa-hitrust"
}
}
# 3) FHIR service (SEPARATE sibling module) created INSIDE the workspace by id
# module "fhir" {
# source = "git::https://github.com/microsoftexpert/terraform-azurerm-healthcare-fhir-service.git?ref=v1.0.0"
# name = "contosofhir"
# workspace_id = module.workspace.id
# location = module.workspace.location
#
# tags = {
# environment = "prod"
# data_class = "phi"
# }
# }🔒 Order matters: the resource group, then the workspace, then each child service. The FHIR service references
module.workspace.idand must be created inmodule.workspace.location.
Required
| Name | Type | Description |
|---|---|---|
name |
string |
Workspace name — 1-24 characters, lowercase letters and digits only (the provider's validator is ^[a-z0-9]{1,24}$). Uppercase is rejected, and one- and two-character names are legal. Unique in the subscription. Force-new. |
resource_group_name |
string |
Existing resource group to hold the workspace. Force-new. |
location |
string |
Azure region. Immutable after creation. Force-new. |
Optional (universal tail)
| Name | Type | Default | Description |
|---|---|---|---|
tags |
map(string) |
{} |
Tags applied to the workspace. |
timeouts |
object(...) |
null |
Create / read / update / delete timeouts. |
Full object() schemas
variable "name" {
type = string
# 1-24 characters, lowercase letters and digits only; force-new.
}
variable "resource_group_name" {
type = string
# Existing resource group; force-new.
}
variable "location" {
type = string
# Azure region; immutable / force-new.
}
variable "tags" {
type = map(string)
default = {}
}
variable "timeouts" {
type = object({
create = optional(string)
read = optional(string)
update = optional(string)
delete = optional(string)
})
default = null
}| Output | Description | Kind |
|---|---|---|
id |
The Azure Resource ID of the Health Data Services workspace (/subscriptions/.../resourceGroups//providers/Microsoft.HealthcareApis/workspaces/) | Passthrough |
name |
The name of the workspace | Passthrough |
resource_group_name |
The resource group holding the workspace | Passthrough |
location |
The Azure region of the workspace, in the provider's normalized form (for example "eastus" even when "East US" was supplied) | Passthrough |
required_child_service_location |
The region every FHIR, DICOM and MedTech service inside this workspace must be created in | Passthrough |
tags |
The tags applied to the workspace | Passthrough |
private_endpoint_connections |
The workspace's private endpoint connections, each with an id and a name, as the provider reports them | Passthrough |
private_endpoint_connections_are_never_reported |
Constant true, and it earns its place because the failure is completely silent | Constant |
private_link_is_the_only_workspace_level_network_control |
Constant true | Constant |
is_compliance_boundary_only |
Constant true | Constant |
workspace_has_no_managed_identity |
Constant true, stated because compositions routinely assume otherwise | Constant |
fhir_public_access_is_not_configurable_from_terraform |
Constant true, and consequential for anyone closing public access as a control | Constant |
customer_managed_keys_supported_on_dicom_only |
Constant true | Constant |
deletion_is_blocked_while_child_services_exist |
Constant true | Constant |
resource_group_deletion_bypasses_the_child_guard |
Constant true, and the single most dangerous fact about this resource | Constant |
data_protection_review_belongs_outside_this_module |
Constant true, recorded as a referral rather than an answer | Constant |
tags_are_the_only_updatable_field |
Constant true | Constant |
plan_requires_no_credential_read |
Constant true | Constant |
- The workspace is a boundary, not a data plane. It has no public-access, encryption, or identity arguments of its own. Every PHI security control — customer-managed keys, private endpoints, Entra RBAC, diagnostics — is configured on the child FHIR/DICOM/MedTech services or by sibling modules. This module keeps the boundary minimal on purpose.
- Force-new triple.
name,resource_group_name, andlocationeach force replacement. Because a workspace cannot be deleted while child services exist, an accidental change to any of these can block a plan until the children are removed. Treat these three as fixed after first apply. - Region is permanent. The region is chosen at creation and cannot change; child services must be created in the workspace's region. Multi-region designs use multiple workspace instances.
- Deletion ordering. Deleting the workspace requires all child services to be gone first. In a composition, that means the child modules are destroyed before this one — the implicit dependency created by passing
module.workspace.idinto the children enforces the correct order. timeoutsis rendered with adynamicblock andtry(...)on each field, so an omittedtimeoutsobject renders as absent rather than as an error.features {}dependence. The provider will not initialize without a caller-sideprovider "azurerm" { features {} }block. If the module appears not to initialize in isolation, that missing block is almost always the cause — it belongs to the root module, never here.
The workspace exposes no exposure toggles, so the secure-defaults table is short — the security surface lives on the child services this module deliberately does not own:
| Concern | Secure posture (empty call) | Opt-out | Where it lives |
|---|---|---|---|
| Public network access | Not configurable on the workspace | — | Child FHIR / DICOM / MedTech services |
| Encryption at rest | On by default (platform-managed); CMK optional | supply a key | Child services |
| Data-plane auth | Entra RBAC only — no keys | — | Child services + role-assignments sibling |
| Private connectivity | Off until a private endpoint is attached | attach a private endpoint | private-endpoint sibling |
| Diagnostics | Off until wired | wire a diagnostic setting | monitor-diagnostic-setting sibling |
The workspace's own contribution to security is that it is the compliance boundary; nothing about the empty call opens exposure.
# From the module folder — plan-only, no cloud calls:
terraform init -backend=false
terraform validate
terraform fmt -check- Pin the module with
?ref=v1.0.0— never a branch. - No
terraform applyfrom this workflow. A human applies from CI against real credentials.
The offline proof gate is what this module guarantees:
| Check | What it proves | Calls Azure? |
|---|---|---|
terraform init -backend=false |
Provider resolves at ~> 4.0; no backend needed. |
No |
terraform validate |
Configuration is internally consistent and type-correct against the pinned schema. | No |
terraform fmt -check |
Canonical formatting. | No |
Only terraform plan (run by a human from CI) exercises the ARM API. This library never runs plan or apply during authoring.
$ terraform output
id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-health-eastus/providers/Microsoft.HealthcareApis/workspaces/contosophi01"
name = "contosophi01"
resource_group_name = "rg-health-eastus"
location = "eastus"
private_endpoint_connections = toset([])| Symptom | Cause | Fix |
|---|---|---|
provider ... features error on init |
The root module is missing provider "azurerm" { features {} }. |
Add the features {} block to the caller's provider — it never lives in this module. |
| Plan wants to replace the workspace | name, resource_group_name, or location changed — all are force-new. |
Revert the change, or accept replacement only after every child service is removed. |
| Cannot delete the workspace | Child FHIR / DICOM / MedTech services still exist. | Destroy the child service modules first, then the workspace. |
name rejected at validate |
The name is not 1-24 lowercase letters and digits. The provider's validator catches the shape before any API call. | Use lowercase letters and digits only, 1-24 chars. |
name rejected at apply |
The name collides with an existing workspace in the subscription. Only the collision reaches Azure. | Choose another name. |
| Child service create fails on region | The child was placed in a different region than the workspace. | Set the child's location to module.workspace.location. |
- Provider resource:
azurerm_healthcare_workspace - Concept: What is an Azure Health Data Services workspace?
- Sibling modules:
terraform-azurerm-resource-group,terraform-azurerm-private-endpoint,terraform-azurerm-monitor-diagnostic-setting,terraform-azurerm-role-assignments, and the FHIR / DICOM / MedTech service modules. - This module's
SCOPE.md.
💙 "Infrastructure as Code should be standardized, consistent, and secure."