Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“Š Microsoft Fabric Workspace Outbound Gateway Rules Terraform Module

Manages a single fabric_workspace_outbound_gateway_rules resource β€” the gateway-routed outbound allow/deny posture for one Fabric workspace β€” against the microsoft/fabric provider ~> 1.12.0.

Terraform Provider Module Version Module Type Resources Plan Only

🧩 Overview

  • πŸšͺ Sets a default_action (Allow | Deny) governing outbound traffic through gateways not explicitly listed.
  • βœ… Optionally defines an allowed_gateways set β€” gateway GUIDs (from terraform-fabric-gateway) permitted regardless of the default action.
  • πŸ”— Unlike the sibling cloud-connection-rules module, this one's naming-derived hypothesis about cross-module references held up: allowed_gateways genuinely references fabric_gateway resource instances.

πŸ’‘ Why it matters: this is a data-governance control restricting which gateways a workspace's items can route outbound traffic through β€” e.g. limiting an on-premises data gateway connection to only the gateways an organization has explicitly reviewed and registered, rather than any gateway visible in the tenant.


❀️ Support this project

If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:

Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!


πŸ—ΊοΈ Where this fits

flowchart LR
 WS["terraform-fabric-workspace"]:::keystone
 GW["terraform-fabric-gateway"]:::sibling
 THIS["terraform-fabric-workspace-outbound-gateway-rules"]:::this
 WS -->|"workspace_id"| THIS
 GW -->|"id, into allowed_gateways"| THIS

 classDef keystone fill:#143551,color:#ffffff,stroke:#143551,stroke-width:2px;
 classDef this fill:#0F6CBD,color:#ffffff,stroke:#0F6CBD,stroke-width:2px;
 classDef sibling fill:#e8e8e8,color:#111111,stroke:#999999,stroke-width:1px;
Loading

Diagram validated for correct rendering before embedding.

🧬 What this builds

flowchart TB
 subgraph Inputs
 A["workspace_id"]
 B["default_action"]
 C["allowed_gateways, set of gateway GUIDs"]
 D["timeouts"]
 end
 R["fabric_workspace_outbound_gateway_rules.this"]:::this
 A --> R
 B --> R
 C --> R
 D --> R
 R --> O1["workspace_id"]
 R --> O2["default_action"]
 R --> O3["allowed_gateways"]

 classDef this fill:#0F6CBD,color:#ffffff,stroke:#0F6CBD,stroke-width:2px;
Loading

Resource inventory: 1 resource β€” fabric_workspace_outbound_gateway_rules.this.

βœ… Provider / Versions

Terraform >= 1.12.0
Provider microsoft/fabric ~> 1.12.0
Provider block None β€” the caller configures provider "fabric" {} at the root

Schema notes that bite:

  • No id attribute β€” confirmed via terraform providers schema -json; workspace_id is the sole key. Outputs lead with workspace_id.
  • default_action is required with no documented provider-native default β€” modeled as a required module variable per this suite's secure-by-default convention.
  • allowed_gateways is an unordered Attributes Set of { id = string } objects β€” this module accepts a flat set(string) of gateway GUIDs and expands each in main.tf.
  • This resource had no prior internal house pattern β€” confirmed fresh this session against the live provider schema and the binary provider schema.
  • No delegated-auth requirement (provider doc: "This resource supports Service Principal authentication").

πŸ”‘ Required Fabric / Entra Permissions

  • Fabric: Workspace Admin role on the target workspace.
  • Entra: calling Service Principal (or Managed Identity) enabled under "Service principals can use Fabric APIs".
  • Fabric tenant administrator must have separately enabled the relevant tenant setting (see Prerequisites).

Microsoft Fabric Prerequisites

  • Tenant setting "Configure workspace-level outbound network rules" enabled by a Fabric tenant admin (off by default).
  • Workspace must reside on a Fabric (F SKU) capacity β€” no other capacity type is supported.
  • This module's rules only matter if terraform-fabric-workspace-network-communication-policy's outbound.default_action is Deny for the same workspace.
  • Universal tenant-level SPN/MSI API access switch.
  • Deployment pipelines are not supported alongside workspace outbound access protection.

πŸ“ Module Structure

terraform-fabric-workspace-outbound-gateway-rules/
β”œβ”€β”€ providers.tf # required_providers floor β€” no provider {} block
β”œβ”€β”€ variables.tf # workspace_id, default_action, allowed_gateways, timeouts
β”œβ”€β”€ main.tf # fabric_workspace_outbound_gateway_rules.this β€” thin renderer
β”œβ”€β”€ outputs.tf # workspace_id (primary), default_action, allowed_gateways
β”œβ”€β”€ README.md # this file
β”œβ”€β”€ SCOPE.md # lightweight standalone scope
└── examples/
 β”œβ”€β”€ basic/ # global deny, no allowed gateways
 └── complete/ # global deny plus two explicit allowed gateways

βš™οΈ Quick Start

module "outbound_gateway_rules" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-workspace-outbound-gateway-rules.git?ref=v1.0.0"

  workspace_id   = module.workspace.id
  default_action = "Deny"
}

πŸ”Œ Cross-Module Contract

Consumes

Input Type Source module
workspace_id string terraform-fabric-workspace's id output
allowed_gateways set(string) terraform-fabric-gateway's id output

Emits

Output Description Consumed by
workspace_id Primary output β€” the workspace GUID these rules govern Informational / cross-referencing
default_action Effective default_action for unlisted gateways Informational
allowed_gateways Effective set of allowed gateway objects Informational

πŸ“š Example Library

1 Β· Basic β€” global deny, no allowed gateways
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-bronze-prod
  default_action = "Deny"
}
2 Β· Global allow (permissive posture)
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-sandbox-dev
  default_action = "Allow"
}

⚠️ Reserve for dev/sandbox workspaces β€” not the recommended posture for a regulated production workspace.

3 Β· Single on-premises gateway allowed
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-onprem-integration-prod
  default_action = "Deny"

  allowed_gateways = [module.onprem_gateway.id]
}
4 Β· Two allowed gateways β€” primary and secondary
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-onprem-integration-prod
  default_action = "Deny"

  allowed_gateways = [
    module.onprem_gateway_primary.id,
    module.vnet_gateway_secondary.id,
  ]
}
5 Β· VNet data gateway only
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-azure-native-prod
  default_action = "Deny"

  allowed_gateways = [module.vnet_gateway.id]
}

ℹ️ Consumes terraform-fabric-gateway's id output for a VirtualNetwork-type gateway registration.

6 Β· Custom timeouts
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-bronze-prod
  default_action = "Deny"

  timeouts = {
    create = "30m"
  }
}
7 Β· Deliberately empty allow list β€” deny every gateway
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id     = module.workspace.id # ws-core-locked-down-prod
  default_action   = "Deny"
  allowed_gateways = []
}

πŸ”’ Explicit allowed_gateways = [] documents intent β€” identical in effect to omitting the argument, since [] is this module's own default.

8 Β· Environment-scoped naming convention
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-onprem-integration-dev
  default_action = "Deny"

  allowed_gateways = [module.onprem_gateway_dev.id]
}
9 Β· Paired with the workspace-level outbound switch
module "network_communication_policy" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-workspace-network-communication-policy.git?ref=v1.0.0"

  workspace_id = module.workspace.id
  outbound = {
    public_access_rules = { default_action = "Deny" }
  }
}

module "outbound_gateway_rules" {
  source = "../../"

  workspace_id     = module.workspace.id
  default_action   = "Deny"
  allowed_gateways = [module.onprem_gateway.id]

  depends_on = [module.network_communication_policy]
}

⚠️ This module's rules have no effect unless the sibling network-communication-policy module's outbound.default_action is Deny for the same workspace β€” an explicit depends_on documents the operational ordering.

10 Β· At scale β€” for_each over multiple workspaces sharing one gateway
variable "onprem_integration_workspace_ids" {
  type = map(string)
}

module "outbound_gateway_rules" {
  for_each = var.onprem_integration_workspace_ids
  source   = "../../"

  workspace_id     = each.value
  default_action   = "Deny"
  allowed_gateways = [module.shared_onprem_gateway.id]
}

πŸ’‘ for_each over a caller-supplied map β€” adding a fifth workspace never threatens the first four.

11 Β· Guarding against a paused/wrong-SKU capacity
data "fabric_capacity" "target" {
  display_name = "cap-casey-fsku-prod"

  lifecycle {
    postcondition {
      condition     = self.state == "Active"
      error_message = "Target capacity must be Active for outbound access protection reads/writes to behave reliably."
    }
  }
}

module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id
  default_action = "Deny"

  depends_on = [data.fabric_capacity.target]
}

⚠️ Outbound access protection additionally requires an F-SKU capacity β€” this postcondition only guards against a paused capacity, not the wrong SKU.

12 Β· Personal on-premises gateway reference
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-analyst-sandbox-prod
  default_action = "Deny"

  allowed_gateways = [module.personal_gateway.id]
}

ℹ️ <VERIFY: whether OnPremisesPersonal-type gateways are fully supported as allow-list entries here β€” not distinguished in this resource's confirmed schema, which accepts any gateway GUID string uniformly>.

13 Β· Rotating a gateway β€” replace one allowed entry without disturbing others
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-onprem-integration-prod
  default_action = "Deny"

  allowed_gateways = [
    module.onprem_gateway_v2.id, # replaces onprem_gateway_v1
  ]
}

ℹ️ Since allowed_gateways is rendered into an unordered Set, swapping one entry in the caller's set(string) produces a minimal update diff rather than a full replacement of the resource.

14 Β· Documenting the tenant prerequisite in a runbook comment
# NOTE: requires the Fabric tenant admin to have enabled "Configure workspace-level outbound network
# rules" and the workspace to be on an F-SKU capacity β€” neither is enforceable from Terraform.
module "outbound_gateway_rules" {
  source = "../../"

  workspace_id   = module.workspace.id # ws-core-bronze-prod
  default_action = "Deny"
}
15 Β· πŸ—οΈ End-to-end composition
module "workspace" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-workspace.git?ref=v1.0.0"

  display_name = "ws-core-onprem-integration-prod"
  capacity_id  = data.fabric_capacity.core_fsku_prod.id
}

data "fabric_capacity" "core_fsku_prod" {
  display_name = "cap-casey-fsku-core-prod"
}

module "gateway" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-gateway.git?ref=v1.0.0"

  display_name = "gw-onprem-primary-prod"
  type         = "OnPremises"
}

module "network_communication_policy" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-workspace-network-communication-policy.git?ref=v1.0.0"

  workspace_id = module.workspace.id
  outbound = {
    public_access_rules = { default_action = "Deny" }
  }
}

module "outbound_gateway_rules" {
  source = "git::https://github.com/microsoftexpert/terraform-fabric-workspace-outbound-gateway-rules.git?ref=v1.0.0"

  workspace_id     = module.workspace.id
  default_action   = "Deny"
  allowed_gateways = [module.gateway.id]

  depends_on = [module.network_communication_policy]
}

output "allowed_gateways" {
  value = module.outbound_gateway_rules.allowed_gateways
}

πŸ—οΈ Wires terraform-fabric-workspace's and terraform-fabric-gateway's id outputs into this module's workspace_id/allowed_gateways, layered on top of the workspace-level outbound switch.

πŸ“₯ Inputs

Variable Type Default Required
workspace_id string β€” βœ…
default_action string (Allow|Deny) β€” βœ…
allowed_gateways set(string) [] ❌
timeouts object({ create, read, update, delete = optional(string) }) null ❌
Full object schemas
variable "workspace_id" {
  type = string
}

variable "default_action" {
  type = string
}

variable "allowed_gateways" {
  type    = set(string)
  default = []
}

variable "timeouts" {
  type = object({
    create = optional(string)
    read   = optional(string)
    update = optional(string)
    delete = optional(string)
  })
  default = null
}

🧾 Outputs

Output Description Sensitive
workspace_id Primary output β€” the workspace GUID (no id attribute exists) No
default_action Effective default_action for gateways not explicitly listed No
allowed_gateways Effective set of allowed gateway objects (unordered) No

🧠 Architecture Notes

  • allowed_gateways is rendered from a flat set(string) of gateway GUIDs into the provider's { id = string } Attributes Set shape via [for gateway_id in var.allowed_gateways: { id = gateway_id }] in main.tf.
  • No id attribute exists on this resource β€” workspace_id is the primary output, confirmed via terraform providers schema -json.
  • Since allowed_gateways is a Set, swapping one entry produces a minimal diff rather than threatening to replace the whole resource β€” there is no count-style index-shifting risk here even though the module's own variable is a flat collection rather than a caller-keyed map.

🧱 Design Principles

Concern Safe default Opt-out
default_action No safe implicit default exists in the provider β€” required Caller must explicitly choose Allow or Deny
allowed_gateways Empty ([]) β€” no gateways allowed unless explicitly added Caller supplies gateway GUIDs

πŸš€ Runbook

cd C:\GitHubCode\newfabricmodules\terraform-fabric-workspace-outbound-gateway-rules
terraform init -backend=false
terraform validate
terraform fmt -check

Pin ?ref=v1.0.0 β€” never a branch. Plan-only; a human applies from a reviewed pipeline.

πŸ§ͺ Testing

  • validate/fmt catch: missing workspace_id/default_action, an invalid default_action value, malformed allowed_gateways shape.
  • Only a live plan/apply exercises: whether the referenced gateway GUIDs actually exist and are reachable from the workspace's capacity, whether the tenant/capacity prerequisites are met.

πŸ’¬ Example Output

workspace_id = "00000000-0000-0000-0000-000000000000"
default_action = "Deny"
allowed_gateways = [
 { id = "11111111-1111-1111-1111-111111111111" },
]

πŸ” Troubleshooting

Symptom Cause Fix
A gateway GUID in allowed_gateways produces no effect GUID does not correspond to an existing fabric_gateway reachable by this workspace's capacity Confirm the gateway ID against terraform-fabric-gateway's id output
apply succeeds but outbound gateway traffic is not actually restricted The sibling terraform-fabric-workspace-network-communication-policy's outbound.default_action is still Allow Set that sibling module's outbound default_action to Deny
apply fails with a permissions error Calling principal lacks Workspace Admin role Grant Admin via terraform-fabric-workspace's role_assignments
Terraform reports drift on every plan Workspace capacity is paused Resume the capacity before planning/applying

πŸ”— Related Docs

About

Terraform module: terraform-fabric-workspace-outbound-gateway-rules

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages