A comprehensive lab environment for testing Power Platform premium features with Azure integration using managed identities, VNet integration, and enterprise security patterns.
This repository provides a quick and automated way to provision Azure and Power Platform resources for:
- β Testing Power Platform premium features (Managed Environments, VNet Integration, Enterprise Policies)
- β Learning enterprise integration patterns between Power Platform and Azure
- β Demonstrating managed identity authentication (no secrets in code!)
- β Exploring secure networking (VNets, Private Endpoints, Firewalls, NAT Gateway)
- β Building production-like architectures with minimal cost (~$0-15/month default config)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Power Platform β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Dataverse Environment (Developer - FREE) β β
β β β’ Managed Environment Features β β
β β β’ VNet Integration (Enterprise Policy) β β
β β β’ Custom APIs (Dataverse Plugins with Managed Identity) β β
β β β’ Federated Identity Credentials (workload identity) β β
β βββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ
β Private Connectivity
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββ
β β Azure β
β βββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββ β
β β VNet (West Europe + North Europe paired regions) β β
β β β’ Subnet Delegation for Power Platform β β
β β β’ Private DNS Zones β β
β β β’ Network Security Groups β β
β β β’ NAT Gateway (optional - whitelistable IP) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Optional Optional β
β ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ β
β β Azure Functions β β Logic App Std β β Data Factory β β
β β (.NET 8 Flex) β β (Workflows) β β (Managed VNet) β β
β β β’ VNet Integration β’ VNet Integrationβ β β’ Dataverse β β
β β β’ OAuth2 + OBO β β β’ Dataverse β β Linked Svc β β
β β β’ RBAC Auth β β Connector β β β’ RBAC Auth β β
β ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ β
β Optional β
β ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ β
β β API Management β β Key Vault β β Storage Accts β β
β β (BFF Pattern) β β (RBAC-based) β β (RBAC-based) β β
β β β’ Internal VNet β β β’ VNet Rules β β β’ VNet Rules β β
β β β’ OAuth Validation β β’ Secrets Mgmt β β β’ Private EP β β
β ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Azure-PowerPlatform-Lab/
βββ README.md # This file
βββ LICENSE # MIT License
βββ .gitignore # Git ignore patterns
β
βββ Infrastructure/ # Terraform IaC
β βββ terraform/
β βββ README.md # Detailed infrastructure docs
β βββ deploy.ps1 # Deployment automation script
β βββ main.tf # Core orchestration
β βββ variables.tf # Variable declarations
β βββ locals.tf # Local values and naming
β βββ providers.tf # Provider configuration
β βββ versions.tf # Version constraints
β βββ outputs.tf # Output definitions
β β
β βββ Resources/ # Resource-specific configs
β β βββ api-management.tf # API Management
β β βββ data-factory.tf # Data Factory
β β βββ function-app.tf # Azure Functions
β β βββ logic-apps.tf # Logic App Standard
β β βββ network.tf # VNet, subnets, DNS
β β βββ power-platform.tf # Power Platform envs
β β
β βββ modules/ # 13 reusable modules
β β βββ api-management/
β β βββ app-registrations/
β β βββ data-factory/
β β βββ function-app-flex/
β β βββ key-vaults/
β β βββ log-analytics/
β β βββ logic-app-connections/
β β βββ logic-app-standard/
β β βββ network/
β β βββ power-platform/
β β βββ power-platform-enterprise-policy/
β β βββ resource-groups/
β β βββ storage-account/
β β
β βββ environments/ # Environment configs
β β βββ dev/terraform.tfvars
β β
β βββ bff-openapi/ # OpenAPI specs
β βββ pp-bff.json
β
β
β
β
β
β
β
β
βββ Source/ # Application code
βββ IntegrationGuide.slnx # Visual Studio solution
β
βββ Azure/ # Azure components
β βββ Functions/
β β βββ FnBackend/ # .NET 8 Isolated Function App
β β βββ Functions/ # HTTP-triggered functions
β β βββ Services/ # Dataverse service client
β β βββ Middleware/ # OAuth2 validation
β β βββ Deployment/ # Deployment scripts
β β βββ deploy.ps1 # Function app code deployment script
β β
β β
β β
β βββ LogicApps/
β β βββ Workflows/ # Logic App Standard workflows
β β β βββ DataverseIntegration/
β β β β βββ workflow.json
| | | βββ DataverseTrigger/
β β β β βββ workflow.json
β β β β
β β β βββ host.json
| | | βββ connections.json
| | | βββ parameters.json
β β β
β β βββ Deployment/
| | βββ deploy.ps1 # Logic App Workflows deployment script
β β
β βββ AzureDataFactory/
β βββ adf_export/ # Exported ADF artifacts
β β βββ datasets/ # Dataverse datasets
β β βββ pipelines/ # Import pipelines
β βββ data/ # Sample data files
β βββ Deployment/ # Import automation
β
βββ PowerPlatform/ # Power Platform components
βββ Plugin/ # Dataverse Plugin (.NET 4.6.2)
β βββ AzKeyVaultDemoPlugin.cs # Azure Key Vault integration
β βββ GenericHttpClientDemoPlugin.cs # HTTP client with MI
β βββ PluginBase.cs
β βββ Services/
β βββ AzKeyVaultService.cs
β βββ GenericHttpClient.cs
β
βββ Solutions/
βββ pplab01/
βββ src_template/ # Template with token placeholders, Unpacked solution source
β βββ customapis/ # Custom APIs
β β βββ kb_AzKeyVaultDemoApi/
β β βββ kb_GenericHttpClient/
β βββ pluginpackages/
β βββ Other/
βββ src/ # terraform apply will output here unpacked solution with replaced tokens
βββ packed/ # Packed solution ZIP after terraform apply command
- Azure Subscription with Owner or Contributor + User Access Administrator roles
- Power Platform License (Developer environment is FREE, or M365 trial)
- Terraform 1.5+ (Install)
- Azure CLI (Install)
- Power Platform CLI (terraform power platform module requires this to configure managed environment since native tf provider has some bugs)
- .NET 8 SDK (Install)
- Visual Studio 2022 or VS Code (for source code development)
1οΈβ£ Deploy Infrastructure (5-10 minutes with minimal configuration, 30-45 minutes with all resources)
# Clone repository
git clone https://github.com/malaker/Azure-PowerPlatform-Lab.git
cd Azure-PowerPlatform-Lab/Infrastructure/terraform
# Configure environment
# Edit environments/dev/terraform.tfvars with your settings:
# - subscription_id
# - default_power_platform_owner_id (your Entra ID user GUID)
# - apim_publisher_email (if enabling APIM)
# Login to Azure
az login
# Initialize Terraform (first time only)
.\deploy.ps1 -Init -Environment dev
# Review what will be created
.\deploy.ps1 -Environment dev -Action plan
# Deploy infrastructure
.\deploy.ps1 -Environment dev -Action apply
# View outputs (URLs, client IDs, etc.)
terraform outputWhat gets deployed:
- 5 Resource Groups
- 4 App Registrations (one with federated credentials)
- VNet with 6 subnets + NSGs
- Key Vault (RBAC-based) that includes client id and secrets
- Azure Function App (Flex Consumption)
- Storage Accounts (RBAC-based)
- Log Analytics + Application Insights
- Power Platform Developer Environment
- Enterprise Policy + VNet Integration
π° Default Cost: ~$0-15/month
cd Source/Azure/Functions/FnBackend/Deployment
#Since terraform generates everytime unique resource names either get function app name from portal azure or terraform outputs
.\deploy.ps1 -FunctionAppName <function resource name>
cd Source/Azure/LogicApps/Deployment
.\deploy.ps1 -LogicAppStandardResourceName <logic app resource name>
cd Source/Azure/AzureDataFactory/Deployment
# Import datasets and pipelines
.\deploy.ps1 -AdfResourceName <ADF resource name>
The solution is automatically packed by Terraform if the source exists.
Deploy solution manually or using PAC CLI
~$0-15/month in Dev environment
| Component | Status | Monthly Cost |
|---|---|---|
| Core Infrastructure (Functions*, Storage, Key Vault) | β Enabled | ~$0 (Free tier) |
| Networking (VNet, NSGs, VNet Peering**) | β Enabled | ~$0-5 (Traffic-based) |
| NAT Gateway | β Disabled | Saves ~$36.50 |
| API Management (Developer_1) | β Disabled | Saves ~$48.04 |
| Logic App Standard (WS1) | β Disabled | Saves ~$197 |
| Data Factory | β Disabled | Saves ~$2-10 |
| Power Platform Developer Env | β Enabled | $0 (Free) |
| Subnet Delegation (Enterprise Policy) | β Enabled | $0 (Free) |
* Azure Functions (Flex Consumption Plan): Includes a generous free monthly grant of 250,000 executions and 100,000 GB-seconds per subscription. Beyond the free tier, costs are $0.000026/GB-s for execution time and $0.40 per million executions. For typical dev/demo workloads, you'll likely stay within the free tier.
** VNet Peering: Cross-region VNet peering (West Europe β North Europe) incurs data transfer charges at ~$0.035/GB for both inbound and outbound traffic. VNets and NSGs themselves are free, but peering costs depend on traffic volume between regions. For minimal dev/demo traffic, costs are typically under $5/month.
~$283-295/month in Dev environment
See Infrastructure README for detailed cost analysis.
Control what gets deployed via environments/dev/terraform.tfvars:
# Network
enable_nat_gateway = false # ~$36.50/month - Static IP for whitelisting
enable_powerplatform_subnet_delegation = true # Free - VNet integration
# Azure Services
enable_api_management = false # ~$48.04/month - API Gateway
enable_logic_apps = false # ~$197/month - Low-code workflows
enable_data_factory = false # ~$2-10/month - ETL/ELT pipelines
# Power Platform
power_platform_environments = [...] # Free for DeveloperDataverse Plugin β Azure Key Vault:
- Federated Identity Credentials (Workload Identity)
- No client secrets in code or environment variables
Dataverse β Internal APIM (Optional) β Azure Functions β Dataverse:
- Dataverse Plugin APIM/Function app integration using managed identity
- Service Principal with OAuth2
- On-Behalf-Of (OBO) flow for user context # Custom connector to be defined manually in maker portal
- Client credentials flow for app-only scenarios
Logic Apps β Dataverse:
- Managed Identity with API Connections
- Service Principal authentication
- Secrets stored in Key Vault (via references)
- Networking configuration (Firewall+VNET outbound integration) # Since Dataverse connector does not use subnet delegation, to function correctly Dataverse Trigger for Logic App it is required to whitelist either Service Tag: PowerPlatformInfra or individual Power Platform IPs which is very error prone.
Data Factory β Dataverse:
- Managed Identity with linked services
- Service Principal authentication
- Key Vault integration for credentials
- VNET Integration
VNet Integration:
- Subnet delegation for Power Platform
- Private connectivity between Azure and Dataverse
- No public internet traversal
Network Security:
- NSGs on all subnets
- Network access restrictions on Functions/Logic Apps
- Private DNS zones for internal APIM
- Service endpoints for Key Vault and Storage
Outbound IP Control:
- Optional NAT Gateway for static IP
- Whitelistable IP for Power Platform IP firewall
- Consistent outbound connectivity
Zero Trust Principles:
- RBAC-based access control (no legacy access policies)
- Managed identities everywhere (no connection strings)
- Key Vault for all secrets
- Network isolation with VNets
Least Privilege Access:
- Function App: Only Key Vault Secrets User + Storage Contributor
- Logic Apps: Only required API Connection access
- Data Factory: Only linked service permissions
- Power Platform SVC: Only required API permissions
API Security:
- OAuth2 + JWT validation on Azure Functions
- API Management with OAuth policies
- App roles for application permissions
- Delegated scopes for user context
- β Managed Environments
- β VNet Integration (Enterprise Policies)
- β Dataverse Plugins with Managed Identity
- β Custom APIs
- β IP Firewall with NAT Gateway (optional)
- β Azure Functions with OAuth2 + OBO flow
- β Logic App Standard with Dataverse triggers
- β Data Factory ETL/ELT pipelines
- β API Management BFF pattern
- β Key Vault integration (no secrets in code!)
- β VNet private connectivity
- β Managed Identity end-to-end
- β RBAC-based access control
- β Network isolation with VNets
- β OAuth2 token validation
- β App roles + delegated permissions
- β Key Vault secret management
To delete all resources:
cd Infrastructure/terraform
# Destroy all infrastructure
.\deploy.ps1 -Environment dev -Action destroy
# Confirm with 'destroy-dev'
# Confirm with 'yes'Note: Power Platform environments may have deletion protection enabled. Manually delete in Power Platform Admin Center if needed. Remember to unlink enterprise policy in the first place in case of manual deletion resources.
This project is licensed under the MIT License - see the LICENSE file for details.
β If this repository helped you, please consider giving it a star!