Skip to content

 

New chat

Azure Lighthouse Cross-Tenant Management Options

 

Managing 3 Azure Tenants with Lighthouse

Azure Cross-Tenancy Management Overview

Azure SQL Managed Instance Private Endpoint Guide

Network Traffic Breakdown for Security Strategy

 

what are the limitations of DSC

Cloud Network and Corporate Network Diagram

AWS vs Azure Network Design Differences

Microsoft 365 Dependency on Azure Landing Zones

SASE Replaces Traditional Network TAP Capabilities

Changing Work Item Types in Azure DevOps

Jan-Bow Milestones Developmental Screening Overview

Azure DevOps and Azure Tenancy Linkage

DevOps Overlay on Landing Zone and VDI

Azure UDR Operational Inefficiency and Best Practices

 

SD-WAN Integration in Azure Architectures Explained

AWS Route Table vs Azure UDR Comparison

Best Practice CIDR Design for Azure Virtual WAN

Azure DevOps Subnet IP Range Guide

Decoupling Azure Networking for Modern Security

Palo Alto Cloud NGFW Introduction Timeline

Best Practices for CIDR in Azure Landing Zones

Implementing Azure Landing Zone Steps Guide

Using Azure AD for Multiple Tenants

Deploy Azure DevOps in Production and Non-Prod

Azure vWAN vs Traditional Hub Comparison

Azure Virtual WAN Cost Savings Explained

Securing Azure Single Tenant for Business Units

Designing Azure Security Landing Zones Features

Securing Azure Single-Tenant Architecture Guide

Security Risks and Mitigations for Azure Virtual WAN

Free vs Paid DeepSeek Features Explained

 

Azure Network Landing Zone Design Overview

 

How to migrate from azure hub an

Migrate Azure Hub-Spoke to Virtual WAN

How to migrate azure hub and spo

New chat

Azure Firewall Design Document with Diagrams

 

Azure Firewall Migration Components Overview

Migrating Palo Alto Firewall to Azure

As-Built Azure Landing Zone Audit Document

As-Built Azure Landing Zone Audit Guide

Finding and Managing Azure Environments Guide

Websites That Earn via Subscription Referrals

Migrating Exadata to Azure Guide

Trump Tariff Calculations Criticized for Flaws

Trump’s Tariff Calculations Criticized by Experts

 

Finding Azure Resource Health Alerts Guide

Finding Log Analytics Configuration in Azure

Azure DevOps Fabric Integration Purpose Explained

DSC Security Risks in Azure Landing Zone

Components of a DevOps Design Overview

Pros and Cons of Environment Routing in Power Platform

 

Structured Power Platform Support Model Guide

Testing Power Platform Catalog Assignment Authorizations

what is the name of the observat

Azure Landing Zone Design Components Overview

Best Practice Test Plan Structure Guide

Sample Test Plan for Power Apps Application

Best Practices for DLP in Power Apps

DLP Policies for Power Apps Examples

Finding Nomad IT Jobs Guide

Microsoft DSC Attribute Configuration Mechanisms Explained

Security Model for Microsoft Power Platform

Best Practices for Power Platform Authentication

Best Practices for Access Control in Power Pages

Best Practices for Power Apps Conditional Access

Deploy Power Platform Using DSC Guide

Power Platform Security Groups Overview

Best Practices for RBAC in Power Apps

Best RBAC Practices for Power Platform Environments

Monitoring Settings for Microsoft Planner and Forms

Benefits of Power Platform Tenant Analytics

Persona Model in Conditional Access Policies

Power Platform Tenant and Admin Settings Purpose

Power Platform Data Sources Overview

 

Upgrade HP Elite Laptop SSD to 512GB

Artist Guitars Australia Sales Voucher Guide

Steps to Build Chatbot Language Model

Understanding Quantum Computing Basics and Applications

Specifying PII Fields in Azure Purview Email Scan

Azure APIs for Email PII Data Scanning

BitLocker and SSD Replacement Security Guide

Rahab in Bible Verses and Contexts

March 10 Cherry Blossom Busan Inquiry

how to connect external user to

how to create a base template fo

what is lowest fare from sydney

what is lowest cost way to fly f

show me a sample power platform

where are settings for power bi

what settings allow launch of mi

where do i configure task notifi

how to extract microsoft power p

which church in Canberra has kor

what ae the configuration settin

what are the configuration setti

what are the configuration setti

what are the configuration setti

what are the configuration setti

what are the configuration setti

 

Azure Lighthouse Cross-Tenant Management Options

what are options for cross tenant management using Azure Lighthouse?

Of course! Azure Lighthouse is the premier and recommended solution for secure, large-scale cross-tenant management. It enables you to manage resources across multiple customer tenants from a single, centralized managing tenant.

Here are the primary options and patterns for cross-tenant management using Azure Lighthouse, broken down from basic to advanced.

  1. Core Concept: Delegated Resource Management

The foundation of Azure Lighthouse is delegated resource management. You don’t get direct access to the customer tenant. Instead, the customer delegates their Azure resources (subscriptions, resource groups) to your managing tenant. Your authorized users and managed identities can then see and operate on these delegated resources as if they were in your own tenant, but without having a user account or role in the customer tenant.

  1. Primary Onboarding Options

There are two main ways to onboard a customer tenant to Azure Lighthouse.

Option A: ARM Templates (Recommended for Partners & Service Providers)

This is the most common and scalable method. You provide the customer with an Azure Resource Manager (ARM) template or a service-managed offer via the Azure Marketplace. The customer deploys this template in their own tenant, which explicitly grants the permissions you’ve defined.

  • How it works:
    1. You create an ARM template that defines:
      • principalId: The User, Group, or Service Principal in your tenant who needs access.
      • roleDefinitionId: The built-in or custom Azure RBAC role (e.g., Contributor, Reader, Log Analytics Contributor).
      • principalIdDisplayName: A friendly name for your team (e.g., “Contoso Support Team”).
    2. The customer deploys this template via the Portal, PowerShell, CLI, or a CI/CD pipeline in their tenant.
    3. Upon successful deployment, the resources are visible in your “My Customers” page in Azure Portal.
  • Best for: Managed Service Providers (MSPs), SIs, and partners with multiple customers. It’s auditable, version-controlled, and easy to automate.

Option B: Managed Service Offers via Azure Marketplace

This method is formal and involves publishing a “Managed Service” plan to the Azure Marketplace. The customer can then “purchase” (it’s free) this offer, which triggers the onboarding process.

  • How it works:
    1. You create a “Managed Service” offer in Partner Center.
    2. You define the same authorization details (users, roles) as in the ARM template.
    3. You publish the offer privately to specific customer tenants or publicly.
    4. The customer accepts the offer in the Azure Portal, which creates the delegation.
  • Best for: Partners who want a formal, marketplace-driven process and may be part of the Cloud Solution Provider (CSP) program.
  1. Management & Operationalization Options

Once onboarded, you can leverage various Azure native services from your managing tenant to manage the delegated resources.

Option 1: Native Azure Portal Experience

This is the simplest way to get started. After onboarding, delegated resources appear in your managing tenant’s Azure Portal.

  • “My Customers” Page: A dedicated page (Azure Active Directory -> My Customers) lists all your customers and their delegated subscriptions/resources.
  • Directory + Subscription Switcher: Use the switcher at the top of the Azure Portal to change context from your tenant to a specific customer’s subscription. Once selected, you can manage their resources directly.
  • Activity Logs: View activity logs for the delegated resources, filtered to show only actions taken by users from your managing tenant.

Option 2: Azure Policy for Governance

Apply and enforce compliance at scale across all customer tenants.

  • How it works:
    1. Create Policy Definitions and Initiatives (as blueprints) in your managing tenant.
    2. Assign these policies directly to the delegated subscriptions or resource groups in the customer tenants.
    3. The policy’s compliance state, remediation tasks, and effects are managed from your tenant.
  • Use Case: Enforcing that all customer VMs must have a specific tag, or that storage accounts must disable public network access.

Option 3: Azure Monitor for Centralized Logging & Alerting

Gain a unified view of the health and performance of all customer environments.

  • Log Analytics Workspaces: Deploy a central Log Analytics workspace in your managing tenant (or use a regional one in a customer tenant). Use Azure Monitor Agent to send logs from VMs in any customer tenant to this central workspace.
  • Azure Monitor Alerts: Create alerts in your managing tenant that monitor conditions across delegated resources. For example, an alert rule that fires if any VM in any customer tenant has >90% CPU for 5 minutes.
  • Workbooks & Dashboards: Create comprehensive dashboards that aggregate data from multiple customer tenants for a single-pane-of-glass view.

Option 4: Automation with Scripts & Managed Identities

Automate management tasks securely using Azure Automation Runbooks or Logic Apps.

  • How it works:
    1. Create an Automation Account with a System-Assigned Managed Identity in your managing tenant.
    2. Grant this Managed Identity the necessary RBAC role on the customer’s delegated resources (this is done during the initial ARM template onboarding).
    3. Your runbook scripts (PowerShell, Python) can now authenticate using the Managed Identity and perform actions across all customer tenants without storing any credentials.
  • Use Case: A nightly runbook that shuts down all non-essential VMs across all customer environments to save costs.

Option 5: Azure Security Center & Microsoft Defender for Cloud

Centralize security management.

  • How it works: When you have a delegated subscription, its security posture, recommendations, and alerts (from Microsoft Defender for Cloud) will appear in your managing tenant’s Defender for Cloud portal. You can set secure scores and track compliance across your entire customer base.

Option 6: Azure Backup & Site Recovery

Manage disaster recovery and backup for customer resources.

  • How it works: Use the Backup Center and Site Recovery vault in your managing tenant to monitor and manage backup jobs, restores, and replication for items in customer tenants.
  1. Advanced Scenarios
  • Cross-Tenant Azure Arc Management: Use Lighthouse to manage servers, Kubernetes clusters, and SQL Managed Instances that are connected via Azure Arc, even if they are hosted outside of Azure (on-premises, other clouds).
  • Nested Delegations: A partner (Tier 1) can delegate a customer’s resources to a sub-partner (Tier 2). The sub-partner then manages the resources from their own tenant.
  • Custom RBAC Roles: Create highly specific custom roles in your managing tenant to provide “least privilege” access for different teams (e.g., a “VM Operator” role that can only start/stop/deallocate VMs).

Summary Table of Options

Option

Primary Use Case

Key Benefit

ARM Template Onboarding

Scalable, automated customer onboarding.

Developer-friendly, version control, CI/CD integration.

Marketplace Offer

Formal, partner-led onboarding.

Integrated with Partner Center/CSP program.

Native Portal Experience

Day-to-day manual management & troubleshooting.

Simple, no extra tools required.

Azure Policy

Governance & Compliance.

Enforce rules at scale across all customers.

Azure Monitor

Centralized monitoring, logging, and alerting.

Single-pane-of-glass for operational health.

Automation Accounts

Automated remediation & management tasks.

Reduces manual toil, ensures consistency.

Defender for Cloud

Unified security management.

Centralized view of security posture and threats.

Key Considerations

  • Security & Least Privilege: Always follow the principle of least privilege. Use custom roles to grant only the permissions absolutely necessary.
  • Pricing: There are no direct costs for using Azure Lighthouse itself. You pay for the underlying Azure services you use (e.g., the cost of the Log Analytics workspace, Automation jobs, etc.) and for any actions performed on the customer’s resources, which are billed to the customer’s subscription.
  • Auditing: All actions taken by users from the managing tenant are logged in the customer tenant’s Activity Log, providing a clear audit trail.

By leveraging these options, you can build a highly efficient, secure, and scalable multi-tenant management solution for any scenario, from simple resource management to complex, automated governance and security operations.

what are options for cross tenant management using Entra ID

Excellent question. While Azure Lighthouse is specifically designed for resource delegation and management, Entra ID (formerly Azure Active Directory) provides the foundational identity and access capabilities that enable cross-tenant scenarios. The options here are more about connecting identities and enabling access rather than directly managing another tenant’s resources.

Here are the primary options for cross-tenant management and collaboration using Entra ID:

  1. Entra ID External ID (B2B) Collaboration

This is the most common and fundamental method. It allows you to invite users from any Entra ID tenant (or even other identity providers like Google, etc.) to be “guest users” in your tenant. They authenticate with their home tenant but can be assigned access to resources in your tenant.

  • How it works:
    1. You invite a user from tenant-b.com to your tenant-a.com.
    2. They receive an invitation and redeem it.
    3. A “Guest User” object is created in your tenant-a.com directory.
    4. You can assign this guest user to Azure AD groups and grant them access to applications (SaaS apps, custom apps) and Azure resources, just like a member user.
  • Key Features:
    • Access Packages (Entra Entitlement Management): For scalable, policy-driven access. You can create a catalog of applications/resources and let external users request access via a portal, with automated approval and expiration workflows.
    • Cross-Tenant Access Settings: Granular control over the collaboration flow between your tenant and other specific tenants.
  • Best for:
    • Collaborating with individual users from partner organizations.
    • Giving a customer’s IT admin access to a SaaS application you host.
    • Federating development teams across company boundaries.
  1. Entra ID Cross-Tenant Access Settings (XTAS)

This is the control plane for B2B collaboration. It allows you to define granular inbound and outbound rules for how you collaborate with specific external Entra ID tenants.

  • How it works:
    You configure settings for a specific partner tenant (e.g., partner-company.com). You can independently control:
    • Inbound Access: What users from the partner tenant can do in your tenant (e.g., allow B2B collaboration, block access to specific apps).
    • Outbound Access: What your users can do in the partner tenant when they are invited as guests.
  • Key Capabilities:
    • Trust Settings: Automatically accept Multi-Factor Authentication (MFA) and compliant device claims from a trusted partner tenant, so their users don’t have to perform MFA again in your tenant.
    • Application Restrictions: Block your internal users from taking data out to unsanctioned applications in other tenants.
    • B2B Direct Connect: The underlying technology for the next option.
  • Best for:
    • Establishing secure, trusted partnerships with specific organizations.
    • Simplifying the user experience by honoring MFA and device compliance from the user’s home tenant.
  1. Entra ID B2B Direct Connect

This is a more integrated form of collaboration focused on sharing applications between two Entra ID tenants, without the need for guest user accounts or invitations.

  • How it works:
    1. Two tenants establish a mutual trust relationship via Cross-Tenant Access Settings.
    2. An admin in tenant-a.com can now grant the entire “Users” group from tenant-b.com access to an application in tenant-a.com.
    3. A user from tenant-b.com goes directly to tenant-a.com’s application. They are seamlessly signed in using their own tenant-b.com account. There is no “guest user” object created in tenant-a.com.
  • Key Differentiator from B2B:

B2B Collaboration

B2B Direct Connect

Creates a “Guest User” object in your directory.

No guest user is created in your directory.

Good for collaborating with many different orgs.

Designed for 1:1, mutual tenant relationships.

User must redeem an invitation.

User access is seamless; they just navigate to the app.

  • Best for:
    • Deep integration between two specific partner companies (e.g., a manufacturer and its primary supplier sharing an ERP module).
    • Sharing applications within a corporate group where each subsidiary has its own tenant.
  1. Entra ID Multi-Tenant Applications

This isn’t about “managing” other tenants but enabling your application to be used by users from any Entra ID tenant.

  • How it works:
    1. You develop an application (e.g., a SaaS app) and register it in your home tenant as Multi-Tenant.
    2. A customer from tenant-c.com consents to your application, either by an admin granting tenant-wide consent or a user granting consent for themselves.
    3. This creates a “service principal” (an enterprise application) in the customer’s tenant, and users there can now sign in to your app with their own work accounts.
  • Best for:
    • ISVs (Independent Software Vendors) building SaaS applications for multiple customers.
    • This is the identity pattern that powers the vast majority of SaaS apps in the Microsoft ecosystem.
  1. Combining Entra ID with Azure Lighthouse

This is the most powerful pattern for true cross-tenant management. You use Entra ID for identity and access control within your managing tenant, and Lighthouse for resource delegation from customer tenants.

  • How it works:
    1. You use Entra ID Groups in your managing tenant. For example, you create a group “Tier-2-Support-Engineers”.
    2. When onboarding a customer via an Azure Lighthouse ARM template, you authorize the Entra ID Group’s object ID (instead of individual users) for a specific RBAC role (e.g., Contributor).
    3. Now, any user you add to that group in your tenant automatically gets Contributor access to all delegated customer resources. Removing them from the group revokes their access.
  • Key Benefit:
    • Simplified User Lifecycle Management: You manage access by simply adding/removing users from groups in your central tenant. You don’t need to update the Lighthouse delegation for every customer every time an employee joins or leaves.

Summary Table: Entra ID Cross-Tenant Options

Option

Primary Use Case

Key Concept

Entra ID B2B Collaboration

Inviting individual external users to access your resources/apps.

“Guest Users” in your directory.

Cross-Tenant Access Settings

Controlling B2B collaboration with specific partner tenants.

The “trust and security” control plane.

B2B Direct Connect

Seamlessly sharing apps between two organizations without guest users.

1:1 tenant trust; no guest objects.

Multi-Tenant Apps

Building a SaaS application for customers to sign into with their own Entra ID.

Customer “consent” to your app.

Entra ID + Lighthouse

Scalable identity management for service providers managing customer Azure resources.

Use Groups in your tenant to control access to delegated resources.

How to Choose:

  • To manage a customer’s Azure resources (VMs, networks, etc.): Use Azure Lighthouse, and leverage Entra ID Groups for scalable access control.
  • To give a customer access to your Azure-based SaaS application: Use a Multi-Tenant Application.
  • To collaborate with specific users from a partner on internal projects/apps: Use B2B Collaboration.
  • To establish a deep, seamless app-sharing partnership with one other company: Use B2B Direct Connect.
  • To configure trust and security policies for any of the above: Use Cross-Tenant Access Settings.

what are options for cross tenant management using Least Privilege Access Custome Roles?

Excellent question. Implementing Least Privilege with Custom Roles is a critical security practice for cross-tenant management, especially when built-in roles are too broad. Here’s a comprehensive guide to the options and patterns for using custom roles in cross-tenant scenarios, primarily with Azure Lighthouse.

Core Concept: Why Custom Roles for Cross-Tenant?

Built-in roles like OwnerContributor, or even Reader are often too permissive for specific management tasks. Custom roles allow you to:

  • Grant only the actions needed for a specific function
  • Reduce attack surface and potential for accidental damage
  • Meet compliance requirements for principle of least privilege
  1. Custom Role Creation & Structure

Where to Create Custom Roles

  • Managing Tenant: Create custom roles in your managing tenant
  • Customer Tenant: Alternatively, create them in the customer tenant (less common for service providers)

Basic Custom Role Structure

json

{

  “Name”: “VM Operator – Read and Start/Stop”,

  “Description”: “Can view VMs and start/deallocate them, but not create or delete”,

  “Actions”: [

    “Microsoft.Compute/virtualMachines/read”,

    “Microsoft.Compute/virtualMachines/start/action”,

    “Microsoft.Compute/virtualMachines/deallocate/action”,

    “Microsoft.Compute/virtualMachines/instanceView/read”

  ],

  “NotActions”: [],

  “DataActions”: [],

  “NotDataActions”: [],

  “AssignableScopes”: [“/”]  // Or specific subscriptions

}

  1. Cross-Tenant Deployment Patterns

Pattern A: Create in Managing Tenant, Deploy via Lighthouse

Most common pattern for service providers

  1. Create custom role in your managing tenant
  2. Reference it in ARM template for Lighthouse onboarding
  3. Deploy to customer tenant – the role definition is copied automatically

json

{

  “$schema”: “https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#”,

  “contentVersion”: “1.0.0.0”,

  “parameters”: {

    “mspOfferName”: { “type”: “string” },

    “managedByTenantId”: { “type”: “string” }

  },

  “variables”: {

    “vmOperatorRoleId”: “[guid(‘vm-operator-role’)]”

  },

  “resources”: [

    {

      “type”: “Microsoft.Authorization/roleDefinitions”,

      “apiVersion”: “2018-01-01-preview”,

      “name”: “[variables(‘vmOperatorRoleId’)]”,

      “properties”: {

        “roleName”: “VM Operator – Cross Tenant”,

        “description”: “Custom VM operator role for cross-tenant management”,

        “type”: “customRole”,

        “permissions”: [

          {

            “actions”: [

              “Microsoft.Compute/virtualMachines/read”,

              “Microsoft.Compute/virtualMachines/start/action”,

              “Microsoft.Compute/virtualMachines/deallocate/action”,

              “Microsoft.Compute/virtualMachines/instanceView/read”,

              “Microsoft.ResourceHealth/availabilityStatuses/read”,

              “Microsoft.Resources/subscriptions/resourceGroups/read”

            ],

            “notActions”: [],

            “dataActions”: [],

            “notDataActions”: []

          }

        ],

        “assignableScopes”: [

          “[subscription().id]”

        ]

      }

    },

    {

      “type”: “Microsoft.ManagedServices/registrationDefinitions”,

      “apiVersion”: “2019-09-01”,

      “name”: “[guid(parameters(‘mspOfferName’))]”,

      “properties”: {

        “registrationDefinitionName”: “[parameters(‘mspOfferName’)]”,

        “description”: “[parameters(‘mspOfferName’)]”,

        “managedByTenantId”: “[parameters(‘managedByTenantId’)]”,

        “authorizations”: [

          {

            “principalId”: “[parameters(‘principalId’)]”, // Your user/group

            “roleDefinitionId”: “[subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, variables(‘vmOperatorRoleId’))]”,

            “principalIdDisplayName”: “VM Operations Team”

          }

        ]

      }

    }

  ]

}

Pattern B: Pre-create in Customer Tenant

For highly regulated environments

  1. Create custom role directly in customer tenant
  2. Reference existing role in Lighthouse onboarding
  3. Requires customer cooperation but gives them full visibility

json

“authorizations”: [

  {

    “principalId”: “[parameters(‘principalId’)]”,

    “roleDefinitionId”: “/subscriptions/{customer-sub-id}/providers/Microsoft.Authorization/roleDefinitions/{custom-role-id}”,

    “principalIdDisplayName”: “Security Monitoring Team”

  }

]

  1. Common Least Privilege Custom Role Examples

Example 1: Backup Operator

json

{

  “permissions”: [

    {

      “actions”: [

        “Microsoft.RecoveryServices/vaults/backupFabrics/operationResults/read”,

        “Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/read”,

        “Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/operationResults/read”,

        “Microsoft.RecoveryServices/vaults/backupJobs/*”,

        “Microsoft.RecoveryServices/vaults/backupPolicies/read”,

        “Microsoft.RecoveryServices/vaults/backupProtectedItems/read”,

        “Microsoft.RecoveryServices/vaults/backupProtectionContainers/read”,

        “Microsoft.RecoveryServices/vaults/read”,

        “Microsoft.RecoveryServices/Vaults/backupOperations/read”,

        “Microsoft.RecoveryServices/Vaults/backupValidateOperation/action”

      ]

    }

  ]

}

Example 2: Security Reader + Remediation

json

{

  “permissions”: [

    {

      “actions”: [

        “Microsoft.Security/*/read”,

        “Microsoft.Security/assessments/*”,

        “Microsoft.Security/policies/read”,

        “Microsoft.Security/securityContacts/read”,

        “Microsoft.Security/regulatoryComplianceStandards/read”,

        // Limited write for remediation

        “Microsoft.Security/tasks/start/action”,

        “Microsoft.Sql/servers/firewallRules/write”,

        “Microsoft.Storage/storageAccounts/delete”

      ]

    }

  ]

}

Example 3: Cost Management Operator

json

{

  “permissions”: [

    {

      “actions”: [

        “Microsoft.Consumption/*/read”,

        “Microsoft.CostManagement/*/read”,

        “Microsoft.Billing/billingAccounts/read”,

        “Microsoft.Resources/subscriptions/read”,

        “Microsoft.Resources/tags/read”,

        “Microsoft.Resources/tags/write”  // For cost allocation tagging

      ]

    }

  ]

}

Example 4: Network Security Operator

json

{

  “permissions”: [

    {

      “actions”: [

        “Microsoft.Network/networkSecurityGroups/read”,

        “Microsoft.Network/networkSecurityGroups/securityRules/read”,

        “Microsoft.Network/networkSecurityGroups/securityRules/write”,

        “Microsoft.Network/networkWatchers/queryFlowLogStatus/action”,

        “Microsoft.Network/networkWatchers/securityGroupView/action”,

        “Microsoft.OperationalInsights/workspaces/query/read”

      ]

    }

  ]

}

  1. Advanced Patterns & Best Practices

Pattern: Layered Role Assignment

Assign multiple custom roles to the same principal for different scopes:

json

“authorizations”: [

  {

    “principalId”: “[parameters(‘monitoringTeamId’)]”,

    “roleDefinitionId”: “[subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, variables(‘readerRoleId’))]”,

    “principalIdDisplayName”: “Monitoring Team – Reader”,

    “delegatedRoleDefinitionIds”: [ “acdd72a7-3385-48ef-bd42-f606fba81ae7” ] // Reader

  },

  {

    “principalId”: “[parameters(‘monitoringTeamId’)]”,

    “roleDefinitionId”: “[subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, variables(‘logContributorRoleId’))]”,

    “principalIdDisplayName”: “Monitoring Team – Log Contributor”,

    “delegatedRoleDefinitionIds”: [ “92aaf0da-9dab-42b6-94a3-d43ce8d16293” ] // Log Analytics Contributor

  }

]

Best Practice: Use Deny Assignments with Caution

While you can use NotActions, consider that deny assignments are complex in cross-tenant scenarios and should be used sparingly.

Best Practice: Regular Role Auditing

powershell

# Check what custom roles exist across delegated subscriptions

Get-AzRoleDefinition | Where-Object { $_.IsCustom -eq $true } |

Select-Object Name, Description, Actions, NotActions

Best Practice: Version Control for Roles

Store custom role definitions as ARM templates in source control with proper versioning and change management.

  1. Limitations and Considerations

Consideration

Impact on Cross-Tenant Custom Roles

Role Limit

Up to 5000 custom roles per tenant

Management Complexity

Each custom role requires maintenance and auditing

Permission Changes

Role definition updates may require re-onboarding

Data Actions

Custom roles can include data plane operations (e.g., storage blob contributor)

Inheritance

Roles apply to the delegated scope and all child resources

  1. Implementation Workflow
  1. Audit Requirements: Document exactly what actions each team needs to perform
  2. Map to Azure Actions: Use Get-AzProviderOperation to find exact action names
  3. Create & Test: Develop custom roles in test environment first
  4. Document: Clearly document the purpose and permissions of each role
  5. Deploy via Lighthouse: Include in ARM templates for customer onboarding
  6. Monitor & Refine: Use Azure Activity Logs to identify unused permissions

Summary

Using custom roles with Azure Lighthouse enables truly least-privilege cross-tenant management by:

  • Eliminating over-permission compared to built-in roles
  • Enabling task-specific access for different teams
  • Reducing risk of accidental or malicious changes
  • Meeting compliance requirements for privileged access

The key is careful planning of permission requirements and systematic implementation through well-structured ARM templates during the Lighthouse onboarding process.

what are options for cross tenant management using Entra ID PIM for JIT Access

Excellent question! Using Entra ID Privileged Identity Management (PIM) for Just-In-Time (JIT) access in cross-tenant scenarios is a powerful security pattern that combines the principle of least privilege with time-bound elevation. Here are the comprehensive options and implementation patterns:

  1. Core Architecture: PIM with Azure Lighthouse

The most effective pattern uses PIM in the managing tenant to control access to delegated resources in customer tenants via Azure Lighthouse.

How It Works:

  1. Lighthouse Delegation: Customer delegates resources to your managing tenant
  2. PIM Eligibility: You make users/groups eligible for Azure AD roles in your tenant
  3. JIT Activation: Users activate their eligible role when needed
  4. Cross-Tenant Access: Activated role grants access to customer resources via Lighthouse
  1. Implementation Patterns

Pattern A: PIM for Azure Built-in Roles + Lighthouse

Use PIM to make users eligible for standard roles that map to Lighthouse authorizations:

json

// Lighthouse ARM template with broad authorization

“authorizations”: [

  {

    “principalId”: “[parameters(‘pimEligibleGroupId’)]”, // Security group for PIM

    “roleDefinitionId”: “[parameters(‘contributorRoleId’)]”,

    “principalIdDisplayName”: “PIM-Eligible Support Team”

  }

]

PIM Configuration:

  • Role: Contributor (or other built-in role)
  • Assignment Type: Eligible
  • Members: Security group containing support engineers
  • Activation Requirements: MFA, justification, approval (optional), max duration (e.g., 2 hours)

Pattern B: PIM for Custom Roles + Lighthouse

More granular control with custom roles:

json

// Custom role for specific operations

{

  “Name”: “PIM-JIT-Emergency-Responder”,

  “Actions”: [

    “Microsoft.Compute/virtualMachines/read”,

    “Microsoft.Compute/virtualMachines/start/action”,

    “Microsoft.Compute/virtualMachines/deallocate/action”,

    “Microsoft.Compute/virtualMachines/restart/action”,

    “Microsoft.Support/*”

  ],

  “AssignableScopes”: [“/”]

}

json

// Lighthouse authorization referencing custom role

“authorizations”: [

  {

    “principalId”: “[parameters(’emergencyRespondersGroupId’)]”,

    “roleDefinitionId”: “[subscriptionResourceId(‘Microsoft.Authorization/roleDefinitions’, variables(’emergencyRoleId’))]”,

    “principalIdDisplayName”: “PIM-Emergency-Responders”

  }

]

  1. Specific PIM Configuration Options for Cross-Tenant
  2. Time-Bound Eligibility Settings

powershell

# Example PIM role settings for cross-tenant access

$settings = @{

    “MaxEligibleDuration” = “P90D”  # Maximum eligibility period

    “MaxActiveDuration” = “PT8H”     # Maximum activation duration (8 hours)

    “RequireMFA” = $true

    “RequireJustification” = $true

    “RequireApproval” = $true        # For sensitive roles

    “Approvers” = @($approverGroupId)

}

  1. Multi-Stage Approval Workflows

For highly sensitive customer environments:

  • First approver: Internal team lead
  • Second approver: Customer-nominated contact (via Entra ID B2B)
  • Automatic expiration: Based on risk level
  1. Emergency Access (“Break Glass”)

json

// Custom break-glass role with broader permissions

{

  “Name”: “Break-Glass-Cross-Tenant”,

  “Actions”: [“*”],

  “NotActions”: [

    “Microsoft.Authorization/*/write”,

    “Microsoft.Blueprint/*”,

    “Microsoft.PolicyInsights/*”

  ]

}

PIM Settings:

  • Activation: Requires multiple approvers
  • Duration: Maximum 1-2 hours
  • Notification: Alerts to both internal and customer security teams
  1. Entra ID PIM Role Options for Cross-Tenant
  2. Azure AD Roles (Identity Plane)

These control access to the managing tenant itself:

Role

Use Case for Cross-Tenant

Privileged Role Administrator

For PIM administrators managing the system

Global Reader

Read-only access to monitor cross-tenant operations

Groups Administrator

Manage security groups used for Lighthouse assignments

User Administrator

Manage B2B guest users for customer collaboration

  1. Azure Resource Roles (Resource Plane)

These control access to customer resources via Lighthouse:

Role

JIT Use Case

Reader

Temporary read-only access for audits

Contributor

Emergency incident response

Security Admin

Security investigation and remediation

SQL DB Contributor

Database emergency maintenance

VM Contributor

Virtual machine troubleshooting

  1. Custom Azure Roles

Tailored for specific cross-tenant functions:

json

{

  “Name”: “PIM-Customer-Security-Responder”,

  “Actions”: [

    “Microsoft.Security/*/read”,

    “Microsoft.Security/tasks/*”,

    “Microsoft.Compute/virtualMachines/read”,

    “Microsoft.Compute/virtualMachines/start/action”,

    “Microsoft.Compute/virtualMachines/deallocate/action”,

    “Microsoft.OperationalInsights/workspaces/search/action”

  ]

}

  1. Advanced PIM Patterns for Cross-Tenant

Pattern 1: Tiered Access Model

Pattern 2: Customer-Specific PIM Groups

Create separate PIM-eligible groups for different customers:

powershell

# Customer A – Limited access

New-AzADGroup -DisplayName “PIM-CustomerA-Support” -MailEnabled $false -SecurityEnabled $true

 

# Customer B – Broader access 

New-AzADGroup -DisplayName “PIM-CustomerB-Full” -MailEnabled $false -SecurityEnabled $true

Pattern 3: Time-Bound Lighthouse with PIM

Combine PIM with temporary Lighthouse delegations:

json

{

  “type”: “Microsoft.ManagedServices/registrationDefinitions”,

  “properties”: {

    “authorizations”: [

      {

        “principalId”: “[parameters(‘pimGroupId’)]”,

        “roleDefinitionId”: “[parameters(‘contributorRoleId’)]”,

        “principalIdDisplayName”: “JIT-Support-Team”

      }

    ],

    “eligibleAuthorizations”: [

      {

        “principalId”: “[parameters(‘pimGroupId’)]”,

        “roleDefinitionId”: “[parameters(‘contributorRoleId’)]”,

        “principalIdDisplayName”: “JIT-Support-Team”,

        “justInTimeAccessPolicy”: {

          “multiFactorAuthProvider”: “Azure”,

          “maximumActivationDuration”: “PT8H”

        }

      }

    ]

  }

}

  1. Automation and Integration Options
  2. PowerShell Automation for PIM Activation

powershell

# Function to request PIM activation for cross-tenant access

function Request-CrossTenantPIMAccess {

    param(

        [string]$RoleName,

        [string]$CustomerName,

        [string]$Justification,

        [int]$DurationHours = 4

    )

   

    # Check current PIM eligibility

    $eligibleAssignments = Get-AzRoleEligibilitySchedule -Filter “asTarget()”

   

    # Request activation

    $activationParams = @{

        RoleDefinitionId = $roleId

        Duration = “PT${DurationHours}H”

        Reason = “Cross-tenant support for $CustomerName: $Justification”

    }

    New-AzRoleAssignmentScheduleRequest @activationParams

}

  1. Logic Apps for Approval Workflows

Create automated approval flows that:

  1. Receive PIM activation requests
  2. Notify customer contacts via email
  3. Wait for customer approval
  4. Auto-approve/deny based on customer response
  5. Log all actions for audit purposes
  1. Azure Monitor Alerts for PIM Activations

json

{

  “alertRule”: {

    “name”: “CrossTenant-PIM-Activation”,

    “condition”: {

      “field”: “category”,

      “equals”: “RoleAssignment”

    },

    “actions”: [

      {

        “actionGroupId”: “/subscriptions/…/actionGroups/SecurityTeam”

      }

    ]

  }

}

  1. Security and Compliance Considerations
  2. Access Reviews

Configure regular access reviews for:

  • PIM-eligible groups membership
  • Customer resource access patterns
  • Activation history and justification quality
  1. Audit and Monitoring

kusto

// KQL query to monitor cross-tenant PIM activations

AuditLogs

| where OperationName == “Elevate access (PIM)”

| where Result == “success”

| extend TargetTenant = tostring(TargetResources[0].DisplayName)

| project TimeGenerated, Identity, TargetTenant, ResultReason

  1. Conditional Access Policies

Integrate with Conditional Access for:

  • Device compliance requirements
  • Location-based restrictions (only activate from corporate IPs)
  • Session controls for sensitive customers
  1. Implementation Checklist
  • Define JIT use cases for each customer/cross-tenant scenario
  • Create custom roles with least privilege for common tasks
  • Establish PIM-eligible security groups in managing tenant
  • Configure PIM policies with appropriate approval workflows
  • Integrate Lighthouse delegations with PIM group principals
  • Set up monitoring and alerting for PIM activations
  • Conduct access reviews regularly
  • Document procedures for emergency and routine JIT access
  • Train users on PIM activation and justification requirements

Summary

Using Entra ID PIM for JIT access in cross-tenant management provides:

✅ Time-bound, approved access to customer resources
✅ Audit trail of all activations and justifications
✅ Reduced standing privileges across tenant boundaries
✅ Flexible approval workflows involving customer stakeholders
✅ Integration with Conditional Access for additional security controls

The key is combining PIM’s eligibility model with Azure Lighthouse’s resource delegation to create a secure, auditable, and efficient cross-tenant access management system.

what are options for cross tenant management using Entra ID Conditional Access Policy

Excellent question! Using Entra ID Conditional Access (CA) for cross-tenant management provides critical security controls that extend beyond your tenant boundaries. Here are the comprehensive options and implementation patterns:

  1. Core Architecture: Where Conditional Access Applies

Key Understanding:

  • CA policies are enforced in the tenant where the identity resides
  • For cross-tenant scenarios, this means:
    • Your managing tenant: Controls access for YOUR employees
    • Customer tenants: Control access for THEIR employees accessing your services
  1. Conditional Access for Azure Lighthouse Scenarios

Pattern A: Protect Access TO Customer Resources

Apply CA policies in YOUR managing tenant to control how your staff accesses delegated customer resources:

json

// CA Policy: Require MFA and compliant device for service desk

{

    “displayName”: “CA01 – Lighthouse Access – Require MFA + Compliant Device”,

    “users”: {

        “include”: [“Lighthouse-ServiceDesk-Group”],

        “exclude”: [“Break-Glass-Accounts”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “conditions”: {

        “locations”: {

            “include”: [“All”]

        },

        “clientApps”: {

            “include”: [“Browser”, “MobileAppsAndDesktopClients”]

        }

    },

    “grant”: {

        “operator”: “AND”,

        “controls”: [

            { “control”: “RequireMultiFactorAuthentication” },

            { “control”: “RequireCompliantDevice” }

        ]

    }

}

Pattern B: Time and Location-Based Restrictions

json

// CA Policy: Restrict support hours and locations

{

    “displayName”: “CA02 – Lighthouse – Business Hours Only”,

    “users”: {

        “include”: [“All-Lighthouse-Engineers”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “conditions”: {

        “locations”: {

            “include”: [“Corporate-IP-Ranges”],

            “exclude”: [“All”]

        },

        “times”: {

            “include”: [

                {“day”: “monday”, “hours”: “0600-1800”},

                {“day”: “tuesday”, “hours”: “0600-1800”},

                {“day”: “friday”, “hours”: “0600-1700”}

            ],

            “exclude”: [“All”]

        }

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “Block” }

        ]

    }

}

  1. Cross-Tenant Access Settings + Conditional Access

Leverage Entra ID Cross-Tenant Access Settings (XTAS) for B2B Collaboration:

Inbound Access Settings (Customers accessing YOUR tenant)

json

// In your managing tenant – control how external users access

{

    “tenantRestrictions”: {

        “partnerTenantId”: “customer-tenant-id”,

        “inboundTrust”: {

            “mfa”: “acceptsMfa”,

            “compliance”: “acceptsCompliance”

        },

        “inboundAccess”: {

            “applications”: {

                “accessType”: “allowed”,

                “targetApplications”: [“your-saas-app-id”]

            }

        }

    }

}

Outbound Access Settings (Your users accessing CUSTOMER tenants)

json

// In your managing tenant – control what your users can access externally

{

    “tenantRestrictions”: {

        “partnerTenantId”: “customer-tenant-id”,

        “outboundAccess”: {

            “applications”: {

                “accessType”: “blocked”,

                “targetApplications”: [“unsanctioned-customer-app-id”]

            }

        }

    }

}

  1. Specific Conditional Access Policy Examples for Cross-Tenant

Policy 1: High-Risk Customer Access

json

{

    “displayName”: “CA03 – High-Risk Customers – Require MFA + Trusted Location”,

    “users”: {

        “include”: [“High-Risk-Customer-Support-Team”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “conditions”: {

        “locations”: {

            “include”: [“Trusted-IP-Ranges”],

            “exclude”: [“All”]

        },

        “userRisk”: {

            “include”: [“High”, “Medium”]

        }

    },

    “grant”: {

        “operator”: “AND”,

        “controls”: [

            { “control”: “RequireMultiFactorAuthentication” },

            { “control”: “RequirePasswordChange” }

        ]

    }

}

Policy 2: Customer Data Protection

json

{

    “displayName”: “CA04 – Customer Data – Require App Protection”,

    “users”: {

        “include”: [“All-Customer-Facing-Users”]

    },

    “applications”: {

        “include”: [“Office365”, “Your-Customer-Portal-App”]

    },

    “conditions”: {

        “clientApps”: {

            “include”: [“MobileAppsAndDesktopClients”]

        },

        “platforms”: {

            “include”: [“Android”, “iOS”]

        }

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “RequireAppProtectionPolicy” },

            { “control”: “Block” }

        ]

    }

}

Policy 3: Session Management for Customer Access

json

{

    “displayName”: “CA05 – Customer Portal – Sign-in Frequency”,

    “users”: {

        “include”: [“External-Collaborators-Group”]

    },

    “applications”: {

        “include”: [“Your-Customer-Portal-App”]

    },

    “session”: {

        “signInFrequency”: {

            “value”: 4,

            “type”: “hours”,

            “isEnabled”: true

        },

        “persistentBrowser”: {

            “mode”: “never”,

            “isEnabled”: true

        }

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “Block” }

        ]

    }

}

  1. Advanced Cross-Tenant Conditional Access Patterns

Pattern 1: Tiered Access Based on Customer Sensitivity

Pattern 2: Customer-Specific CA Policies

Create dynamic groups based on customer assignments:

json

// CA Policy for Financial Services Customers

{

    “displayName”: “CA-FinServ-Customers – Stricter Controls”,

    “users”: {

        “include”: [“FinServ-Support-Team-DynamicGroup”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “grant”: {

        “operator”: “AND”,

        “controls”: [

            { “control”: “RequireMultiFactorAuthentication” },

            { “control”: “RequireCompliantDevice” },

            { “control”: “RequireApprovedClientApp” }

        ]

    }

}

Pattern 3: Break-Glass Emergency Access

json

{

    “displayName”: “CA-BreakGlass – Emergency Bypass”,

    “users”: {

        “include”: [“Break-Glass-Accounts”]

    },

    “applications”: {

        “include”: [“All”]

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “Block” }

        ]

    },

    “session”: null,

    “state”: “disabled”  // Enable only during emergencies

}

  1. Integration with Other Entra ID Capabilities
  2. Conditional Access + Identity Protection

json

// Automatically require password reset for risky sign-ins

{

    “displayName”: “CA-Risky-Signins – Cross-Tenant Access”,

    “users”: {

        “include”: [“All-Lighthouse-Users”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “conditions”: {

        “userRisk”: {

            “include”: [“High”]

        }

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “RequirePasswordChange” },

            { “control”: “Block” }

        ]

    }

}

  1. Conditional Access + Terms of Use

json

// Require acceptance of customer data handling policy

{

    “displayName”: “CA-Require-Data-Agreement”,

    “users”: {

        “include”: [“All-Customer-Facing-Users”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”, “Your-Customer-Portal”]

    },

    “grant”: {

        “operator”: “AND”,

        “controls”: [

            { “control”: “RequireTermsOfUse” },

            { “control”: “RequireMultiFactorAuthentication” }

        ]

    }

}

  1. Device Filter-based Policies

json

// Use device filters for granular control

{

    “displayName”: “CA-Corporate-Devices-Only”,

    “users”: {

        “include”: [“Lighthouse-Engineering-Team”]

    },

    “applications”: {

        “include”: [“Microsoft Azure Management”]

    },

    “conditions”: {

        “devices”: {

            “deviceFilter”: {

                “mode”: “include”,

                “rule”: “device.trustType -ne \”ServerAD\” -or device.isCompliant -eq True”

            }

        }

    },

    “grant”: {

        “operator”: “OR”,

        “controls”: [

            { “control”: “Block” }

        ]

    }

}

  1. Monitoring and Reporting for Cross-Tenant CA
  2. Azure Monitor Workbooks for Cross-Tenant Insights

kusto

// KQL query for cross-tenant CA monitoring

SigninLogs

| where ConditionalAccessPolicies != “[]”

| where ResourceTenantId != HomeTenantId

| extend CAResult = ConditionalAccessPolicies[0].result

| project TimeGenerated, UserPrincipalName, AppDisplayName,

          ResourceTenantId, CAResult, IPAddress, Location

  1. Alert Rules for Cross-Tenant Policy Failures

json

{

    “alertRule”: {

        “displayName”: “Cross-Tenant CA Blocked Sign-ins”,

        “description”: “Alert when CA policies block cross-tenant access”,

        “condition”: {

            “allOf”: [

                {

                    “field”: “SigninLogs”,

                    “operator”: “Contains”,

                    “value”: “block”

                },

                {

                    “field”: “SigninLogs”,

                    “operator”: “Contains”,

                    “value”: “ResourceTenantId”

                }

            ]

        },

        “actions”: [

            {

                “actionGroupId”: “/subscriptions/…/actionGroups/SecurityTeam”

            }

        ]

    }

}

  1. Implementation Strategy and Best Practices

Phase 1: Baseline Policies

  1. Require MFA for all external access
  2. Block legacy authentication protocols
  3. Require compliant devices for administrative access

Phase 2: Customer-Specific Policies

  1. Create customer sensitivity tiers
  2. Implement location-based restrictions for high-sensitivity customers
  3. Configure session controls for external applications

Phase 3: Advanced Protections

  1. Integrate with Identity Protection for risk-based policies
  2. Implement Terms of Use for data handling agreements
  3. Create emergency access procedures with appropriate controls

Best Practices:

  • Use report-only mode initially to test policies
  • Create dynamic groups for customer-based assignments
  • Monitor sign-in logs specifically for cross-tenant activity
  • Regularly review and update CA policies based on new threats
  • Coordinate with customers on their CA requirements and trusted locations
  1. Customer Communication Template

When implementing cross-tenant CA policies, communicate with customers:

text

Subject: Enhanced Security Controls for Your Azure Environment

 

Dear [Customer Name],

 

As part of our ongoing security commitment, we’re implementing additional Conditional Access controls for accessing your Azure environment:

 

  • Multi-Factor Authentication required for all support access
  • Device compliance requirements for administrative tasks
  • Location-based restrictions aligned with your security policies
  • Session timeouts for extended access periods

 

These controls help ensure that access to your environment meets the highest security standards.

 

Please whitelist our corporate IP ranges: [Your IP Ranges]

Summary

Using Entra ID Conditional Access for cross-tenant management provides:

✅ Granular security controls based on user, device, location, and risk
✅ Consistent policy enforcement across all customer tenants
✅ Risk-based access decisions using Identity Protection integration
✅ Session controls for sensitive customer data access
✅ Compliance alignment with customer security requirements

The key is layering CA policies that become progressively stricter based on customer sensitivity and access scenarios, while maintaining operational efficiency through proper planning and communication.

what are options for cross tenant management using Azure centralised logging and monitoring?

Excellent question! Centralized logging and monitoring is a critical component of effective cross-tenant management, providing visibility, security, and operational insights across all customer environments. Here are the comprehensive options and patterns:

  1. Core Architecture Patterns

Pattern A: Hub-and-Spoke Model (Recommended)

Central Logging Workspace in Managing Tenant

  • Single Log Analytics workspace in your managing tenant
  • Data collected from all customer tenants
  • Unified querying, alerting, and dashboards

Pattern B: Regional Hub Model

Multiple Central Workspaces (e.g., East US, West Europe)

  • Works better for data residency requirements
  • More complex to manage but addresses compliance needs

Pattern C: Customer-Specific with Central Aggregation

Local workspaces in customer tenants + central aggregation

  • Customers retain their own data
  • Selective data forwarded to central location
  1. Data Collection Methods

Method 1: Azure Monitor Agent (AMA) – Cross-Workspace

Collect data from customer VMs/Resources directly to your central workspace

json

// Data Collection Rule (DCR) in customer tenant targeting central workspace

{

    “location”: “eastus”,

    “properties”: {

        “dataSources”: {

            “performanceCounters”: [

                {

                    “name”: “perfCounterDataSource”,

                    “streams”: [“Microsoft-Perf”],

                    “scheduledTransferPeriod”: “PT1M”,

                    “samplingFrequencyInSeconds”: 60,

                    “counterSpecifier”: “\\Processor(_Total)\\% Processor Time”

                }

            ],

            “windowsEventLogs”: [

                {

                    “name”: “eventLogDataSource”,

                    “streams”: [“Microsoft-WindowsEvent”],

                    “scheduledTransferPeriod”: “PT1M”,

                    “xPathQueries”: [“Security!*[System[(Level=1 or Level=2 or Level=3)]]”]

                }

            ]

        },

        “destinations”: {

            “logAnalytics”: [

                {

                    “workspaceResourceId”: “/subscriptions/{managing-sub}/resourcegroups/{rg}/providers/microsoft.operationalinsights/workspaces/{central-workspace}”,

                    “name”: “centralWorkspace”

                }

            ]

        },

        “dataFlows”: [

            {

                “streams”: [“Microsoft-Perf”, “Microsoft-WindowsEvent”],

                “destinations”: [“centralWorkspace”]

            }

        ]

    }

}

Method 2: Diagnostic Settings – Cross-Tenant

Send Azure resource logs directly to central workspace

json

// Diagnostic setting on customer resource

{

    “properties”: {

        “workspaceId”: “/subscriptions/{managing-sub}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{central-workspace}”,

        “logs”: [

            {

                “category”: “Administrative”,

                “enabled”: true,

                “retentionPolicy”: {

                    “days”: 90,

                    “enabled”: true

                }

            }

        ]

    }

}

Method 3: Azure Lighthouse-Aware Queries

Query across multiple workspaces using KQL

kql

// Cross-workspace query from managing tenant

union workspace(‘customer1-workspace’).SecurityEvent,

      workspace(‘customer2-workspace’).SecurityEvent,

      workspace(‘customer3-workspace’).SecurityEvent

| where TimeGenerated >= ago(24h)

| where EventID == 4624 // Successful logons

| project TimeGenerated, Computer, Account, IpAddress, Workspace = _ResourceId

  1. Centralized Monitoring Solutions
  2. Azure Dashboard – Cross-Tenant Views

Create unified dashboards in managing tenant

json

{

    “lenses”: {

        “0”: {

            “order”: 0,

            “parts”: [

                {

                    “position”: {

                        “x”: 0,

                        “y”: 0,

                        “rowSpan”: 2,

                        “colSpan”: 3

                    },

                    “metadata”: {

                        “type”: “Extension/Microsoft_OperationsManagementSuite_Workspace/PartType/LogsDashboardPart”,

                        “inputs”: [

                            {

                                “name”: “Query”,

                                “value”: “Perf | summarize AggregatedValue = avg(CounterValue) by Computer, bin(TimeGenerated, 1h) | where Computer contains ‘customer'”

                            }

                        ]

                    }

                }

            ]

        }

    }

}

  1. Azure Monitor Workbooks – Multi-Tenant Reporting

Interactive reports with tenant filtering

json

// Workbook template for cross-tenant security overview

{

    “version”: “1.0”,

    “items”: [

        {

            “type”: “query”,

            “content”: {

                “query”: “SecurityEvent | where TimeGenerated >= ago(7d) | summarize EventCount = count() by Tenant = tostring(split(_ResourceId, ‘/’)[8]), Activity”,

                “size”: 20,

                “title”: “Security Events by Tenant”,

                “visualization”: “barchart”

            }

        }

    ],

    “parameters”: [

        {

            “name”: “TenantFilter”,

            “type”: “dropdown”,

            “label”: “Select Tenant”,

            “query”: “find where TimeGenerated > ago(1h) | distinct Tenant”

        }

    ]

}

  1. Azure Monitor Alerts – Cross-Tenant Alerting

Unified alert rules covering all customers

json

// Alert rule for critical security events across all tenants

{

    “location”: “global”,

    “properties”: {

        “description”: “Alert on critical security events across all customer tenants”,

        “severity”: 1,

        “enabled”: true,

        “condition”: {

            “allOf”: [

                {

                    “field”: “Entities”,

                    “operator”: “Contains”,

                    “values”: [“SecurityEvent”]

                },

                {

                    “field”: “AlertSeverity”,

                    “operator”: “Equals”,

                    “values”: [“High”]

                }

            ]

        },

        “actions”: [

            {

                “actionGroupId”: “/subscriptions/{sub}/resourceGroups/{rg}/providers/microsoft.insights/actionGroups/CrossTenant-SecurityTeam”

            }

        ]

    }

}

  1. Specific Cross-Tenant Monitoring Scenarios

Scenario 1: Security & Compliance Monitoring

kql

// Cross-tenant security baseline monitoring

let timeRange = 1h;

union isfuzzy=true

    workspace(‘customer1-workspace’).SecurityEvent,

    workspace(‘customer2-workspace’).SecurityEvent,

    workspace(‘customer3-workspace’).SecurityEvent

| where TimeGenerated >= ago(timeRange)

| where EventID in (4625, 4648, 4672)  // Failed logons, special privileges

| extend Tenant = extract(@”\/subscriptions\/([^\/]+)”, 1, _ResourceId)

| summarize FailedAttempts = count() by Tenant, Account, Computer, bin(TimeGenerated, 15m)

| where FailedAttempts > 5

Scenario 2: Performance & Health Monitoring

kql

// Cross-tenant performance analysis

Perf

| where TimeGenerated >= ago(1h)

| where ObjectName == “Processor” and CounterName == “% Processor Time”

| extend Tenant = tostring(split(_ResourceId, ‘/’)[8])

| summarize

    AvgCPU = avg(CounterValue),

    P95CPU = percentile(CounterValue, 95),

    MaxCPU = max(CounterValue)

    by Tenant, Computer, bin(TimeGenerated, 5m)

| where AvgCPU > 80

Scenario 3: Cost & Resource Optimization

kql

// Cross-tenant resource utilization and cost tracking

AzureActivity

| where TimeGenerated >= ago(7d)

| where OperationNameValue endswith “write”

| extend ResourceType = tostring(parse_json(Properties).entity),

       Tenant = Caller

| summarize

    ResourceChanges = count(),

    DistinctUsers = dcount(Caller)

    by Tenant, ResourceType, bin(TimeGenerated, 1d)

  1. Advanced Centralized Logging Patterns

Pattern 1: Tiered Data Collection

json

// Different data collection rules based on customer tier

{

    “BasicTier”: {

        “performanceCounters”: [“\\Processor\\% Processor Time”, “\\Memory\\Available MBytes”],

        “eventLogs”: [“Security”, “System”],

        “samplingFrequency”: “PT5M”

    },

    “PremiumTier”: {

        “performanceCounters”: [“*”],  // All counters

        “eventLogs”: [“Security”, “System”, “Application”, “Windows PowerShell”],

        “samplingFrequency”: “PT1M”,

        “syslog”: [“auth”, “authpriv”, “daemon”]

    }

}

Pattern 2: Customer-Specific Data Routing

kql

// KQL function for customer-specific data routing

let CustomerDataRouting = (customerName: string) {

    union

    workspace(${customerName}-infra).Perf,

    workspace(${customerName}-apps).AppExceptions,

    workspace(${customerName}-sec).SecurityEvent

};

CustomerDataRouting(“Contoso”)

| where TimeGenerated >= ago(1h)

Pattern 3: Automated Baseline & Anomaly Detection

kql

// Cross-tenant anomaly detection

let baselineData =

    Perf

    | where TimeGenerated >= ago(30d)

    | where ObjectName == “Processor” and CounterName == “% Processor Time”

    | summarize baseline=percentile(CounterValue, 95) by Computer;

Perf

| where TimeGenerated >= ago(1h)

| where ObjectName == “Processor” and CounterName == “% Processor Time”

| join kind=inner baselineData on Computer

| extend deviation = CounterValue – baseline

| where deviation > 20  // More than 20% above baseline

| project TimeGenerated, Computer, CounterValue, baseline, deviation, Tenant

  1. Integration with Azure Services
  2. Azure Sentinel for Cross-Tenant SIEM

kql

// Sentinel cross-workspace hunting query

union isfuzzy=true workspace(‘customer1’).SecurityEvent,

      workspace(‘customer2’).SecurityEvent,

      workspace(‘customer3’).SecurityEvent

| where TimeGenerated >= ago(1d)

| where EventID == 4688  // Process creation

| where NewProcessName contains “powershell”

| extend CommandLine = tostring(CommandLine)

| where CommandLine contains “-EncodedCommand”

| project TimeGenerated, Computer, Account, CommandLine, Tenant

  1. Azure Resource Graph for Inventory

kql

// Cross-tenant resource inventory

Resources

| where type in~ (‘microsoft.compute/virtualmachines’, ‘microsoft.network/virtualnetworks’)

| extend Tenant = subscriptionId

| project Tenant, ResourceType = type, Name, Location, SKU, Status = properties.provisioningState

  1. Application Insights Cross-Tenant

kql

// Monitor multi-tenant applications

union app(‘customer1-app’).requests,

      app(‘customer2-app’).requests,

      app(‘customer3-app’).requests

| where timestamp >= ago(1h)

| summarize

    TotalRequests = count(),

    FailedRequests = countif(success == false),

    AvgDuration = avg(duration)

    by Customer = appName, bin(timestamp, 5m)

  1. Automation and Deployment
  2. ARM Template for Cross-Tenant Monitoring

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “customerSubscriptionId”: { “type”: “string” },

        “centralWorkspaceId”: { “type”: “string” }

    },

    “resources”: [

        {

            “type”: “Microsoft.Resources/deployments”,

            “apiVersion”: “2020-10-01”,

            “name”: “crossTenantMonitoring”,

            “subscriptionId”: “[parameters(‘customerSubscriptionId’)]”,

            “properties”: {

                “mode”: “Incremental”,

                “template”: {

                    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

                    “contentVersion”: “1.0.0.0”,

                    “resources”: [

                        {

                            “type”: “Microsoft.Insights/dataCollectionRules”,

                            “apiVersion”: “2022-06-01”,

                            “name”: “CrossTenant-DCR”,

                            “location”: “eastus”,

                            “properties”: {

                                “dataSources”: {

                                    “performanceCounters”: [/*…*/],

                                    “windowsEventLogs”: [/*…*/]

                                },

                                “destinations”: {

                                    “logAnalytics”: [

                                        {

                                            “workspaceResourceId”: “[parameters(‘centralWorkspaceId’)]”,

                                            “name”: “centralLogs”

                                        }

                                    ]

                                },

                                “dataFlows”: [/*…*/]

                            }

                        }

                    ]

                }

            }

        }

    ]

}

  1. PowerShell Automation

powershell

# Deploy cross-tenant monitoring at scale

function Deploy-CrossTenantMonitoring {

    param(

        [string[]]$CustomerSubscriptions,

        [string]$CentralWorkspaceId

    )

   

    foreach ($sub in $CustomerSubscriptions) {

        # Set context to customer subscription

        Set-AzContext -SubscriptionId $sub

       

        # Create Data Collection Rule

        New-AzDataCollectionRule -ResourceGroupName “monitoring-rg” -Name “CrossTenant-DCR” -Location “EastUS” -JsonString (Get-DCRTemplate -WorkspaceId $CentralWorkspaceId)

       

        # Deploy diagnostic settings to key resources

        Set-AzDiagnosticSetting -ResourceId “/subscriptions/$sub/resourceGroups/*” -WorkspaceId $CentralWorkspaceId -Enabled $true

    }

}

  1. Security and Compliance Considerations
  2. Data Segregation and Access Control

json

// Azure RBAC for workspace access with customer context

{

    “role”: “Log Analytics Reader”,

    “scope”: “/subscriptions/{central-sub}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{workspace}”,

    “conditions”: [

        {

            “condition”: “(@Resource[Microsoft.OperationalInsights/workspaces:TenantId] StringEqualsIgnoreCase ‘customer-tenant-id’)”

        }

    ]

}

  1. Data Retention Policies

json

// Tiered retention based on data sensitivity

{

    “tableLevelRetentionPolicies”: {

        “SecurityEvent”: 365,  // 1 year for security

        “Perf”: 93,           // 93 days for performance

        “Heartbeat”: 30,      // 30 days for heartbeat

        “AzureActivity”: 180  // 6 months for activity logs

    }

}

  1. Cost Management

kql

// Monitor and optimize cross-tenant logging costs

Usage

| where TimeGenerated >= ago(30d)

| where DataType in (“Perf”, “SecurityEvent”, “WindowsEvent”)

| extend Tenant = tostring(split(_ResourceId, ‘/’)[8])

| summarize

    TotalGB = sum(Quantity),

    EstimatedCost = sum(Quantity) * 2.76  // Per GB pricing

    by Tenant, DataType, bin(TimeGenerated, 1d)

  1. Implementation Checklist
  • Design data collection strategy (what, how, where)
  • Establish central Log Analytics workspace in managing tenant
  • Configure cross-tenant data collection rules using Lighthouse
  • Implement diagnostic settings for Azure resource logs
  • Create unified dashboards and workbooks
  • Set up cross-tenant alert rules
  • Establish data retention and archiving policies
  • Implement access controls and data segregation
  • Configure cost monitoring and optimization
  • Develop runbooks for common issues
  • Establish compliance and audit reporting

Summary

Centralized logging and monitoring for cross-tenant management provides:

✅ Unified visibility across all customer environments
✅ Standardized alerting and incident response
✅ Cost-effective data aggregation and analysis
✅ Security compliance and audit capabilities
✅ Operational efficiency through automation
✅ Proactive monitoring and trend analysis

The key success factors are proper architecture planning, automated deployment, careful cost management, and maintaining appropriate data segregation while still achieving the benefits of centralized visibility.

what are options for cross tenant management using Naming Convention and Tagging?

Excellent question! Naming conventions and tagging are foundational for effective cross-tenant management, providing organization, automation, and cost management across multiple customer environments. Here are comprehensive options and patterns:

  1. Cross-Tenant Naming Convention Framework
  2. Resource Naming Standard Structure

text

{tenant}-{environment}-{location}-{service}-{instance}-{role}

Example Implementation:

json

{

    “namingStandard”: {

        “tenant”: [“contoso”, “fabrikam”, “adventureworks”],

        “environment”: [“prod”, “dev”, “test”, “stg”, “uat”],

        “location”: [“eus”, “weu”, “neu”, “sea”],

        “service”: [“vm”, “sql”, “str”, “vnet”, “nsg”],

        “instance”: [“001”, “002”, “web”, “api”, “db”],

        “role”: [“primary”, “secondary”, “dr”, “mgmt”]

    }

}

  1. Real-World Naming Examples

bash

# Virtual Machine

contoso-prod-eus-vm-web-001

fabrikam-dev-weu-vm-sql-primary

 

# Storage Account (with uniqueness)

contosoprodstrweubackup001

fabrikamdevstrsuslogs002

 

# Virtual Network

contoso-prod-eus-vnet-core-001

fabrikam-dev-weu-vnet-app-001

 

# Resource Group

rg-contoso-prod-eus-network

rg-fabrikam-dev-weu-databases

  1. Comprehensive Tagging Strategy for Cross-Tenant
  2. Mandatory Tags for All Resources

json

{

    “mandatoryTags”: {

        “Tenant”: “contoso”,

        “Environment”: “production”,

        “CostCenter”: “IT-12345”,

        “Project”: “CustomerPortal”,

        “ManagedBy”: “MSP-Operations”,

        “DataClassification”: “Confidential”,

        “Compliance”: “PCI-DSS”,

        “DeploymentVersion”: “v2.1.0”

    }

}

  1. Operational Tags

json

{

    “operationalTags”: {

        “ApplicationOwner”: “customer-support@company.com”,

        “TechnicalOwner”: “azure-team@msp.com”,

        “SupportTier”: “24×7-Premium”,

        “BackupRetention”: “30-days”,

        “MaintenanceWindow”: “Sat-02:00-04:00-UTC”,

        “DRPriority”: “Tier-1”,

        “AutoShutdown”: “Enabled”

    }

}

  1. Business and Billing Tags

json

{

    “businessTags”: {

        “BusinessUnit”: “Customer-Facing-Apps”,

        “InvoiceGroup”: “Contoso-Q2-2024”,

        “ChargebackDepartment”: “IT-Infrastructure”,

        “ProjectID”: “PRJ-2024-001”,

        “CustomerPO”: “PO-789123”,

        “ServiceLevel”: “Gold”

    }

}

  1. Implementation Patterns

Pattern A: ARM Template Tag Inheritance

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “tenantCode”: { “type”: “string” },

        “environment”: { “type”: “string” },

        “projectName”: { “type”: “string” }

    },

    “variables”: {

        “baseTags”: {

            “Tenant”: “[parameters(‘tenantCode’)]”,

            “Environment”: “[parameters(‘environment’)]”,

            “Project”: “[parameters(‘projectName’)]”,

            “DeploymentDate”: “[utcNow()]”,

            “ManagedBy”: “AzureLighthouse-MSP”

        }

    },

    “resources”: [

        {

            “type”: “Microsoft.Compute/virtualMachines”,

            “apiVersion”: “2023-03-01”,

            “name”: “[concat(parameters(‘tenantCode’), ‘-‘, parameters(‘environment’), ‘-vm-web-001’)]”,

            “location”: “[resourceGroup().location]”,

            “tags”: “[variables(‘baseTags’)]”,

            “properties”: { /* VM properties */ }

        }

    ]

}

Pattern B: Azure Policy for Tag Enforcement

json

{

    “mode”: “Indexed”,

    “policyRule”: {

        “if”: {

            “allOf”: [

                {

                    “field”: “type”,

                    “equals”: “Microsoft.Resources/subscriptions/resourceGroups”

                },

                {

                    “field”: “tags[‘Tenant’]”,

                    “exists”: false

                }

            ]

        },

        “then”: {

            “effect”: “append”,

            “details”: [

                {

                    “field”: “tags[‘Tenant’]”,

                    “value”: “[subscription().displayName]”

                },

                {

                    “field”: “tags[‘Environment’]”,

                    “value”: “unspecified”

                },

                {

                    “field”: “tags[‘ManagedBy’]”,

                    “value”: “cross-tenant-mgmt”

                }

            ]

        }

    }

}

Pattern C: PowerShell Automation for Tag Management

powershell

function Set-CrossTenantTags {

    param(

        [string]$TenantName,

        [string]$Environment,

        [string]$CostCenter,

        [string]$SubscriptionId

    )

   

    $tags = @{

        “Tenant” = $TenantName

        “Environment” = $Environment

        “CostCenter” = $CostCenter

        “ManagedBy” = “Azure-Lighthouse-MSP”

        “Compliance” = “Standard”

        “LastReviewed” = (Get-Date).ToString(“yyyy-MM-dd”)

    }

   

    # Apply to subscription

    New-AzSubscriptionTag -Tag $tags -SubscriptionId $SubscriptionId

   

    # Apply to all resource groups

    $resourceGroups = Get-AzResourceGroup -SubscriptionId $SubscriptionId

    foreach ($rg in $resourceGroups) {

        Update-AzTag -ResourceId $rg.ResourceId -Tag $tags -Operation Merge

    }

}

  1. Cross-Tenant Resource Identification
  2. Azure Resource Graph Queries with Tags

kql

// Find all resources by tenant

Resources

| where tags[‘Tenant’] =~ ‘contoso’

| project name, type, resourceGroup, subscriptionId, location, tags

 

// Cost analysis by tenant and environment

Resources

| where isnotempty(tags[‘Tenant’])

| extend Tenant = tags[‘Tenant’], Environment = tags[‘Environment’]

| join (ResourceContainers | where type=~’microsoft.resources/subscriptions’ | project subscriptionId, subscriptionName) on subscriptionId

| summarize TotalCost = sum(todouble(properties.cost)) by Tenant, Environment, subscriptionName

 

// Compliance reporting

Resources

| where tags[‘Compliance’] != ‘Compliant’

| extend Tenant = tags[‘Tenant’], Owner = tags[‘ApplicationOwner’]

| project name, type, resourceGroup, Tenant, Owner, ComplianceStatus = tags[‘Compliance’]

  1. Automated Discovery and Tagging

powershell

function Discover-AndTag-TenantResources {

    param([string]$SubscriptionId, [string]$TenantCode)

   

    Set-AzContext -SubscriptionId $SubscriptionId

   

    $resources = Get-AzResource -SubscriptionId $SubscriptionId

   

    foreach ($resource in $resources) {

        $currentTags = $resource.Tags

        if (!$currentTags) { $currentTags = @{} }

       

        # Add cross-tenant tags if missing

        if (!$currentTags[‘Tenant’]) {

            $currentTags[‘Tenant’] = $TenantCode

        }

        if (!$currentTags[‘Environment’]) {

            $currentTags[‘Environment’] = Infer-Environment -ResourceName $resource.Name

        }

        if (!$currentTags[‘ManagedBy’]) {

            $currentTags[‘ManagedBy’] = “Azure-Lighthouse”

        }

       

        # Update resource tags

        Set-AzResource -ResourceId $resource.ResourceId -Tag $currentTags -Force

    }

}

  1. Cost Management and Chargeback
  2. Cost Allocation Tags

json

{

    “chargebackTags”: {

        “BillingEntity”: “Contoso-Corporate”,

        “Department”: “Marketing-Digital”,

        “CostCenter”: “CC-MKT-2024-Q2”,

        “ProjectCode”: “PROJ-CONTOSO-REDESIGN”,

        “BusinessUnit”: “Digital-Transformation”,

        “ServiceCatalog”: “Web-Hosting-Services”

    }

}

  1. Cost Analysis Queries

kql

// Cost by tenant and environment

CostManagement

| where TimeGenerated >= ago(30d)

| extend Tenant = tags[‘Tenant’], Environment = tags[‘Environment’]

| where isnotempty(Tenant)

| summarize TotalCost = sum(Cost) by Tenant, Environment, ServiceName

| order by TotalCost desc

 

// Chargeback reporting

Resources

| extend Department = tags[‘Department’], ProjectCode = tags[‘ProjectCode’]

| where isnotempty(Department)

| join (CostManagement | where Date >= startofmonth(now())) on $left.id == $right.ResourceId

| summarize

    DepartmentCost = sum(Cost),

    ResourceCount = count()

    by Department, ProjectCode, ServiceName

  1. Security and Compliance Tagging
  2. Security Classification Tags

json

{

    “securityTags”: {

        “DataClassification”: “Public|Internal|Confidential|Restricted”,

        “PII”: “Yes|No”,

        “GDPR”: “Applicable|NotApplicable”,

        “BackupRequired”: “Yes|No”,

        “EncryptionRequired”: “Yes|No”,

        “SecurityZone”: “DMZ|Internal|Management”

    }

}

  1. Compliance Enforcement via Policy

json

{

    “if”: {

        “allOf”: [

            {

                “field”: “type”,

                “equals”: “Microsoft.Storage/storageAccounts”

            },

            {

                “field”: “tags[‘DataClassification’]”,

                “equals”: “Confidential”

            },

            {

                “field”: “Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly”,

                “notEquals”: true

            }

        ]

    },

    “then”: {

        “effect”: “deny”,

        “details”: {

            “message”: “Storage accounts with Confidential data must have HTTPS only enabled”

        }

    }

}

  1. Automation and Governance
  2. Azure DevOps Pipeline for Tag Enforcement

yaml

# azure-pipelines.yml

stages:

– stage: ValidateTags

  jobs:

  – job: CheckResourceTags

    steps:

    – task: AzureCLI@2

      inputs:

        azureSubscription: ‘lighthouse-connection’

        scriptType: ‘pscore’

        scriptLocation: ‘inlineScript’

        inlineScript: |

          $requiredTags = @(‘Tenant’, ‘Environment’, ‘CostCenter’, ‘ManagedBy’)

          $resources = az graph query -q “Resources | where resourceGroup =~ ‘$(resourceGroup)'” –output json | ConvertFrom-Json

         

          foreach ($resource in $resources.data) {

            foreach ($tag in $requiredTags) {

              if (!$resource.tags.$tag) {

                Write-Error “Resource $($resource.name) is missing required tag: $tag”

                exit 1

              }

            }

          }

 

– stage: ApplyDefaultTags

  jobs:

  – job: TagResources

    steps:

    – task: AzurePowerShell@5

      inputs:

        azureSubscription: ‘lighthouse-connection’

        ScriptType: ‘InlineScript’

        Inline: |

          $tags = @{

            Tenant = ‘$(tenantName)’

            Environment = ‘$(environment)’

            ManagedBy = ‘Azure-Lighthouse’

            DeploymentPipeline = ‘$(Build.DefinitionName)’

            BuildId = ‘$(Build.BuildId)’

          }

         

          Set-AzResourceGroup -Name ‘$(resourceGroup)’ -Tag $tags

  1. Azure Function for Tag Maintenance

csharp

// C# Azure Function for automated tag management

[FunctionName(“CrossTenantTagManager”)]

public static async Task Run([TimerTrigger(“0 0 2 * * *”)] TimerInfo myTimer, ILogger log)

{

    var tenants = await GetManagedTenantsAsync();

   

    foreach (var tenant in tenants)

    {

        var resources = await GetTenantResourcesAsync(tenant.SubscriptionId);

       

        foreach (var resource in resources)

        {

            var updatedTags = EnsureRequiredTags(resource.Tags, tenant);

            if (updatedTags != resource.Tags)

            {

                await UpdateResourceTagsAsync(resource.ResourceId, updatedTags);

            }

        }

    }

}

 

private static IDictionary<string, string> EnsureRequiredTags(

    IDictionary<string, string> currentTags,

    TenantInfo tenant)

{

    var requiredTags = new Dictionary<string, string>

    {

        [“Tenant”] = tenant.Code,

        [“Environment”] = tenant.Environment,

        [“ManagedBy”] = “Azure-Lighthouse-MSP”,

        [“LastTagReview”] = DateTime.UtcNow.ToString(“yyyy-MM-dd”)

    };

   

    // Merge with existing tags

    return requiredTags

        .Concat(currentTags ?? new Dictionary<string, string>())

        .GroupBy(kvp => kvp.Key)

        .ToDictionary(g => g.Key, g => g.First().Value);

}

  1. Monitoring and Reporting
  2. Tag Compliance Dashboard

kql

// Tag compliance reporting

Resources

| extend

    Tenant = tags[‘Tenant’],

    Environment = tags[‘Environment’],

    ManagedBy = tags[‘ManagedBy’]

| summarize

    TotalResources = count(),

    TaggedWithTenant = countif(isnotempty(Tenant)),

    TaggedWithEnvironment = countif(isnotempty(Environment)),

    TaggedWithManagedBy = countif(isnotempty(ManagedBy))

    by subscriptionId

| extend

    TenantTagCompliance = TaggedWithTenant * 100 / TotalResources,

    EnvironmentTagCompliance = TaggedWithEnvironment * 100 / TotalResources,

    ManagedByTagCompliance = TaggedWithManagedBy * 100 / TotalResources

  1. Resource Inventory by Tenant

kql

// Cross-tenant resource inventory

Resources

| where isnotempty(tags[‘Tenant’])

| extend

    Tenant = tags[‘Tenant’],

    Environment = tags[‘Environment’],

    CostCenter = tags[‘CostCenter’]

| summarize

    ResourceCount = count(),

    Locations = dcount(location),

    ResourceTypes = dcount(type)

    by Tenant, Environment

| order by Tenant, Environment

  1. Implementation Strategy

Phase 1: Foundation

  1. Define naming convention standard
  2. Establish mandatory tag dictionary
  3. Create Azure Policy for tag enforcement
  4. Document standards for all teams

Phase 2: Implementation

  1. Apply policies to all managed tenants
  2. Implement automated tagging solutions
  3. Update deployment templates with tagging
  4. Train teams on naming and tagging standards

Phase 3: Optimization

  1. Implement cost chargeback reporting
  2. Establish compliance monitoring
  3. Create automated remediation
  4. Continuous improvement based on usage patterns

Best Practices:

  • Start simple with 5-10 mandatory tags
  • Use Azure Policy to enforce standards
  • Automate tagging during deployment
  • Regularly audit tag compliance
  • Educate customers on tagging benefits
  • Use consistent casing (PascalCase recommended)
  • Document tag values and meanings

Summary

Effective naming conventions and tagging for cross-tenant management provide:

✅ Resource identification across tenant boundaries
✅ Cost management and chargeback capabilities
✅ Automation enablement through consistent patterns
✅ Security and compliance enforcement
✅ Operational efficiency in management tasks
✅ Reporting and analytics across all customers

The key is establishing consistent standards, enforcing them through automation and policy, and continuously refining based on operational experience across all managed tenants.

what are options for cross tenant management using Azure Private Link

Excellent question! Azure Private Link is a crucial component for secure cross-tenant management, enabling private connectivity between your managing tenant and customer environments without exposing services to the public internet. Here are comprehensive options and implementation patterns:

  1. Core Architecture Patterns

Pattern A: Centralized Private Link Hub

Private connectivity through shared hub virtual network

Pattern B: Direct Private Link per Customer

Dedicated private endpoints for each customer environment

Pattern C: Hybrid DNS Resolution

Central DNS with conditional forwarding to customer DNS

  1. Private Link for Azure PaaS Services Cross-Tenant
  2. Key Azure Services Supporting Private Link
  • Azure Storage (Blob, File, Table, Queue)
  • Azure SQL Database & Azure SQL Managed Instance
  • Azure Key Vault
  • Azure Container Registry
  • Azure App Service & Azure Functions
  • Azure Monitor (Log Analytics, Application Insights)
  • Azure Backup & Azure Site Recovery
  • Azure Automation
  1. Implementation Template for Storage Private Link

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “customerStorageAccountName”: { “type”: “string” },

        “customerSubscriptionId”: { “type”: “string” },

        “hubVNetId”: { “type”: “string” },

        “privateEndpointSubnetId”: { “type”: “string” }

    },

    “resources”: [

        {

            “type”: “Microsoft.Network/privateEndpoints”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(parameters(‘customerStorageAccountName’), ‘-pe’)]”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “subnet”: {

                    “id”: “[parameters(‘privateEndpointSubnetId’)]”

                },

                “privateLinkServiceConnections”: [

                    {

                        “name”: “[concat(parameters(‘customerStorageAccountName’), ‘-pls-connection’)]”,

                        “properties”: {

                            “privateLinkServiceId”: “[resourceId(parameters(‘customerSubscriptionId’), ‘Microsoft.Storage/storageAccounts’, parameters(‘customerStorageAccountName’))]”,

                            “groupIds”: [“blob”]

                        }

                    }

                ]

            }

        },

        {

            “type”: “Microsoft.Network/privateDnsZones”,

            “apiVersion”: “2020-06-01”,

            “name”: “privatelink.blob.core.windows.net”,

            “location”: “global”,

            “resources”: [

                {

                    “type”: “virtualNetworkLinks”,

                    “apiVersion”: “2020-06-01”,

                    “name”: “[concat(‘hub-vnet-link’)]”,

                    “location”: “global”,

                    “dependsOn”: [

                        “[resourceId(‘Microsoft.Network/privateDnsZones’, ‘privatelink.blob.core.windows.net’)]”

                    ],

                    “properties”: {

                        “virtualNetwork”: {

                            “id”: “[parameters(‘hubVNetId’)]”

                        },

                        “registrationEnabled”: false

                    }

                }

            ]

        }

    ]

}

  1. Cross-Tenant Private Link Scenarios

Scenario 1: Secure Log Analytics Workspace Access

Private connectivity to central Log Analytics workspace

json

{

    “resources”: [

        {

            “type”: “Microsoft.OperationalInsights/clusters”,

            “apiVersion”: “2021-06-01”,

            “name”: “central-logs-cluster”,

            “location”: “eastus”,

            “sku”: { “name”: “CapacityReservation”, “capacity”: 1000 }

        },

        {

            “type”: “Microsoft.OperationalInsights/workspaces”,

            “apiVersion”: “2020-08-01”,

            “name”: “central-logs-workspace”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “PerGB2018” },

                “features”: {

                    “clusterResourceId”: “[resourceId(‘Microsoft.OperationalInsights/clusters’, ‘central-logs-cluster’)]”

                }

            }

        },

        {

            “type”: “Microsoft.Network/privateEndpoints”,

            “apiVersion”: “2023-05-01”,

            “name”: “la-workspace-pe”,

            “location”: “eastus”,

            “properties”: {

                “subnet”: { “id”: “[variables(‘privateEndpointSubnetId’)]” },

                “privateLinkServiceConnections”: [

                    {

                        “properties”: {

                            “privateLinkServiceId”: “[resourceId(‘Microsoft.OperationalInsights/workspaces’, ‘central-logs-workspace’)]”,

                            “groupIds”: [“api”]

                        }

                    }

                ]

            }

        }

    ]

}

Scenario 2: Cross-Tenant Azure Automation

Private connectivity for automation runbooks and update management

json

{

    “resources”: [

        {

            “type”: “Microsoft.Automation/automationAccounts”,

            “apiVersion”: “2021-06-22”,

            “name”: “cross-tenant-automation”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “Basic” },

                “publicNetworkAccess”: false  // Force private access only

            }

        },

        {

            “type”: “Microsoft.Network/privateEndpoints”,

            “apiVersion”: “2023-05-01”,

            “name”: “automation-account-pe”,

            “properties”: {

                “subnet”: { “id”: “[variables(‘automationSubnetId’)]” },

                “privateLinkServiceConnections”: [

                    {

                        “properties”: {

                            “privateLinkServiceId”: “[resourceId(‘Microsoft.Automation/automationAccounts’, ‘cross-tenant-automation’)]”,

                            “groupIds”: [“Webhook”, “DSCAndHybridWorker”]

                        }

                    }

                ]

            }

        }

    ]

}

Scenario 3: Secure Key Vault Access

Private connectivity for cross-tenant secret management

json

{

    “resources”: [

        {

            “type”: “Microsoft.KeyVault/vaults”,

            “apiVersion”: “2023-02-01”,

            “name”: “cross-tenant-kv”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “standard”, “family”: “A” },

                “tenantId”: “[subscription().tenantId]”,

                “enableRbacAuthorization”: true,

                “publicNetworkAccess”: “Disabled”  // Enforce private access

            }

        },

        {

            “type”: “Microsoft.Network/privateEndpoints”,

            “apiVersion”: “2023-05-01”,

            “name”: “keyvault-pe”,

            “properties”: {

                “subnet”: { “id”: “[variables(‘keyVaultSubnetId’)]” },

                “privateLinkServiceConnections”: [

                    {

                        “properties”: {

                            “privateLinkServiceId”: “[resourceId(‘Microsoft.KeyVault/vaults’, ‘cross-tenant-kv’)]”,

                            “groupIds”: [“vault”]

                        }

                    }

                ]

            }

        }

    ]

}

  1. DNS Configuration for Cross-Tenant Private Link
  2. Central Private DNS Zones in Hub

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/privateDnsZones”,

            “apiVersion”: “2020-06-01”,

            “name”: “privatelink.blob.core.windows.net”,

            “location”: “global”

        },

        {

            “type”: “Microsoft.Network/privateDnsZones”,

            “apiVersion”: “2020-06-01”,

            “name”: “privatelink.azure-automation.net”,

            “location”: “global”

        },

        {

            “type”: “Microsoft.Network/privateDnsZones”,

            “apiVersion”: “2020-06-01”,

            “name”: “privatelink.vaultcore.azure.net”,

            “location”: “global”

        },

        {

            “type”: “Microsoft.Network/privateDnsZones/virtualNetworkLinks”,

            “apiVersion”: “2020-06-01”,

            “name”: “[concat(‘hub-vnet-link-‘, parameters(‘tenantName’))]”,

            “location”: “global”,

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/privateDnsZones’, ‘privatelink.blob.core.windows.net’)]”

            ],

            “properties”: {

                “virtualNetwork”: {

                    “id”: “[parameters(‘hubVNetId’)]”

                },

                “registrationEnabled”: false

            }

        }

    ]

}

  1. PowerShell DNS Configuration

powershell

function Configure-CrossTenantPrivateDNS {

    param(

        [string]$HubSubscriptionId,

        [string]$CustomerSubscriptionId,

        [string]$CustomerVNetId

    )

   

    # Set context to hub subscription

    Set-AzContext -SubscriptionId $HubSubscriptionId

   

    $privateDnsZones = @(

        “privatelink.blob.core.windows.net”,

        “privatelink.file.core.windows.net”,

        “privatelink.azure-automation.net”,

        “privatelink.vaultcore.azure.net”,

        “privatelink.oms.opinsights.azure.com”,

        “privatelink.ods.opinsights.azure.com”,

        “privatelink.agentsvc.azure-automation.net”

    )

   

    foreach ($zoneName in $privateDnsZones) {

        # Create private DNS zone if not exists

        $zone = Get-AzPrivateDnsZone -Name $zoneName -ErrorAction SilentlyContinue

        if (!$zone) {

            $zone = New-AzPrivateDnsZone -Name $zoneName -ResourceGroupName “hub-networking”

        }

       

        # Link customer VNet to private DNS zone

        $vnetLinkName = “link-$($CustomerSubscriptionId.Replace(‘-‘,”))”

        New-AzPrivateDnsVirtualNetworkLink -ZoneName $zoneName -ResourceGroupName “hub-networking” `

            -Name $vnetLinkName -VirtualNetworkId $CustomerVNetId

    }

}

  1. Network Security and Access Control
  2. Network Security Groups for Private Endpoints

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/networkSecurityGroups”,

            “apiVersion”: “2023-05-01”,

            “name”: “private-endpoint-nsg”,

            “location”: “eastus”,

            “properties”: {

                “securityRules”: [

                    {

                        “name”: “Allow-Hub-To-PrivateEndpoints”,

                        “properties”: {

                            “protocol”: “*”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “*”,

                            “sourceAddressPrefix”: “10.1.0.0/16”,  # Hub VNet

                            “destinationAddressPrefix”: “10.2.0.0/16”,  # Private Endpoint Subnet

                            “access”: “Allow”,

                            “priority”: 100,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Deny-Internet-To-PrivateEndpoints”,

                        “properties”: {

                            “protocol”: “*”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “*”,

                            “sourceAddressPrefix”: “Internet”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Deny”,

                            “priority”: 200,

                            “direction”: “Inbound”

                        }

                    }

                ]

            }

        }

    ]

}

  1. Azure Firewall for Cross-Tenant Traffic

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/azureFirewalls”,

            “apiVersion”: “2023-05-01”,

            “name”: “cross-tenant-fw”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “AZFW_Hub”, “tier”: “Standard” },

                “threatIntelMode”: “Alert”,

                “applicationRuleCollections”: [

                    {

                        “name”: “Allow-CrossTenant-PaaS”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-PrivateLink-Services”,

                                    “protocols”: [{ “protocolType”: “Https”, “port”: 443 }],

                                    “targetFqdns”: [

                                        “*.privatelink.blob.core.windows.net”,

                                        “*.privatelink.azure-automation.net”,

                                        “*.privatelink.vaultcore.azure.net”

                                    ],

                                    “sourceAddresses”: [“10.1.0.0/16”]

                                }

                            ]

                        }

                    }

                ]

            }

        }

    ]

}

  1. Cross-Tenant Connectivity Patterns

Pattern 1: Hub-Spoke with Private Link

json

{

    “resources”: [

        // Hub Virtual Network

        {

            “type”: “Microsoft.Network/virtualNetworks”,

            “apiVersion”: “2023-05-01”,

            “name”: “hub-vnet”,

            “location”: “eastus”,

            “properties”: {

                “addressSpace”: { “addressPrefixes”: [“10.1.0.0/16”] },

                “subnets”: [

                    {

                        “name”: “AzureBastionSubnet”,

                        “properties”: { “addressPrefix”: “10.1.1.0/27” }

                    },

                    {

                        “name”: “private-endpoints”,

                        “properties”: {

                            “addressPrefix”: “10.1.2.0/24”,

                            “privateEndpointNetworkPolicies”: “Disabled”

                        }

                    }

                ]

            }

        },

       

        // VNet Peering to Customer VNets (via Lighthouse)

        {

            “type”: “Microsoft.Network/virtualNetworks/virtualNetworkPeerings”,

            “apiVersion”: “2023-05-01”,

            “name”: “hub-to-customer1-peering”,

            “dependsOn”: [“[resourceId(‘Microsoft.Network/virtualNetworks’, ‘hub-vnet’)]”],

            “properties”: {

                “allowVirtualNetworkAccess”: true,

                “allowForwardedTraffic”: true,

                “allowGatewayTransit”: false,

                “useRemoteGateways”: false,

                “remoteVirtualNetwork”: {

                    “id”: “/subscriptions/customer-sub/resourceGroups/customer-rg/providers/Microsoft.Network/virtualNetworks/customer-vnet”

                }

            }

        }

    ]

}

Pattern 2: Azure Virtual WAN with Private Link

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualWans”,

            “apiVersion”: “2023-05-01”,

            “name”: “cross-tenant-vwan”,

            “location”: “eastus”,

            “properties”: {

                “allowBranchToBranchTraffic”: true,

                “allowVnetToVnetTraffic”: true,

                “type”: “Standard”

            }

        },

        {

            “type”: “Microsoft.Network/virtualHubs”,

            “apiVersion”: “2023-05-01”,

            “name”: “central-hub”,

            “location”: “eastus”,

            “properties”: {

                “virtualWan”: {

                    “id”: “[resourceId(‘Microsoft.Network/virtualWans’, ‘cross-tenant-vwan’)]”

                },

                “addressPrefix”: “10.100.0.0/16”

            }

        }

    ]

}

  1. Monitoring and Troubleshooting
  2. Azure Monitor Workbooks for Private Link

kql

// Private Link connection monitoring

AzureDiagnostics

| where ResourceType == “PRIVATEENDPOINTS”

| where Category == “PrivateEndpointConnection”

| project TimeGenerated, Resource, OperationName, ResultType, CallerIpAddress

| summarize ConnectionCount = count() by bin(TimeGenerated, 1h), OperationName

  1. Network Watcher for Connectivity Testing

powershell

function Test-CrossTenantPrivateConnectivity {

    param(

        [string]$SourceVmId,

        [string]$PrivateEndpointFqdn

    )

   

    $connectionTest = Test-AzNetworkWatcherConnectivity `

        -NetworkWatcherName “NetworkWatcher_eastus” `

        -ResourceId $SourceVmId `

        -DestinationAddress $PrivateEndpointFqdn `

        -DestinationPort 443

   

    if ($connectionTest.ConnectivityStatus -eq “Reachable”) {

        Write-Output “Private Link connectivity successful to $PrivateEndpointFqdn”

    } else {

        Write-Error “Private Link connectivity failed to $PrivateEndpointFqdn”

        # Log detailed troubleshooting info

        $connectionTest | ConvertTo-Json -Depth 5 | Out-File “connectivity-debug.json”

    }

}

  1. Security and Compliance
  2. Private Link with Azure Policy Enforcement

json

{

    “mode”: “Indexed”,

    “policyRule”: {

        “if”: {

            “allOf”: [

                {

                    “field”: “type”,

                    “equals”: “Microsoft.Storage/storageAccounts”

                },

                {

                    “field”: “Microsoft.Storage/storageAccounts/publicNetworkAccess”,

                    “notEquals”: “Disabled”

                }

            ]

        },

        “then”: {

            “effect”: “deny”,

            “details”: {

                “message”: “Storage accounts must have public network access disabled and use Private Link for cross-tenant access”

            }

        }

    }

}

  1. Azure Blueprints for Private Link Architecture

json

{

    “properties”: {

        “description”: “Cross-Tenant Private Link Blueprint”,

        “targetScope”: “subscription”,

        “parameters”: {

            “hubVNetId”: { “type”: “string” },

            “privateEndpointSubnetId”: { “type”: “string” }

        },

        “resourceGroups”: {

            “private-link-rg”: {

                “description”: “Resource group for cross-tenant private endpoints”

            }

        },

        “artifacts”: [

            {

                “kind”: “policyAssignment”,

                “properties”: {

                    “displayName”: “Enforce Private Link for PaaS”,

                    “policyDefinitionId”: “/providers/Microsoft.Authorization/policyDefinitions/…”

                }

            }

        ]

    }

}

  1. Cost Optimization and Management
  2. Private Link Cost Analysis

kql

// Monitor Private Link costs across tenants

UsageDetails

| where MeterCategory =~ “Networking” and MeterSubCategory =~ “Private Endpoints”

| extend Tenant = tags[‘Tenant’]

| summarize

    TotalCost = sum(Quantity * UnitPrice),

    PrivateEndpointCount = dcount(ResourceId)

    by Tenant, bin(UsageDateTime, 1d)

| order by TotalCost desc

  1. Automated Private Endpoint Cleanup

powershell

function Remove-OrphanedPrivateEndpoints {

    $privateEndpoints = Get-AzPrivateEndpoint

   

    foreach ($pe in $privateEndpoints) {

        $connection = $pe.PrivateLinkServiceConnections[0]

        if ($connection.PrivateLinkServiceId) {

            $resource = Get-AzResource -ResourceId $connection.PrivateLinkServiceId -ErrorAction SilentlyContinue

            if (!$resource) {

                Write-Warning “Removing orphaned private endpoint: $($pe.Name)”

                Remove-AzPrivateEndpoint -ResourceId $pe.Id -Force

            }

        }

    }

}

Implementation Checklist

  • Design hub VNet architecture for private endpoints
  • Identify required PaaS services for private connectivity
  • Configure private DNS zones for name resolution
  • Implement network security controls (NSGs, Firewall)
  • Deploy private endpoints for each service
  • Test connectivity from all customer environments
  • Configure monitoring and alerting
  • Implement cost tracking for private endpoints
  • Document access patterns and troubleshooting procedures
  • Establish security policies for private link enforcement

Summary

Using Azure Private Link for cross-tenant management provides:

✅ Enhanced security through private connectivity
✅ Network isolation from public internet
✅ Compliance with data protection requirements
✅ Reliable service connectivity without public endpoints
✅ Centralized management of private connections
✅ Improved performance through optimized routing

The key success factors are proper DNS configuration, network security design, and automated deployment processes that scale across multiple customer tenants while maintaining security and compliance standards.

what are options for cross tenant management using Azure VNet peering?

Excellent question! Azure VNet peering provides direct network connectivity between virtual networks across tenants, enabling secure, low-latency communication for management operations. Here are comprehensive options and implementation patterns:

  1. Core Architecture Patterns

Pattern A: Hub-and-Spoke with Cross-Tenant Peering

Central hub VNet in managing tenant peered to customer spoke VNets

Pattern B: Full Mesh Peering

Direct peering between all relevant VNets across tenants (complex but high-performance)

Pattern C: Regional Hub Pattern

Multiple hub VNets in different regions for global customers

  1. VNet Peering Implementation with Azure Lighthouse
  2. ARM Template for Cross-Tenant VNet Peering

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “hubVNetId”: { “type”: “string” },

        “customerVNetId”: { “type”: “string” },

        “customerSubscriptionId”: { “type”: “string” },

        “peeringName”: { “type”: “string” }

    },

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworks/virtualNetworkPeerings”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(parameters(‘peeringName’), ‘-to-customer’)]”,

            “properties”: {

                “allowVirtualNetworkAccess”: true,

                “allowForwardedTraffic”: true,

                “allowGatewayTransit”: false,

                “useRemoteGateways”: false,

                “remoteVirtualNetwork”: {

                    “id”: “[parameters(‘customerVNetId’)]”

                }

            }

        },

        {

            “type”: “Microsoft.Resources/deployments”,

            “apiVersion”: “2020-10-01”,

            “name”: “[concat(‘customer-peering-‘, parameters(‘peeringName’))]”,

            “subscriptionId”: “[parameters(‘customerSubscriptionId’)]”,

            “properties”: {

                “mode”: “Incremental”,

                “template”: {

                    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

                    “contentVersion”: “1.0.0.0”,

                    “resources”: [

                        {

                            “type”: “Microsoft.Network/virtualNetworks/virtualNetworkPeerings”,

                            “apiVersion”: “2023-05-01”,

                            “name”: “[concat(parameters(‘peeringName’), ‘-to-hub’)]”,

                            “properties”: {

                                “allowVirtualNetworkAccess”: true,

                                “allowForwardedTraffic”: true,

                                “allowGatewayTransit”: false,

                                “useRemoteGateways”: false,

                                “remoteVirtualNetwork”: {

                                    “id”: “[parameters(‘hubVNetId’)]”

                                }

                            }

                        }

                    ]

                }

            }

        }

    ]

}

  1. PowerShell Automation for VNet Peering

powershell

function New-CrossTenantVNetPeering {

    param(

        [string]$HubSubscriptionId,

        [string]$CustomerSubscriptionId,

        [string]$HubVNetName,

        [string]$CustomerVNetName,

        [string]$HubResourceGroup = “hub-networking”,

        [string]$CustomerResourceGroup = “customer-networking”

    )

   

    # Set context to hub subscription

    Set-AzContext -SubscriptionId $HubSubscriptionId

   

    # Get hub VNet

    $hubVNet = Get-AzVirtualNetwork -Name $HubVNetName -ResourceGroupName $HubResourceGroup

   

    # Set context to customer subscription

    Set-AzContext -SubscriptionId $CustomerSubscriptionId

   

    # Get customer VNet

    $customerVNet = Get-AzVirtualNetwork -Name $CustomerVNetName -ResourceGroupName $CustomerResourceGroup

   

    # Create peering from hub to customer

    Set-AzContext -SubscriptionId $HubSubscriptionId

    Add-AzVirtualNetworkPeering -Name “peer-to-$CustomerVNetName” `

        -VirtualNetwork $hubVNet `

        -RemoteVirtualNetworkId $customerVNet.Id `

        -AllowForwardedTraffic `

        -AllowVirtualNetworkAccess

   

    # Create peering from customer to hub

    Set-AzContext -SubscriptionId $CustomerSubscriptionId

    Add-AzVirtualNetworkPeering -Name “peer-to-$HubVNetName” `

        -VirtualNetwork $customerVNet `

        -RemoteVirtualNetworkId $hubVNet.Id `

        -AllowForwardedTraffic `

        -AllowVirtualNetworkAccess

   

    Write-Output “VNet peering established between $HubVNetName and $CustomerVNetName”

}

  1. Network Architecture and IP Planning
  2. IP Address Space Design

json

{

    “networkDesign”: {

        “hubVNet”: {

            “addressSpace”: [“10.1.0.0/16”],

            “subnets”: {

                “management”: “10.1.1.0/24”,

                “jumpboxes”: “10.1.2.0/24”,

                “gateway”: “10.1.3.0/27”,

                “azureBastion”: “10.1.4.0/27”

            }

        },

        “customerVNets”: {

            “contoso”: {

                “addressSpace”: [“10.10.0.0/16”],

                “region”: “eastus”

            },

            “fabrikam”: {

                “addressSpace”: [“10.20.0.0/16”],

                “region”: “westeurope”

            },

            “adventureworks”: {

                “addressSpace”: [“10.30.0.0/16”],

                “region”: “southeastasia”

            }

        }

    }

}

  1. Subnet Planning for Management Services

json

{

    “subnetDesign”: {

        “managementSubnet”: {

            “name”: “snet-management”,

            “addressPrefix”: “10.1.1.0/24”,

            “services”: [

                “Azure Bastion”,

                “Jumpbox VMs”,

                “Azure Automation Hybrid Workers”

            ],

            “nsg”: “nsg-management-restricted”

        },

        “monitoringSubnet”: {

            “name”: “snet-monitoring”,

            “addressPrefix”: “10.1.5.0/24”,

            “services”: [

                “Monitoring VMs”,

                “Log Collectors”,

                “Network Watcher”

            ],

            “nsg”: “nsg-monitoring”

        }

    }

}

  1. Specific Cross-Tenant Management Scenarios

Scenario 1: Secure Jumpbox Access

Deploy bastion hosts in hub VNet for customer VM management

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/bastionHosts”,

            “apiVersion”: “2023-05-01”,

            “name”: “cross-tenant-bastion”,

            “location”: “eastus”,

            “properties”: {

                “ipConfigurations”: [

                    {

                        “name”: “bastion-ipconfig”,

                        “properties”: {

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘AzureBastionSubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, ‘bastion-pip’)]”

                            }

                        }

                    }

                ]

            }

        },

        {

            “type”: “Microsoft.Compute/virtualMachines”,

            “apiVersion”: “2023-03-01”,

            “name”: “jumpbox-management”,

            “location”: “eastus”,

            “properties”: {

                “hardwareProfile”: { “vmSize”: “Standard_B2s” },

                “networkProfile”: {

                    “networkInterfaces”: [

                        {

                            “id”: “[resourceId(‘Microsoft.Network/networkInterfaces’, ‘jumpbox-nic’)]”

                        }

                    ]

                },

                “storageProfile”: { /* … */ },

                “osProfile”: { /* … */ }

            },

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/networkInterfaces’, ‘jumpbox-nic’)]”

            ]

        }

    ]

}

Scenario 2: Hybrid Worker Management

Azure Automation hybrid workers in hub accessing customer resources

json

{

    “resources”: [

        {

            “type”: “Microsoft.Automation/automationAccounts”,

            “apiVersion”: “2022-08-08”,

            “name”: “cross-tenant-automation”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “Basic” }

            }

        },

        {

            “type”: “Microsoft.Automation/hybridRunbookWorkerGroups”,

            “apiVersion”: “2022-08-08”,

            “name”: “customer-management-workers”,

            “properties”: {

                “credential”: { /* Hybrid worker credentials */ }

            }

        }

    ]

}

Scenario 3: Cross-Tenant Backup and Recovery

Central backup infrastructure accessing customer VMs

json

{

    “resources”: [

        {

            “type”: “Microsoft.RecoveryServices/vaults”,

            “apiVersion”: “2023-02-01”,

            “name”: “central-backup-vault”,

            “location”: “eastus”,

            “sku”: { “name”: “Standard” },

            “properties”: { /* … */ }

        },

        {

            “type”: “Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems”,

            “apiVersion”: “2023-02-01”,

            “name”: “cross-tenant-backup-policy”,

            “properties”: {

                “protectedItemType”: “Microsoft.Compute/virtualMachines”,

                “policyId”: “[resourceId(‘Microsoft.RecoveryServices/vaults/backupPolicies’, ‘central-backup-vault’, ‘default-policy’)]”,

                “sourceResourceId”: “/subscriptions/customer-sub/resourceGroups/customer-rg/providers/Microsoft.Compute/virtualMachines/customer-vm”

            }

        }

    ]

}

  1. Network Security Configuration
  2. Network Security Groups for Cross-Tenant Traffic

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/networkSecurityGroups”,

            “apiVersion”: “2023-05-01”,

            “name”: “nsg-cross-tenant-management”,

            “location”: “eastus”,

            “properties”: {

                “securityRules”: [

                    {

                        “name”: “Allow-RDP-From-Jumpboxes”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “3389”,

                            “sourceAddressPrefix”: “10.1.2.0/24”,  # Jumpbox subnet

                            “destinationAddressPrefix”: “VirtualNetwork”,

                            “access”: “Allow”,

                            “priority”: 100,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Allow-WinRM-From-Management”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “5986”,

                            “sourceAddressPrefix”: “10.1.1.0/24”,  # Management subnet

                            “destinationAddressPrefix”: “VirtualNetwork”,

                            “access”: “Allow”,

                            “priority”: 110,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Deny-All-Other-Inbound”,

                        “properties”: {

                            “protocol”: “*”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “*”,

                            “sourceAddressPrefix”: “*”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Deny”,

                            “priority”: 4096,

                            “direction”: “Inbound”

                        }

                    }

                ]

            }

        }

    ]

}

  1. Azure Firewall for Cross-Tenant Traffic Control

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/azureFirewalls”,

            “apiVersion”: “2023-05-01”,

            “name”: “fw-cross-tenant”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “AZFW_Hub”, “tier”: “Standard” },

                “threatIntelMode”: “Alert”,

                “applicationRuleCollections”: [

                    {

                        “name”: “Allow-CrossTenant-Management”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-Azure-Management”,

                                    “protocols”: [{ “protocolType”: “Https”, “port”: 443 }],

                                    “targetFqdns”: [

                                        “management.azure.com”,

                                        “*.blob.core.windows.net”,

                                        “*.azure-automation.net”

                                    ],

                                    “sourceAddresses”: [“10.1.0.0/16”]

                                }

                            ]

                        }

                    }

                ],

                “networkRuleCollections”: [

                    {

                        “name”: “Allow-CrossTenant-RDP”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-RDP-To-Customers”,

                                    “protocols”: [“TCP”],

                                    “sourceAddresses”: [“10.1.2.0/24”],  # Jumpboxes

                                    “destinationAddresses”: [“10.0.0.0/8”],  # All customer ranges

                                    “destinationPorts”: [“3389”]

                                }

                            ]

                        }

                    }

                ]

            }

        }

    ]

}

  1. DNS Configuration for Cross-Tenant
  2. Custom DNS Servers for Name Resolution

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworks”,

            “apiVersion”: “2023-05-01”,

            “name”: “hub-vnet”,

            “location”: “eastus”,

            “properties”: {

                “addressSpace”: { “addressPrefixes”: [“10.1.0.0/16”] },

                “dhcpOptions”: {

                    “dnsServers”: [“10.1.1.4”, “10.1.1.5”]  # Custom DNS servers

                },

                “subnets”: [ /* … */ ]

            }

        },

        {

            “type”: “Microsoft.Network/privateDnsZones”,

            “apiVersion”: “2020-06-01”,

            “name”: “internal.management.com”,

            “location”: “global”,

            “resources”: [

                {

                    “type”: “virtualNetworkLinks”,

                    “apiVersion”: “2020-06-01”,

                    “name”: “link-to-hub”,

                    “properties”: {

                        “virtualNetwork”: {

                            “id”: “[resourceId(‘Microsoft.Network/virtualNetworks’, ‘hub-vnet’)]”

                        },

                        “registrationEnabled”: true

                    }

                }

            ]

        }

    ]

}

  1. Conditional DNS Forwarding

powershell

function Configure-CrossTenantDNS {

    param(

        [string]$HubVNetName,

        [string]$CustomerVNetName,

        [string]$CustomerDomain

    )

   

    # Create DNS server in hub

    $dnsServer = New-AzNetworkInterface -Name “dns-server” -ResourceGroupName “hub-networking” `

        -Location “eastus” -SubnetId “/subscriptions/hub-sub/resourceGroups/hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet/subnets/snet-management”

   

    # Configure conditional forwarders for customer domains

    Add-DnsServerConditionalForwarderZone -Name $CustomerDomain `

        -MasterServers (Get-AzNetworkInterface -Name $CustomerVNetName).IpConfigurations.PrivateIpAddress

}

  1. Monitoring and Troubleshooting
  2. Network Watcher for Connectivity Testing

powershell

function Test-CrossTenantConnectivity {

    param(

        [string]$SourceVmId,

        [string]$DestinationIp,

        [int]$Port = 3389

    )

   

    $connectionTest = Test-AzNetworkWatcherConnectivity `

        -NetworkWatcherName “NetworkWatcher_eastus” `

        -ResourceId $SourceVmId `

        -DestinationAddress $DestinationIp `

        -DestinationPort $Port

   

    return @{

        Status = $connectionTest.ConnectivityStatus

        Latency = $connectionTest.AvgLatencyInMs

        Hops = $connectionTest.Hops

    }

}

 

# Test connectivity to customer VMs

$customerVMs = @(

    @{ Name = “contoso-web-01”; IP = “10.10.1.10” },

    @{ Name = “contoso-sql-01”; IP = “10.10.2.10” }

)

 

foreach ($vm in $customerVMs) {

    $result = Test-CrossTenantConnectivity -SourceVmId $jumpboxId -DestinationIp $vm.IP

    Write-Output “Connectivity to $($vm.Name): $($result.Status), Latency: $($result.Latency)ms”

}

  1. Azure Monitor for Network Performance

kql

// Monitor cross-tenant network performance

AzureMetrics

| where ResourceProvider == “MICROSOFT.NETWORK”

| where MetricName == “VMAvailability”

| extend VNet = tostring(parse_json(tostring(parse_json(ResourceId).VNet)))

| where VNet contains “customer”

| summarize AvgAvailability = avg(Average) by VNet, bin(TimeGenerated, 1h)

  1. Automation and Governance
  2. Azure Policy for Network Compliance

json

{

    “mode”: “Indexed”,

    “policyRule”: {

        “if”: {

            “allOf”: [

                {

                    “field”: “type”,

                    “equals”: “Microsoft.Network/virtualNetworks”

                },

                {

                    “field”: “Microsoft.Network/virtualNetworks/addressSpace.addressPrefixes”,

                    “notContains”: “10.”

                }

            ]

        },

        “then”: {

            “effect”: “deny”,

            “details”: {

                “message”: “Virtual networks must use RFC 1918 address space for cross-tenant peering compatibility”

            }

        }

    }

}

  1. Azure Blueprints for Network Architecture

json

{

    “properties”: {

        “description”: “Cross-Tenant Network Architecture Blueprint”,

        “targetScope”: “subscription”,

        “parameters”: {

            “hubAddressSpace”: { “type”: “string” },

            “customerAddressSpace”: { “type”: “string” }

        },

        “resourceGroups”: {

            “network-rg”: {

                “description”: “Resource group for cross-tenant networking”

            }

        },

        “artifacts”: [

            {

                “kind”: “template”,

                “properties”: {

                    “template”: { /* Hub VNet template */ },

                    “parameters”: {

                        “addressSpace”: { “value”: “[parameters(‘hubAddressSpace’)]” }

                    }

                }

            }

        ]

    }

}

  1. Cost Optimization and Management
  2. VNet Peering Cost Monitoring

kql

// Monitor cross-tenant data transfer costs

UsageDetails

| where MeterCategory =~ “Networking” and MeterSubCategory =~ “VNet Peering”

| extend Tenant = tags[‘Tenant’]

| summarize

    TotalCost = sum(Quantity * UnitPrice),

    DataTransferGB = sum(Quantity)

    by Tenant, bin(UsageDateTime, 1d)

| order by TotalCost desc

  1. Automated Peering Cleanup

powershell

function Remove-OrphanedVNetPeerings {

    $vnets = Get-AzVirtualNetwork

   

    foreach ($vnet in $vnets) {

        $peerings = Get-AzVirtualNetworkPeering -VirtualNetworkName $vnet.Name -ResourceGroupName $vnet.ResourceGroupName

       

        foreach ($peering in $peerings) {

            $remoteVNet = Get-AzResource -ResourceId $peering.RemoteVirtualNetwork.Id -ErrorAction SilentlyContinue

            if (!$remoteVNet) {

                Write-Warning “Removing orphaned peering: $($peering.Name) from $($vnet.Name)”

                Remove-AzVirtualNetworkPeering -Name $peering.Name -VirtualNetworkName $vnet.Name -ResourceGroupName $vnet.ResourceGroupName -Force

            }

        }

    }

}

Implementation Checklist

  • Design IP address schema to avoid overlaps
  • Plan hub VNet architecture with management subnets
  • Configure network security groups for cross-tenant traffic
  • Set up DNS resolution across peered networks
  • Deploy Azure Firewall for centralized control
  • Implement monitoring and connectivity testing
  • Establish naming conventions for network resources
  • Configure backup and disaster recovery paths
  • Document network topology and access patterns
  • Test failover and recovery procedures

Summary

Using Azure VNet peering for cross-tenant management provides:

✅ Low-latency, high-bandwidth connectivity between tenants
✅ Enhanced security through private network routing
✅ Centralized management of network resources
✅ Cost-effective data transfer compared to VPN/Gateway
✅ Scalable architecture for multiple customer environments
✅ Integration with other Azure services (Firewall, Bastion, etc.)

The key success factors are proper IP planning, robust security configuration, automated deployment processes, and comprehensive monitoring to ensure reliable cross-tenant connectivity for management operations.

This response is AI-generated, for reference only.

what are options for cross tenant management using Azure VPN Gateway

Excellent question! Azure VPN Gateway provides secure, encrypted cross-tenant connectivity over the public internet, offering flexible options for management scenarios where direct network peering isn’t feasible. Here are comprehensive options and implementation patterns:

  1. Core Architecture Patterns

Pattern A: Site-to-Site VPN with Cross-Tenant Connectivity

VPN Gateway in managing tenant connecting to customer on-premises or Azure networks

Pattern B: Point-to-Site for Remote Management

Individual administrator connections to customer networks

Pattern C: VNet-to-VNet VPN as Peering Alternative

When VNet peering isn’t possible due to overlapping IP spaces

  1. VPN Gateway Implementation with Azure Lighthouse
  2. ARM Template for Cross-Tenant VPN Gateway

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “gatewayName”: { “type”: “string” },

        “gatewayType”: { “type”: “string” },

        “customerGatewayPublicIp”: { “type”: “string” },

        “customerAddressSpace”: { “type”: “string” },

        “sharedKey”: { “type”: “securestring” }

    },

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworkGateways”,

            “apiVersion”: “2023-05-01”,

            “name”: “[parameters(‘gatewayName’)]”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “ipConfigurations”: [

                    {

                        “name”: “vnetGatewayConfig”,

                        “properties”: {

                            “privateIPAllocationMethod”: “Dynamic”,

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘GatewaySubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, concat(parameters(‘gatewayName’), ‘-pip’))]”

                            }

                        }

                    }

                ],

                “gatewayType”: “[parameters(‘gatewayType’)]”,

                “vpnType”: “RouteBased”,

                “enableBgp”: false,

                “activeActive”: false,

                “sku”: {

                    “name”: “VpnGw2”,

                    “tier”: “VpnGw2”

                }

            }

        },

        {

            “type”: “Microsoft.Network/localNetworkGateways”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(parameters(‘gatewayName’), ‘-local’)]”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “gatewayIpAddress”: “[parameters(‘customerGatewayPublicIp’)]”,

                “localNetworkAddressSpace”: {

                    “addressPrefixes”: [“[parameters(‘customerAddressSpace’)]”]

                }

            }

        },

        {

            “type”: “Microsoft.Network/connections”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(parameters(‘gatewayName’), ‘-connection’)]”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “virtualNetworkGateway1”: {

                    “id”: “[resourceId(‘Microsoft.Network/virtualNetworkGateways’, parameters(‘gatewayName’))]”

                },

                “localNetworkGateway2”: {

                    “id”: “[resourceId(‘Microsoft.Network/localNetworkGateways’, concat(parameters(‘gatewayName’), ‘-local’))]”

                },

                “connectionType”: “IPsec”,

                “connectionProtocol”: “IKEv2”,

                “routingWeight”: 0,

                “sharedKey”: “[parameters(‘sharedKey’)]”,

                “enableBgp”: false

            },

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/virtualNetworkGateways’, parameters(‘gatewayName’))]”,

                “[resourceId(‘Microsoft.Network/localNetworkGateways’, concat(parameters(‘gatewayName’), ‘-local’))]”

            ]

        }

    ]

}

  1. PowerShell Automation for VPN Gateway Deployment

powershell

function New-CrossTenantVPNConnection {

    param(

        [string]$HubSubscriptionId,

        [string]$CustomerName,

        [string]$CustomerGatewayPublicIp,

        [string]$CustomerAddressSpace,

        [string]$SharedKey,

        [string]$HubVNetName = “hub-vnet”,

        [string]$HubResourceGroup = “hub-networking”

    )

   

    # Set context to hub subscription

    Set-AzContext -SubscriptionId $HubSubscriptionId

   

    # Create public IP for VPN gateway

    $vpnPublicIp = New-AzPublicIpAddress -Name “vpn-gw-pip-$CustomerName” `

        -ResourceGroupName $HubResourceGroup -Location “eastus” `

        -AllocationMethod Dynamic -Sku Basic

   

    # Get gateway subnet

    $vnet = Get-AzVirtualNetwork -Name $HubVNetName -ResourceGroupName $HubResourceGroup

    $gatewaySubnet = $vnet.Subnets | Where-Object { $_.Name -eq “GatewaySubnet” }

   

    # Create VPN gateway

    $vpnGateway = New-AzVirtualNetworkGateway -Name “vpn-gw-$CustomerName” `

        -ResourceGroupName $HubResourceGroup -Location “eastus” `

        -IpConfigurations @(

            @{

                Name = “vnetGatewayConfig”

                PrivateIpAddress = $null

                PublicIpAddress = $vpnPublicIp

                Subnet = $gatewaySubnet

            }

        ) -GatewayType “Vpn” -VpnType “RouteBased” `

        -Sku @{ Name = “VpnGw1”; Tier = “VpnGw1” }

   

    # Create local network gateway

    $localGateway = New-AzLocalNetworkGateway -Name “local-gw-$CustomerName” `

        -ResourceGroupName $HubResourceGroup -Location “eastus” `

        -GatewayIpAddress $CustomerGatewayPublicIp `

        -AddressPrefix $CustomerAddressSpace

   

    # Create connection

    $vpnConnection = New-AzVirtualNetworkGatewayConnection -Name “conn-$CustomerName” `

        -ResourceGroupName $HubResourceGroup -Location “eastus” `

        -VirtualNetworkGateway1 $vpnGateway -LocalNetworkGateway2 $localGateway `

        -ConnectionType IPsec -SharedKey $SharedKey

   

    Write-Output “VPN connection established to $CustomerName”

    return @{

        GatewayId = $vpnGateway.Id

        ConnectionId = $vpnConnection.Id

        PublicIp = $vpnPublicIp.IpAddress

    }

}

  1. Network Architecture and IP Planning
  2. VPN Gateway Subnet and IP Design

json

{

    “vpnGatewayDesign”: {

        “hubVNet”: {

            “addressSpace”: [“10.1.0.0/16”],

            “subnets”: {

                “GatewaySubnet”: “10.1.0.0/27”,

                “management”: “10.1.1.0/24”,

                “jumpboxes”: “10.1.2.0/24”

            }

        },

        “customerConfigurations”: {

            “contoso”: {

                “gatewayPublicIp”: “203.0.113.10”,

                “addressSpace”: [“192.168.1.0/24”, “10.100.0.0/16”],

                “sharedKey”: “Cont0s0$3cur3K3y2024!”,

                “bgpEnabled”: false

            },

            “fabrikam”: {

                “gatewayPublicIp”: “198.51.100.20”,

                “addressSpace”: [“172.16.0.0/16”],

                “sharedKey”: “F@br1k@m$3cur3K3y!”,

                “bgpEnabled”: true

            }

        }

    }

}

  1. Route Table Configuration for VPN Traffic

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/routeTables”,

            “apiVersion”: “2023-05-01”,

            “name”: “rt-vpn-management”,

            “location”: “eastus”,

            “properties”: {

                “routes”: [

                    {

                        “name”: “to-contoso”,

                        “properties”: {

                            “addressPrefix”: “192.168.1.0/24”,

                            “nextHopType”: “VirtualNetworkGateway”

                        }

                    },

                    {

                        “name”: “to-fabrikam”,

                        “properties”: {

                            “addressPrefix”: “172.16.0.0/16”,

                            “nextHopType”: “VirtualNetworkGateway”

                        }

                    },

                    {

                        “name”: “default-to-internet”,

                        “properties”: {

                            “addressPrefix”: “0.0.0.0/0”,

                            “nextHopType”: “Internet”

                        }

                    }

                ]

            }

        },

        {

            “type”: “Microsoft.Network/routeTables/subnets”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(‘rt-vpn-management/’, ‘snet-management’)]”,

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/routeTables’, ‘rt-vpn-management’)]”

            ],

            “properties”: {

                “addressPrefix”: “10.1.1.0/24”

            }

        }

    ]

}

  1. Specific Cross-Tenant Management Scenarios

Scenario 1: Site-to-Site for On-Premises Management

Connect to customer on-premises networks for hybrid management

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworkGateways”,

            “apiVersion”: “2023-05-01”,

            “name”: “vpn-gw-onprem-management”,

            “properties”: {

                “ipConfigurations”: [

                    {

                        “properties”: {

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘GatewaySubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, ‘vpn-gw-pip’)]”

                            }

                        }

                    }

                ],

                “gatewayType”: “Vpn”,

                “vpnType”: “RouteBased”,

                “sku”: { “name”: “VpnGw2”, “tier”: “VpnGw2” },

                “vpnClientConfiguration”: {

                    “vpnClientProtocols”: [“OpenVPN”],

                    “vpnClientAddressPool”: {

                        “addressPrefixes”: [“172.16.201.0/24”]

                    }

                }

            }

        }

    ]

}

Scenario 2: Point-to-Site for Administrator Access

Secure remote access for management staff

powershell

# Generate and deploy P2S VPN certificates

function New-P2SVPNConfiguration {

    param([string]$CustomerName)

   

    # Generate root certificate

    $rootCert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `

        -Subject “CN=CrossTenantVPN-Root” -KeyExportPolicy Exportable `

        -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation “Cert:\CurrentUser\My” `

        -KeyUsageProperty Sign -KeyUsage CertSign

   

    # Generate client certificate

    $clientCert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `

        -Subject “CN=CrossTenantVPN-Client-$CustomerName” -KeyExportPolicy Exportable `

        -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation “Cert:\CurrentUser\My” `

        -Signer $rootCert -TextExtension @(“2.5.29.37={text}1.3.6.1.5.5.7.3.2”)

   

    # Export public key for VPN gateway

    $rootCertBase64 = [Convert]::ToBase64String($rootCert.RawData, ‘InsertLineBreaks’)

   

    # Configure VPN gateway with root certificate

    $vpnClientConfig = New-AzVpnClientConfiguration -ResourceGroupName “hub-networking” `

        -Name “vpn-gw-$CustomerName” -AuthenticationMethod “EAPTLS” `

        -ClientRootCertificates $rootCertBase64

   

    return @{

        ClientCert = $clientCert

        VPNProfile = $vpnClientConfig.VPNProfileSASUrl

    }

}

Scenario 3: VNet-to-VPN as Peering Alternative

When customer VNets have overlapping IP address spaces

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/connections”,

            “apiVersion”: “2023-05-01”,

            “name”: “vpn-conn-overlapping-ips”,

            “properties”: {

                “virtualNetworkGateway1”: {

                    “id”: “[resourceId(‘Microsoft.Network/virtualNetworkGateways’, ‘hub-vpn-gw’)]”

                },

                “virtualNetworkGateway2”: {

                    “id”: “/subscriptions/customer-sub/resourceGroups/customer-rg/providers/Microsoft.Network/virtualNetworkGateways/customer-vpn-gw”

                },

                “connectionType”: “Vnet2Vnet”,

                “connectionProtocol”: “IKEv2”,

                “routingWeight”: 0,

                “sharedKey”: “[parameters(‘vnetSharedKey’)]”,

                “enableBgp”: false,

                “useLocalAzureIpAddress”: false,

                “usePolicyBasedTrafficSelectors”: false,

                “ipsecPolicies”: [

                    {

                        “saLifeTimeSeconds”: 28800,

                        “saDataSizeKilobytes”: 102400000,

                        “ipsecEncryption”: “AES256”,

                        “ipsecIntegrity”: “SHA256”,

                        “ikeEncryption”: “AES256”,

                        “ikeIntegrity”: “SHA384”,

                        “dhGroup”: “DHGroup24”,

                        “pfsGroup”: “PFS24”

                    }

                ]

            }

        }

    ]

}

  1. Network Security Configuration
  2. Network Security Groups for VPN Traffic

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/networkSecurityGroups”,

            “apiVersion”: “2023-05-01”,

            “name”: “nsg-vpn-management”,

            “location”: “eastus”,

            “properties”: {

                “securityRules”: [

                    {

                        “name”: “Allow-VPN-IKE-Inbound”,

                        “properties”: {

                            “protocol”: “UDP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “500”,

                            “sourceAddressPrefix”: “*”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Allow”,

                            “priority”: 100,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Allow-VPN-IPSEC-Inbound”,

                        “properties”: {

                            “protocol”: “UDP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “4500”,

                            “sourceAddressPrefix”: “*”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Allow”,

                            “priority”: 110,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Allow-RDP-From-Customers”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “3389”,

                            “sourceAddressPrefix”: “192.168.0.0/16”,

                            “destinationAddressPrefix”: “10.1.2.0/24”,

                            “access”: “Allow”,

                            “priority”: 120,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Deny-All-Other-Inbound”,

                        “properties”: {

                            “protocol”: “*”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “*”,

                            “sourceAddressPrefix”: “*”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Deny”,

                            “priority”: 4096,

                            “direction”: “Inbound”

                        }

                    }

                ]

            }

        }

    ]

}

  1. Azure Firewall for VPN Traffic Inspection

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/azureFirewalls”,

            “apiVersion”: “2023-05-01”,

            “name”: “fw-vpn-inspection”,

            “location”: “eastus”,

            “properties”: {

                “sku”: { “name”: “AZFW_Hub”, “tier”: “Standard” },

                “threatIntelMode”: “Alert”,

                “networkRuleCollections”: [

                    {

                        “name”: “Allow-CrossTenant-Management”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-RDP-To-Jumpboxes”,

                                    “protocols”: [“TCP”],

                                    “sourceAddresses”: [“192.168.0.0/16”, “172.16.0.0/16”],

                                    “destinationAddresses”: [“10.1.2.0/24”],

                                    “destinationPorts”: [“3389”]

                                },

                                {

                                    “name”: “Allow-WinRM-Management”,

                                    “protocols”: [“TCP”],

                                    “sourceAddresses”: [“192.168.0.0/16”, “172.16.0.0/16”],

                                    “destinationAddresses”: [“10.1.1.0/24”],

                                    “destinationPorts”: [“5985”, “5986”]

                                }

                            ]

                        }

                    }

                ],

                “applicationRuleCollections”: [

                    {

                        “name”: “Allow-Management-Tools”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-Azure-Management”,

                                    “protocols”: [{ “protocolType”: “Https”, “port”: 443 }],

                                    “sourceAddresses”: [“10.1.0.0/16”],

                                    “targetFqdns”: [

                                        “management.azure.com”,

                                        “*.blob.core.windows.net”,

                                        “*.azure-automation.net”

                                    ]

                                }

                            ]

                        }

                    }

                ]

            }

        }

    ]

}

  1. Monitoring and Troubleshooting
  2. VPN Gateway Diagnostics and Monitoring

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworkGateways”,

            “apiVersion”: “2023-05-01”,

            “name”: “vpn-gw-monitored”,

            “properties”: {

                “ipConfigurations”: [ /* … */ ],

                “gatewayType”: “Vpn”,

                “vpnType”: “RouteBased”,

                “sku”: { “name”: “VpnGw2”, “tier”: “VpnGw2” },

                “diagnosticLogs”: {

                    “enabled”: true,

                    “storageAccountId”: “[resourceId(‘Microsoft.Storage/storageAccounts’, ‘vpnlogs’)]”,

                    “logs”: [

                        {

                            “category”: “GatewayDiagnosticLog”,

                            “enabled”: true,

                            “retentionPolicy”: {

                                “days”: 90,

                                “enabled”: true

                            }

                        },

                        {

                            “category”: “TunnelDiagnosticLog”,

                            “enabled”: true,

                            “retentionPolicy”: {

                                “days”: 90,

                                “enabled”: true

                            }

                        },

                        {

                            “category”: “RouteDiagnosticLog”,

                            “enabled”: true,

                            “retentionPolicy”: {

                                “days”: 90,

                                “enabled”: true

                            }

                        }

                    ]

                }

            }

        }

    ]

}

  1. Azure Monitor for VPN Performance

kql

// Monitor VPN tunnel status and performance

AzureMetrics

| where ResourceProvider == “MICROSOFT.NETWORK”

| where ResourceType == “VIRTUALNETWORKGATEWAYS”

| where MetricName in (“TunnelIngressBytes”, “TunnelEgressBytes”, “TunnelIngressPacketDropCount”, “TunnelEgressPacketDropCount”)

| extend GatewayName = tostring(split(ResourceId, ‘/’)[8])

| summarize

    AvgIngressBytes = avg(Average),

    AvgEgressBytes = avg(Average),

    MaxIngressBytes = max(Maximum),

    MaxEgressBytes = max(Maximum)

    by GatewayName, MetricName, bin(TimeGenerated, 5m)

  1. Connection Testing and Alerting

powershell

function Test-VPNConnectionHealth {

    param([string]$GatewayName, [string]$ResourceGroup)

   

    $connection = Get-AzVirtualNetworkGatewayConnection -Name $GatewayName -ResourceGroupName $ResourceGroup

    $tunnelStatus = Get-AzVirtualNetworkGatewayConnectionSharedKey -Name $GatewayName -ResourceGroupName $ResourceGroup

   

    $healthStatus = @{

        ConnectionName = $connection.Name

        ConnectionStatus = $connection.ConnectionStatus

        EgressBytes = $connection.EgressBytesTransferred

        IngressBytes = $connection.IngressBytesTransferred

        LastConnectionEstablished = $connection.LastConnectionEstablished

    }

   

    # Alert if connection is down for more than 5 minutes

    if ($connection.ConnectionStatus -ne “Connected” -and

        (Get-Date) – $connection.LastConnectionEstablished -gt (New-TimeSpan -Minutes 5)) {

       

        Send-Alert -Message “VPN connection $($connection.Name) is down” -Severity “High”

    }

   

    return $healthStatus

}

  1. High Availability and Disaster Recovery
  2. Active-Active VPN Gateway Configuration

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworkGateways”,

            “apiVersion”: “2023-05-01”,

            “name”: “vpn-gw-ha”,

            “properties”: {

                “ipConfigurations”: [

                    {

                        “name”: “gwIpConfig1”,

                        “properties”: {

                            “privateIPAllocationMethod”: “Dynamic”,

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘GatewaySubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, ‘vpn-gw-pip1’)]”

                            }

                        }

                    },

                    {

                        “name”: “gwIpConfig2”,

                        “properties”: {

                            “privateIPAllocationMethod”: “Dynamic”,

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘GatewaySubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, ‘vpn-gw-pip2’)]”

                            }

                        }

                    }

                ],

                “gatewayType”: “Vpn”,

                “vpnType”: “RouteBased”,

                “enableBgp”: true,

                “activeActive”: true,

                “sku”: { “name”: “VpnGw3”, “tier”: “VpnGw3” },

                “bgpSettings”: {

                    “asn”: 65515,

                    “bgpPeeringAddress”: “10.1.0.254”,

                    “peerWeight”: 0

                }

            }

        }

    ]

}

  1. Multi-Region VPN Gateway Deployment

powershell

function Deploy-MultiRegionVPN {

    param([string[]]$Regions = @(“eastus”, “westus”, “westeurope”))

   

    foreach ($region in $Regions) {

        $deploymentParams = @{

            HubSubscriptionId = $HubSubscriptionId

            HubResourceGroup = “hub-networking-$region”

            HubVNetName = “hub-vnet-$region”

            Region = $region

        }

       

        # Deploy regional VPN gateway

        New-CrossTenantVPNConnection @deploymentParams

       

        # Configure cross-region routing

        Set-AzVirtualNetworkGateway -Name “vpn-gw-$region” `

            -ResourceGroupName “hub-networking-$region” `

            -EnableBgpRouteTranslationForNat $true

    }

   

    Write-Output “Multi-region VPN deployment completed”

}

  1. Cost Optimization and Management
  2. VPN Gateway Cost Monitoring

kql

// Monitor VPN gateway costs across tenants

UsageDetails

| where MeterCategory =~ “Networking” and MeterSubCategory =~ “VPN Gateway”

| extend GatewayName = tostring(ResourceId)

| summarize

    TotalCost = sum(Quantity * UnitPrice),

    GatewayHours = sum(Quantity)

    by GatewayName, bin(UsageDateTime, 1d)

| order by TotalCost desc

  1. Automated VPN Gateway Scaling

powershell

function Optimize-VPNGatewayCost {

    param([string]$GatewayName, [string]$ResourceGroup)

   

    $gateway = Get-AzVirtualNetworkGateway -Name $GatewayName -ResourceGroupName $ResourceGroup

    $connectionStats = Get-AzVirtualNetworkGatewayConnection -Name “$GatewayName-conn” -ResourceGroupName $ResourceGroup

   

    # Calculate average bandwidth usage

    $avgBandwidth = ($connectionStats.EgressBytesTransferred + $connectionStats.IngressBytesTransferred) / 24h

   

    # Scale down if usage is low

    if ($avgBandwidth -lt 100MB -and $gateway.Sku.Tier -eq “VpnGw2”) {

        Write-Output “Scaling down $GatewayName from VpnGw2 to VpnGw1”

        $gateway.Sku.Tier = “VpnGw1”

        $gateway | Set-AzVirtualNetworkGateway

    }

   

    # Scale up during business hours if needed

    if ((Get-Date).Hour -ge 8 -and (Get-Date).Hour -le 18 -and

        $avgBandwidth -gt 500MB -and $gateway.Sku.Tier -eq “VpnGw1”) {

        Write-Output “Scaling up $GatewayName from VpnGw1 to VpnGw2”

        $gateway.Sku.Tier = “VpnGw2”

        $gateway | Set-AzVirtualNetworkGateway

    }

}

Implementation Checklist

  • Design IP address schema for VPN connectivity
  • Plan GatewaySubnet with adequate address space
  • Select appropriate VPN Gateway SKU based on bandwidth requirements
  • Configure cryptographic policies and shared keys
  • Set up network security groups for VPN traffic
  • Implement route tables for traffic steering
  • Configure monitoring and alerting for connection health
  • Establish certificate authority for P2S connections
  • Test failover and disaster recovery procedures
  • Document connection parameters for each customer

Summary

Using Azure VPN Gateway for cross-tenant management provides:

✅ Secure encrypted tunnels over public internet
✅ Flexible connectivity options (S2S, P2S, VNet-to-VNet)
✅ Compatibility with on-premises networks
✅ Solution for overlapping IP address spaces
✅ BGP support for dynamic routing
✅ High availability with active-active configuration

The key success factors are proper cryptographic configuration, robust monitoring, cost optimization through appropriate SKU selection, and comprehensive documentation of connection parameters for each customer environment.

This response is AI-generated, for reference only.

what are options for cross tenant management using Azure Bastion?

Excellent question! Azure Bastion provides secure, seamless RDP/SSH connectivity to VMs without exposing them to the public internet, making it ideal for cross-tenant management. Here are comprehensive options and implementation patterns:

  1. Core Architecture Patterns

Pattern A: Centralized Bastion Host

Single Azure Bastion in managing tenant accessing customer VMs via Azure Lighthouse

Pattern B: Regional Bastion Hosts

Multiple Bastion hosts in different regions for global customers

Pattern C: Customer-Dedicated Bastion

Bastion deployed per customer for isolation (higher cost)

  1. Azure Bastion Implementation with Azure Lighthouse
  2. ARM Template for Centralized Bastion

json

{

    “$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,

    “contentVersion”: “1.0.0.0”,

    “parameters”: {

        “bastionName”: { “type”: “string” },

        “bastionSubnetAddressPrefix”: { “type”: “string” }

    },

    “resources”: [

        {

            “type”: “Microsoft.Network/virtualNetworks”,

            “apiVersion”: “2023-05-01”,

            “name”: “hub-vnet”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “addressSpace”: {

                    “addressPrefixes”: [“10.1.0.0/16”]

                },

                “subnets”: [

                    {

                        “name”: “AzureBastionSubnet”,

                        “properties”: {

                            “addressPrefix”: “[parameters(‘bastionSubnetAddressPrefix’)]”

                        }

                    },

                    {

                        “name”: “management”,

                        “properties”: {

                            “addressPrefix”: “10.1.1.0/24”

                        }

                    }

                ]

            }

        },

        {

            “type”: “Microsoft.Network/publicIPAddresses”,

            “apiVersion”: “2023-05-01”,

            “name”: “[concat(parameters(‘bastionName’), ‘-pip’)]”,

            “location”: “[resourceGroup().location]”,

            “sku”: { “name”: “Standard” },

            “properties”: {

                “publicIPAllocationMethod”: “Static”

            }

        },

        {

            “type”: “Microsoft.Network/bastionHosts”,

            “apiVersion”: “2023-05-01”,

            “name”: “[parameters(‘bastionName’)]”,

            “location”: “[resourceGroup().location]”,

            “properties”: {

                “ipConfigurations”: [

                    {

                        “name”: “bastionIpConfig”,

                        “properties”: {

                            “subnet”: {

                                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, ‘hub-vnet’, ‘AzureBastionSubnet’)]”

                            },

                            “publicIPAddress”: {

                                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, concat(parameters(‘bastionName’), ‘-pip’))]”

                            }

                        }

                    }

                ],

                “enableTunneling”: true,

                “enableIpConnect”: true,

                “enableShareableLink”: true

            },

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/virtualNetworks’, ‘hub-vnet’)]”,

                “[resourceId(‘Microsoft.Network/publicIPAddresses’, concat(parameters(‘bastionName’), ‘-pip’))]”

            ]

        }

    ]

}

  1. PowerShell Automation for Bastion Deployment

powershell

function New-CrossTenantBastion {

    param(

        [string]$HubSubscriptionId,

        [string]$BastionName = “cross-tenant-bastion”,

        [string]$HubVNetName = “hub-vnet”,

        [string]$HubResourceGroup = “hub-networking”,

        [string]$BastionSubnetPrefix = “10.1.0.0/27”

    )

   

    # Set context to hub subscription

    Set-AzContext -SubscriptionId $HubSubscriptionId

   

    # Create or get hub VNet

    $vnet = Get-AzVirtualNetwork -Name $HubVNetName -ResourceGroupName $HubResourceGroup -ErrorAction SilentlyContinue

    if (!$vnet) {

        $vnet = New-AzVirtualNetwork -Name $HubVNetName -ResourceGroupName $HubResourceGroup `

            -Location “eastus” -AddressPrefix “10.1.0.0/16”

    }

   

    # Create Bastion subnet

    $bastionSubnet = Add-AzVirtualNetworkSubnetConfig -Name “AzureBastionSubnet” `

        -VirtualNetwork $vnet -AddressPrefix $BastionSubnetPrefix

    $vnet | Set-AzVirtualNetwork

   

    # Create public IP

    $publicIp = New-AzPublicIpAddress -Name “$BastionName-pip” -ResourceGroupName $HubResourceGroup `

        -Location “eastus” -Sku “Standard” -AllocationMethod “Static” -Zone 1,2,3

   

    # Deploy Azure Bastion

    $bastion = New-AzBastion -ResourceGroupName $HubResourceGroup -Name $BastionName `

        -PublicIpAddress $publicIp -VirtualNetwork $vnet -Sku “Standard” `

        -EnableTunneling $true -EnableIpConnect $true -EnableShareableLink $true

   

    Write-Output “Azure Bastion deployed successfully”

    return @{

        BastionId = $bastion.Id

        PublicIp = $publicIp.IpAddress

        ResourceGroup = $HubResourceGroup

    }

}

  1. Network Architecture and Security
  2. Bastion Subnet Requirements

json

{

    “bastionSubnetSpecs”: {

        “name”: “AzureBastionSubnet”,

        “minimumSize”: “/27”,

        “recommendedSize”: “/26”,

        “purpose”: “Dedicated for Azure Bastion only”,

        “restrictions”: [

            “No Network Security Groups (NSG) required”,

            “No Route Tables (UDR) required”,

            “No other resources can be deployed in this subnet”

        ]

    },

    “exampleConfigurations”: {

        “small”: { “subnetSize”: “/27”, “maxInstances”: 2 },

        “medium”: { “subnetSize”: “/26”, “maxInstances”: 8 },

        “large”: { “subnetSize”: “/25”, “maxInstances”: 16 }

    }

}

  1. Network Security Configuration

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/networkSecurityGroups”,

            “apiVersion”: “2023-05-01”,

            “name”: “nsg-customer-vm-access”,

            “location”: “eastus”,

            “properties”: {

                “securityRules”: [

                    {

                        “name”: “Allow-RDP-From-Bastion”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “3389”,

                            “sourceAddressPrefix”: “10.1.0.0/27”,  # Bastion subnet

                            “destinationAddressPrefix”: “VirtualNetwork”,

                            “access”: “Allow”,

                            “priority”: 100,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Allow-SSH-From-Bastion”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “22”,

                            “sourceAddressPrefix”: “10.1.0.0/27”,  # Bastion subnet

                            “destinationAddressPrefix”: “VirtualNetwork”,

                            “access”: “Allow”,

                            “priority”: 110,

                            “direction”: “Inbound”

                        }

                    },

                    {

                        “name”: “Deny-All-Other-RDP-SSH”,

                        “properties”: {

                            “protocol”: “TCP”,

                            “sourcePortRange”: “*”,

                            “destinationPortRange”: “3389,22”,

                            “sourceAddressPrefix”: “*”,

                            “destinationAddressPrefix”: “*”,

                            “access”: “Deny”,

                            “priority”: 200,

                            “direction”: “Inbound”

                        }

                    }

                ]

            }

        }

    ]

}

  1. Specific Cross-Tenant Management Scenarios

Scenario 1: Direct VM Connectivity via Lighthouse

Access customer VMs directly through centralized Bastion

powershell

function Connect-CustomerVMViaBastion {

    param(

        [string]$BastionResourceGroup,

        [string]$BastionName,

        [string]$CustomerVMResourceId,

        [string]$Protocol = “RDP”,  # RDP or SSH

        [int]$Port = 3389

    )

   

    # Get Bastion context

    $bastion = Get-AzBastion -ResourceGroupName $BastionResourceGroup -Name $BastionName

   

    # Generate connection script based on protocol

    if ($Protocol -eq “RDP”) {

        $connectionScript = @”

# RDP Connection via Azure Bastion

`$bastion = Get-AzBastion -ResourceGroupName ‘$BastionResourceGroup’ -Name ‘$BastionName’

`$vm = Get-AzResource -ResourceId ‘$CustomerVMResourceId’

Connect-AzBastionRDP -ResourceGroupName ‘$BastionResourceGroup’ -Name ‘$BastionName’ -TargetResourceId ‘$CustomerVMResourceId’ -Port $Port

“@

    } else {

        $connectionScript = @”

# SSH Connection via Azure Bastion 

`$bastion = Get-AzBastion -ResourceGroupName ‘$BastionResourceGroup’ -Name ‘$BastionName’

`$vm = Get-AzResource -ResourceId ‘$CustomerVMResourceId’

Connect-AzBastionSSH -ResourceGroupName ‘$BastionResourceGroup’ -Name ‘$BastionName’ -TargetResourceId ‘$CustomerVMResourceId’ -Port $Port

“@

    }

   

    Write-Output “Connection script generated for $Protocol to $CustomerVMResourceId”

    return $connectionScript

}

Scenario 2: Shareable Links for Temporary Access

Generate time-limited access links for customer collaboration

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/bastionHosts”,

            “apiVersion”: “2023-05-01”,

            “name”: “bastion-shareable-links”,

            “properties”: {

                “ipConfigurations”: [ /* … */ ],

                “enableShareableLink”: true

            }

        }

    ]

}

powershell

function New-BastionShareableLink {

    param(

        [string]$BastionResourceGroup,

        [string]$BastionName,

        [string]$TargetResourceId,

        [string]$Protocol = “RDP”,

        [timespan]$Duration = (New-TimeSpan -Hours 4)

    )

   

    # Generate shareable link

    $shareableLink = New-AzBastionShareableLink -ResourceGroupName $BastionResourceGroup `

        -BastionHostName $BastionName -TargetResourceId $TargetResourceId `

        -Protocol $Protocol -Duration $Duration

   

    # Log link creation for audit

    Write-ActivityLog -Message “Shareable link created for $TargetResourceId” `

        -Category “BastionAccess” -ResourceId $TargetResourceId

   

    return @{

        Link = $shareableLink.BastionShareableLink.Url

        Expires = (Get-Date).Add($Duration)

        Target = $TargetResourceId

    }

}

Scenario 3: IP Connect for Native Client Access

Use native RDP/SSH clients through Bastion

powershell

function Enable-BastionIPConnect {

    param(

        [string]$BastionResourceGroup,

        [string]$BastionName,

        [string]$ClientIPAddress

    )

   

    # Enable IP Connect feature

    $bastion = Get-AzBastion -ResourceGroupName $BastionResourceGroup -Name $BastionName

    $bastion.EnableIpConnect = $true

    $bastion | Set-AzBastion

   

    # Generate IP Connect token

    $token = New-AzBastionIpConnectToken -ResourceGroupName $BastionResourceGroup `

        -BastionHostName $BastionName -TargetResourceId $TargetResourceId

   

    Write-Output “IP Connect enabled. Token: $($token.IpConnectToken)”

    return $token

}

  1. Integration with Other Azure Services
  2. Azure Bastion + Azure Firewall

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/azureFirewalls”,

            “apiVersion”: “2023-05-01”,

            “name”: “fw-bastion-traffic”,

            “properties”: {

                “sku”: { “name”: “AZFW_Hub”, “tier”: “Standard” },

                “threatIntelMode”: “Alert”,

                “applicationRuleCollections”: [

                    {

                        “name”: “Allow-Bastion-WebAccess”,

                        “properties”: {

                            “priority”: 100,

                            “action”: { “type”: “Allow” },

                            “rules”: [

                                {

                                    “name”: “Allow-Bastion-Portal”,

                                    “protocols”: [{ “protocolType”: “Https”, “port”: 443 }],

                                    “sourceAddresses”: [“10.1.0.0/27”],  # Bastion subnet

                                    “targetFqdns”: [

                                        “*.blob.core.windows.net”,

                                        “*.azurewebsites.net”,

                                        “*.servicebus.windows.net”

                                    ]

                                }

                            ]

                        }

                    }

                ]

            }

        }

    ]

}

  1. Azure Monitor Integration for Bastion Logging

json

{

    “resources”: [

        {

            “type”: “Microsoft.Network/bastionHosts”,

            “apiVersion”: “2023-05-01”,

            “name”: “bastion-with-logs”,

            “properties”: {

                “ipConfigurations”: [ /* … */ ],

                “enableTunneling”: true

            }

        },

        {

            “type”: “Microsoft.Insights/diagnosticSettings”,

            “apiVersion”: “2021-05-01-preview”,

            “name”: “bastion-diagnostics”,

            “properties”: {

                “workspaceId”: “[resourceId(‘Microsoft.OperationalInsights/workspaces’, ‘central-logs’)]”,

                “logs”: [

                    {

                        “category”: “BastionAuditLogs”,

                        “enabled”: true,

                        “retentionPolicy”: {

                            “days”: 90,

                            “enabled”: true

                        }

                    }

                ]

            },

            “dependsOn”: [

                “[resourceId(‘Microsoft.Network/bastionHosts’, ‘bastion-with-logs’)]”

            ]

        }

    ]

}

  1. Security and Access Control
  2. Azure RBAC for Bastion Access

json

{

    “roleAssignments”: [

        {

            “roleDefinitionId”: “1a9b8a64-43c6-4fb7-b74a-8ce04c92b13d”,  # Bastion Reader

            “principalId”: “support-team-group-id”,

            “scope”: “/subscriptions/hub-sub/resourceGroups/hub-networking/providers/Microsoft.Network/bastionHosts/cross-tenant-bastion”

        },

        {

            “roleDefinitionId”: “a795c144-9c7d-4b6b-9a53-20d2054d7b6c”,  # Bastion Contributor

            “principalId”: “bastion-admin-group-id”,

            “scope”: “/subscriptions/hub-sub/resourceGroups/hub-networking”

        }

    ]

}

  1. Conditional Access Policies

json

{

    “conditionalAccessPolicy”: {

        “displayName”: “CA-Bastion-Access-Require-MFA”,

        “users”: {

            “include”: [“Bastion-Users-Group”],

            “exclude”: [“Break-Glass-Accounts”]

        },

        “applications”: {

            “include”: [“Microsoft Azure Management”]

        },

        “conditions”: {

            “locations”: {

                “include”: [“All”]

            },

            “clientApps”: {

                “include”: [“Browser”]

            }

        },

        “grant”: {

            “operator”: “AND”,

            “controls”: [

                { “control”: “RequireMultiFactorAuthentication” },

                { “control”: “RequireCompliantDevice” }

            ]

        }

    }

}

  1. Just-In-Time VM Access with Bastion

powershell

function Enable-JITAccessWithBastion {

    param(

        [string]$VMResourceId,

        [timespan]$AccessDuration = (New-TimeSpan -Hours 2),

        [string]$Approver

    )

   

    # Request JIT access

    $jitRequest = @{

        VirtualMachines = @(

            @{

                Id = $VMResourceId

                Ports = @(

                    @{

                        Number = 3389

                        Protocol = “TCP”

                        AllowedSourceAddressPrefix = “10.1.0.0/27”  # Bastion subnet

                        MaxRequestAccessDuration = “PT2H”

                    }

                )

            }

        )

    }

   

    # Submit JIT request

    $jitPolicy = New-AzJitNetworkAccessPolicy -ResourceGroupName (Get-AzResource -ResourceId $VMResourceId).ResourceGroupName `

        -Location (Get-AzResource -ResourceId $VMResourceId).Location -Name “Bastion-JIT” `

        -VirtualMachine $jitRequest.VirtualMachines

   

    Write-Output “JIT access enabled for VM: $VMResourceId”

    Write-ActivityLog -Message “JIT access granted via Bastion for $AccessDuration” `

        -Category “Security” -ResourceId $VMResourceId

   

    return $jitPolicy

}

  1. Monitoring and Troubleshooting
  2. Bastion Connection Logging

kql

// Monitor Bastion connections across tenants

AzureDiagnostics

| where ResourceType == “BASTION_HOSTS”

| where Category == “BastionAuditLogs”

| extend SessionId = tostring(properties.SessionId)

| extend TargetResource = tostring(properties.TargetResource)

| extend User = tostring(properties.User)

| project TimeGenerated, SessionId, TargetResource, User, OperationName, ResultType

| summarize ConnectionCount = count() by bin(TimeGenerated, 1h), TargetResource

  1. Bastion Performance Monitoring

kql

// Monitor Bastion performance metrics

AzureMetrics

| where ResourceType == “BASTION_HOSTS”

| where MetricName in (“SessionCount”, “CPUUtilization”, “MemoryUtilization”)

| extend BastionName = tostring(split(ResourceId, ‘/’)[8])

| summarize

    AvgSessions = avg(Average),

    MaxSessions = max(Maximum),

    P95Sessions = percentile(Average, 95)

    by BastionName, MetricName, bin(TimeGenerated, 15m)

  1. Connection Health Checking

powershell

function Test-BastionConnectivity {

    param(

        [string]$BastionResourceGroup,

        [string]$BastionName,

        [string]$TestVMResourceId

    )

   

    $bastion = Get-AzBastion -ResourceGroupName $BastionResourceGroup -Name $BastionName

    $testVM = Get-AzResource -ResourceId $TestVMResourceId

   

    $connectivityTest = @{

        BastionStatus = $bastion.ProvisioningState

        BastionSku = $bastion.Sku.Name

        TestVMStatus = $testVM.Properties.ProvisioningState

        TestVMLocation = $testVM.Location

        NetworkConnectivity = Test-NetConnection -ComputerName $testVM.Properties.privateIPAddress -Port 3389 -InformationLevel Quiet

    }

   

    # Log connectivity status

    if ($connectivityTest.NetworkConnectivity) {

        Write-Output “Bastion connectivity test PASSED”

    } else {

        Write-Warning “Bastion connectivity test FAILED”

    }

   

    return $connectivityTest

}

  1. Cost Optimization and Management
  2. Bastion SKU Selection Guide

json

{

    “bastionSkuComparison”: {

        “Basic”: {

            “maxInstances”: 2,

            “maxSessions”: 25,

            “features”: [“RDP/SSH over browser”],

            “monthlyCost”: “$0.19/hour + data processing”,

            “recommendedFor”: “Small teams, infrequent use”

        },

        “Standard”: {

            “maxInstances”: 10,

            “maxSessions”: 50,

            “features”: [“All Basic features”, “IP Connect”, “Shareable Links”, “Native Client Support”],

            “monthlyCost”: “$0.32/hour + data processing”,

            “recommendedFor”: “Cross-tenant management, enterprise use”

        }

    }

}

  1. Automated Bastion Scaling

powershell

function Optimize-BastionCost {

    param(

        [string]$BastionResourceGroup,

        [string]$BastionName

    )

   

    $bastion = Get-AzBastion -ResourceGroupName $BastionResourceGroup -Name $BastionName

    $sessions = Get-AzMetric -ResourceId $bastion.Id -MetricName “SessionCount” -TimeGrain 01:00:00

   

    $avgSessions = ($sessions.Data | Measure-Object -Property Average -Average).Average

   

    # Scale recommendations based on usage

    if ($avgSessions -lt 5 -and $bastion.Sku.Name -eq “Standard”) {

        Write-Output “Consider downgrading to Basic SKU – low session usage detected”

    } elseif ($avgSessions -gt 40 -and $bastion.Sku.Name -eq “Standard”) {

        Write-Output “High session usage detected – monitor for performance issues”

    }

   

    return @{

        CurrentSku = $bastion.Sku.Name

        AverageSessions = [math]::Round($avgSessions, 2)

        Recommendation = if ($avgSessions -lt 5) { “Downgrade to Basic” } else { “Maintain Standard” }

    }

}

Implementation Checklist

  • Design hub VNet with dedicated AzureBastionSubnet (/27 or larger)
  • Select appropriate Bastion SKU (Basic vs Standard)
  • Configure public IP for Bastion host
  • Set up Azure Lighthouse delegations for customer VM access
  • Configure NSGs on customer VMs to allow Bastion subnet
  • Implement RBAC for Bastion access control
  • Enable diagnostic logging for audit purposes
  • Configure Conditional Access policies if needed
  • Test connectivity to customer VMs
  • Document access procedures for support teams

Summary

Using Azure Bastion for cross-tenant management provides:

✅ Secure RDP/SSH access without public endpoints
✅ No open inbound ports on customer VMs
✅ Browser-based connectivity from anywhere
✅ Azure AD integration for authentication
✅ Audit logging of all sessions
✅ Shareable links for temporary access
✅ Native client support via IP Connect

The key success factors are proper network design, security configuration, cost optimization through appropriate SKU selection, and comprehensive monitoring of Bastion sessions across all customer environments.

what are the design components of Azure Lighthouse?

Excellent question! Azure Lighthouse has a well-defined architecture with specific design components that work together to enable cross-tenant management. Here’s a comprehensive breakdown of the key design components:

  1. Core Architectural Components
  2. Tenant Relationship Structure
  3. Fundamental Design Components

Component 1: Managed Services Registration Definition (MSRD)

The core artifact that defines the service offering and access rules

json

{

    “type”: “Microsoft.ManagedServices/registrationDefinitions”,

    “apiVersion”: “2019-09-01”,

    “name”: “[guid(parameters(‘mspOfferName’))]”,

    “properties”: {

        “registrationDefinitionName”: “[parameters(‘mspOfferName’)]”,

        “description”: “Managed services offer for Azure infrastructure management”,

        “managedByTenantId”: “[parameters(‘managedByTenantId’)]”,

        “authorizations”: [

            {

                “principalId”: “[parameters(‘supportEngineersGroupId’)]”,

                “roleDefinitionId”: “b24988ac-6180-42a0-ab88-20f7382dd24c”, // Contributor

                “principalIdDisplayName”: “Support Engineers Team”

            },

            {

                “principalId”: “[parameters(‘monitoringGroupId’)]”,

                “roleDefinitionId”: “acdd72a7-3385-48ef-bd42-f606fba81ae7”, // Reader

                “principalIdDisplayName”: “Monitoring Team”

            }

        ]

    }

}

Component 2: Authorizations

Define WHO can access WHAT with WHICH permissions

json

“authorizations”: [

    {

        “principalId”: “a1b2c3d4-e5f6-7890-abcd-ef1234567890”,

        “principalIdDisplayName”: “VM Operations Team”,

        “roleDefinitionId”: “9980e02c-c2be-4d73-94e8-173b1dc7cf3c”, // Virtual Machine Contributor

        “delegatedRoleDefinitionIds”: [

            “b24988ac-6180-42a0-ab88-20f7382dd24c” // Contributor

        ]

    }

]

Component 3: Registration Assignments

The actual assignment of the service offering to customer resources

json

{

    “type”: “Microsoft.ManagedServices/registrationAssignments”,

    “apiVersion”: “2019-09-01”,

    “name”: “[guid(parameters(‘mspOfferName’), parameters(‘customerSubscriptionId’))]”,

    “properties”: {

        “registrationDefinitionId”: “[resourceId(‘Microsoft.ManagedServices/registrationDefinitions’, parameters(‘registrationDefinitionId’))]”

    }

}

  1. Identity and Access Management Components
  2. Principal Types

json

{

    “principalOptions”: {

        “user”: {

            “type”: “User”,

            “useCase”: “Individual administrators”,

            “limitation”: “User lifecycle management complexity”

        },

        “group”: {

            “type”: “Group”,

            “useCase”: “Recommended for teams”,

            “benefit”: “Simplified user management”

        },

        “servicePrincipal”: {

            “type”: “Service Principal”,

            “useCase”: “Automation, runbooks, applications”,

            “benefit”: “Non-interactive access”

        },

        “managedIdentity”: {

            “type”: “Managed Identity”,

            “useCase”: “Azure services automation”,

            “benefit”: “No credential management”

        }

    }

}

  1. RBAC Integration

json

{

    “rbacIntegration”: {

        “builtInRoles”: [

            “Owner”,

            “Contributor”,

            “Reader”,

            “User Access Administrator”,

            “Virtual Machine Contributor”,

            “Storage Account Contributor”

        ],

        “customRoles”: {

            “purpose”: “Least privilege access”,

            “example”: “VM-Start-Stop-Only”,

            “benefit”: “Reduced risk exposure”

        },

        “limitations”: [

            “Cannot grant classical administrator roles”,

            “Cannot manage Azure AD itself”,

            “Limited data plane operations”

        ]

    }

}

  1. Scope Management Components
  2. Scope Levels

json

{

    “scopeLevels”: {

        “managementGroup”: {

            “useCase”: “Enterprise-wide management”,

            “benefit”: “Broad coverage across subscriptions”,

            “limitation”: “Requires customer MG permissions”

        },

        “subscription”: {

            “useCase”: “Most common scenario”,

            “benefit”: “Full subscription access”,

            “recommendation”: “Default starting point”

        },

        “resourceGroup”: {

            “useCase”: “Limited, specific resources”,

            “benefit”: “Least privilege principle”,

            “example”: “Single application workload”

        }

    }

}

  1. Scope Hierarchy Design
  2. Service Provider Management Components
  3. My Customers View

Centralized view of all customer resources

json

{

    “myCustomers”: {

        “features”: [

            “Unified view across all customers”,

            “Directory and subscription switcher”,

            “Bulk operations across tenants”,

            “Access review capabilities”

        ],

        “accessMethods”: [

            “Azure Portal: My Customers blade”,

            “PowerShell: Get-AzLighthouse* cmdlets”,

            “CLI: az managedservices commands”,

            “REST API: ManagedServices provider”

        ]

    }

}

  1. Managed Services Marketplace Integration

json

{

    “marketplaceIntegration”: {

        “privateOffers”: {

            “purpose”: “Specific customer offerings”,

            “process”: “Publish via Partner Center”,

            “benefit”: “Formalized service agreement”

        },

        “publicOffers”: {

            “purpose”: “Standardized service catalog”,

            “process”: “Public marketplace listing”,

            “benefit”: “Customer self-service onboarding”

        },

        “pricingModels”: [

            “Bring Your Own License (BYOL)”,

            “Usage-based pricing”,

            “Flat-rate monthly pricing”

        ]

    }

}

  1. Security and Compliance Components
  2. Audit and Monitoring

json

{

    “auditComponents”: {

        “activityLogs”: {

            “source”: “Customer tenant”,

            “data”: “All actions by managing tenant users”,

            “retention”: “90 days by default”

        },

        “azureAdAuditLogs”: {

            “source”: “Managing tenant”,

            “data”: “User sign-ins and access patterns”,

            “integration”: “Azure Sentinel, Log Analytics”

        },

        “customMonitoring”: {

            “approaches”: [

                “Centralized Log Analytics workspace”,

                “Azure Policy compliance tracking”,

                “Custom alert rules for suspicious activity”

            ]

        }

    }

}

  1. Access Review Components

json

{

    “accessReview”: {

        “periodicReviews”: {

            “frequency”: “Quarterly recommended”,

            “scope”: “All lighthouse authorizations”,

            “process”: “Azure AD Access Reviews”

        },

        “automatedRemediation”: {

            “inactiveUsers”: “Auto-remove after 90 days inactivity”,

            “roleChanges”: “Update based on job function changes”,

            “customerChanges”: “Adjust based on contract changes”

        }

    }

}

  1. Automation and Integration Components
  2. ARM Template Components

json

{

    “armTemplateStructure”: {

        “parameters”: {

            “mspOfferName”: “Unique service identifier”,

            “managedByTenantId”: “Service provider tenant ID”,

            “authorizations”: “Array of access definitions”

        },

        “variables”: {

            “registrationDefinitionId”: “Generated GUID”,

            “roleDefinitionIds”: “RBAC role references”

        },

        “resources”: [

            “registrationDefinition”,

            “optional: customer resources monitoring”

        ],

        “outputs”: {

            “mspOfferDescription”: “Service description”,

            “registrationDefinitionId”: “For assignment reference”

        }

    }

}

  1. PowerShell Integration

powershell

# Lighthouse Management Module

class LighthouseDesignComponents {

    [string]$ManagingTenantId

    [array]$CustomerSubscriptions

    [hashtable]$ServiceOfferings

    [array]$AuthorizationTemplates

   

    # Method to create new service offering

    [void] CreateServiceOffering(

        [string]$OfferName,

        [array]$Authorizations,

        [string]$Description

    ) {

        # Implementation for registration definition

    }

   

    # Method to onboard customer

    [void] OnboardCustomer(

        [string]$CustomerSubscriptionId,

        [string]$OfferName,

        [string]$Scope

    ) {

        # Implementation for registration assignment

    }

}

  1. Advanced Design Components
  2. Nested Lighthouse Scenarios

json

{

    “nestedLighthouse”: {

        “scenario”: “Tiered service delivery”,

        “architecture”: “MSP -> Sub-MSP -> End Customer”,

        “components”: [

            “Primary MSP delegates to secondary MSP”,

            “Secondary MSP manages customer resources”,

            “Audit chain maintained across tiers”

        ],

        “considerations”: [

            “Complex access tracing”,

            “Cumulative permission evaluation”,

            “Multi-level compliance requirements”

        ]

    }

}

  1. Cross-Tenant Monitoring Architecture

json

{

    “monitoringArchitecture”: {

        “centralLogging”: {

            “workspace”: “Log Analytics in managing tenant”,

            “dataSources”: [

                “Activity logs from all customers”,

                “Resource metrics and diagnostics”,

                “Security Center findings”

            ],

            “integration”: “Azure Lighthouse APIs”

        },

        “alerting”: {

            “unifiedAlerts”: “Cross-tenant alert rules”,

            “actionGroups”: “Centralized notification system”,

            “automatedResponse”: “Cross-tenant runbooks”

        }

    }

}

  1. Governance and Policy Components
  2. Azure Policy Integration

json

{

    “policyComponents”: {

        “definitionLocation”: “Managing tenant”,

        “assignmentScope”: “Customer subscriptions”,

        “complianceTracking”: “Centralized compliance dashboard”,

        “remediation”: “Cross-tenant remediation tasks”

    }

}

  1. Cost Management Components

json

{

    “costManagement”: {

        “visibility”: “Cost analysis across all customers”,

        “chargeback”: “Resource tagging for cost allocation”,

        “budgeting”: “Cross-tenant budget alerts”,

        “optimization”: “Centralized recommendations”

    }

}

  1. Lifecycle Management Components
  2. Onboarding Workflow

json

{

    “onboardingProcess”: {

        “phase1”: {

            “name”: “Preparation”,

            “activities”: [

                “Customer agreement and scope definition”,

                “RBAC strategy and role design”,

                “ARM template development”

            ]

        },

        “phase2”: {

            “name”: “Deployment”,

            “activities”: [

                “Registration definition creation”,

                “Customer deployment validation”,

                “Access testing and verification”

            ]

        },

        “phase3”: {

            “name”: “Operation”,

            “activities”: [

                “Monitoring and alerting setup”,

                “Documentation and runbooks”,

                “Customer training and handoff”

            ]

        }

    }

}

  1. Offboarding Components

json

{

    “offboardingProcess”: {

        “accessRevocation”: {

            “immediate”: “Remove registration assignments”,

            “validation”: “Verify access termination”,

            “confirmation”: “Customer sign-off”

        },

        “dataHandling”: {

            “logsRetention”: “Maintain audit trails as required”,

            “customerData”: “Ensure complete data handover”,

            “compliance”: “Meet contractual and regulatory requirements”

        }

    }

}

Summary of Key Design Components

Component Category

Key Elements

Purpose

Core Architecture

Registration Definitions, Authorizations, Assignments

Foundation of service offering and access

Identity & Access

Users, Groups, Service Principals, Managed Identities

Secure, manageable access control

Scope Management

Management Groups, Subscriptions, Resource Groups

Granular resource targeting

Service Provider Tools

My Customers view, Marketplace integration

Operational efficiency and scaling

Security & Compliance

Audit logs, Access reviews, Monitoring

Risk management and compliance

Automation

ARM templates, PowerShell, REST APIs

Scalable deployment and management

Governance

Azure Policy, Cost Management, Tagging

Consistent operations and control

Lifecycle

Onboarding, Operations, Offboarding

End-to-end service management

The strength of Azure Lighthouse lies in how these components work together to create a secure, scalable, and manageable cross-tenant management solution that maintains clear boundaries while enabling efficient service delivery.