Enhancing Azure Network Security with Terraform: Best Practices

  • Thread Author
Application network security in Azure isn’t just about spinning up a couple of apps—it’s about carefully designing a network that isolates and protects your services while ensuring they can still talk to each other. In a recent Medium post, Bob Code takes us on a hands-on journey through configuring subnets, endpoints, DNS, and NSGs with Terraform. He not only walks through the code but also explains the rationale behind Azure’s recommended security blueprint. Let’s break down the key insights and explore the broader implications for Windows and cloud administrators.

Presentation slide on enhancing Azure network security using Terraform best practices.Segregating Your Application with Subnets in Azure​

Azure’s blueprint for securing applications starts with the principle of segregation. Instead of lumping all your services into one network space, Azure recommends placing each service in its own subnet. This separation:
• Helps isolate workloads
• Reduces the attack surface by only exposing necessary endpoints
• Simplifies applying security policies on a per-service basis
Bob Code’s example creates two separate function apps housed within their own subnets. This design serves as a starting point for better network security. The Terraform code creates a virtual network (vnet) along with subnets to ensure that even though the two apps reside in the same vnet, they communicate only through their designated channels.

Setting Up the Foundation Using Terraform​

The initial Terraform code demonstrates how to deploy two applications using Azure Functions in a controlled environment. The code snippets include resource definitions for storage accounts, service plans, and the two function apps. Here’s an abbreviated look at what the initial setup might involve:

resource "azurerm_storage_account" "sa1" {
name = "dnsexamplesa"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_service_plan" "asp" {
name = "dns-asp"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
os_type = "Windows"
sku_name = "P1v2"
}

resource "azurerm_windows_function_app" "app1" {​

name = "dns-app1"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
storage_account_name = azurerm_storage_account.sa1.name
storage_account_access_key = azurerm_storage_account.sa1.primary_access_key
service_plan_id = azurerm_service_plan.asp.id
virtual_network_subnet_id = azurerm_subnet.subnet1.id
app_settings = {
"WEBSITE_RUN_FROM_PACKAGE" = "1"
"WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED" = "1"
}
}
This snippet (and its counterpart for app2) sets up the groundwork for deploying your applications securely on Azure. The use of Terraform code ensures that these configurations are both reproducible and maintainable—a critical requirement for any production environment.

The Role of Subnet Delegation​

Deploying services into a subnet is one thing—making sure that Azure applies the correct network policies automatically is another. That’s where subnet delegation comes into play. Subnet delegation in Azure automates:
• IP allocation
• Routing
• Conflict prevention
• Policy application
Bob Code’s updated Terraform code for subnets includes a delegation block. When you delegate a subnet to a specific service (for example, Microsoft.Web/serverFarms for Azure functions), Azure enforces service-specific rules that streamline network management. However, there’s a catch: once a subnet is delegated, certain functionalities, like attaching private endpoints, become restricted.
For example, without delegation, your service subnet might be fine. But if you try to add a private endpoint directly to it, you’ll encounter an error because Azure won’t allow private endpoints in a subnet that’s already been delegated. This scenario is a classic reminder: with great power (delegation) comes some limitations.

Private Endpoints: A Double-Edged Sword​

A private endpoint gives your Azure service a private IP address from your virtual network, allowing secure communication over the Azure backbone rather than the public internet. Think of it as giving your application a secret handshake that’s recognized only within your trusted environment.
However, as Bob Code’s article highlights, if you try to attach a private endpoint to a subnet already dedicated (delegated) to a service like Azure Functions, you’ll hit this error:
"Private endpoint ... cannot be created as subnet ... is delegated."
This limitation is by design. Delegated subnets are reserved exclusively for their assigned services, preventing conflicts and ensuring dedicated resources for service-specific management.

Creating a Dedicated Subnet for Private Endpoints​

The natural solution? Create a dedicated subnet just for private endpoints. In the Terraform code, Bob Code addresses this by introducing a new subnet (say, subnet3) that isn’t subject to service delegation. This design separation means:
• Your application services (in delegated subnets) remain isolated and benefit from Azure-managed policies.
• Private endpoints get their own dedicated network space, enabling secure linkages without stepping on the toes of delegated configurations.
Here’s a snippet of how this subnet for private endpoints might look:

resource "azurerm_subnet" "subnet3" {
name = "subnet3"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = [ "10.0.3.0/24" ]
}
resource "azurerm_private_endpoint" "app1_pe" {
name = "app1-pe"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.subnet3.id
}

resource "azurerm_private_endpoint" "app2_pe" {​

name = "app2-pe"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.subnet3.id
}
This approach ensures that private endpoints function without conflict, preserving the integrity of the delegated subnets while still allowing a secure, private connection. It’s a clear reminder that sometimes separating concerns—whether in code or network architecture—is the best strategy.

The Power of Azure Private Link​

Once the private endpoints are set up, the next step is connecting them to the applications through Azure Private Link. In simple terms, Azure Private Link creates a private connection between your private endpoint and the Azure service. This full integration ensures that communication travels exclusively over the secure Azure backbone.
Azure Private Link is a game-changer for Windows users and administrators looking to secure PaaS services like SQL Server, Storage accounts, or App Services. By using Private Link, you avoid exposing sensitive data to the public internet, thereby significantly mitigating the risk of external breaches.
In addition to security, Private Link simplifies network management. It abstracts the complexity behind secure connections, reducing the need for intricate firewall rules or complicated routing logic. For IT professionals managing a hybrid environment, this efficiency translates directly into easier maintenance and stronger security postures.

Emphasizing Network Security Groups (NSGs)​

While the article’s focus is on subnets, endpoints, and DNS configuration, it’s worth taking a moment to consider the role of Network Security Groups (NSGs). NSGs are your front-line defenders—they control inbound and outbound traffic to your subnets and resources.
Key benefits of NSGs include:
• Granular traffic filtering based on source, destination, port, and protocol
• Simplified administration of network security policies
• The ability to apply policies at both the subnet and resource level
In an environment where you’re using Terraform to automate your deployments, integrating NSG configurations is a best practice. Whether you’re having internal communication between apps or restricting external traffic, NSGs help ensure that only authorized traffic gets through. Their pairing with delegated subnets and dedicated private endpoint subnets reinforces a robust security strategy.

Testing and Validating Your Network Design​

After setting up your infrastructure using Terraform, testing becomes critical. Bob Code touches on testing connectivity between the apps via the private endpoints. Here are some testing points you should consider:
  • Validate that your function apps are correctly deployed within their respective subnets.
  • Confirm that the dedicated private endpoint subnet is functioning and correctly forwarding requests.
  • Use network diagnostic tools available in Azure to monitor traffic flow.
  • Ensure that NSG rules (if applied) are correctly enforcing security without interrupting legitimate communication.
Consider running these tests regularly as part of your DevOps pipeline. Automated tests can catch misconfigurations early, keeping downtime and security lapses to a minimum.

Conclusion: Balancing Functionality and Security​

Bob Code’s deep dive into application network security using Terraform on Azure serves as a practical guide for both new and seasoned cloud professionals. By carefully segregating applications into dedicated subnets, implementing delegation for service-specific policies, and establishing dedicated spaces for private endpoints, administrators can construct an environment where security is baked in from day one.
Key takeaways for Windows and Azure users include:
• Segregation is key—separate different services into their own subnets to reduce the attack surface.
• Use subnet delegation to allow Azure to automatically manage networking rules, but be mindful of its limitations regarding private endpoints.
• When creating private endpoints, allocate a dedicated subnet to avoid conflicts and ensure private connectivity.
• Leverage Azure Private Link to build secure, private connections between your services, keeping all traffic off the public internet.
• Incorporate NSGs for an added layer of security, filtering traffic and enforcing company policies with precision.
In today’s cloud-first world, designing a secure network isn’t optional—it’s essential. While the technical details might seem overwhelming at first, careful planning and automation with Terraform can dramatically simplify this process. And as always, while there’s always room for more robust solutions, the architecture outlined here provides a secure foundation for modern cloud applications.
By adopting these best practices, you not only improve the security posture of your applications but also streamline maintenance and operations in an increasingly competitive digital landscape. As Microsoft and Azure continue to evolve, staying ahead of security trends and adapting your architecture accordingly will be essential for long-term success.
Short, sweet, and secure—this robust setup reminds us all that the best defense in digital architecture is smart, deliberate design combined with powerful, built-in cloud capabilities.

Source: Medium
 
Last edited:
Securing your applications in the cloud is a bit like locking your front door—but still leaving a carefully controlled side entrance for your trusted friends. For anyone deploying apps in Azure, the challenge isn’t only about getting your service up and running; it’s about ensuring that your network stays secure while enabling secure communication between services. This deep dive into Azure network security, illustrated with Terraform code, brings together best practices around subnets, delegation, private endpoints, DNS, and NSGs.

Deploying Your Azure App with Terraform​

Imagine you’ve just deployed your app to Azure. You’ve got your storage account, service plan, and even your function apps running. But the question that immediately arises is: Who can access your app, and how can you control that access? In the example provided, the code deploys two Windows Function Apps—each tucked away in its own subnet of a virtual network. The Terraform snippets demonstrate how to create all the necessary resources:
  • Storage Account & Service Plan: These form the bedrock of your application, ensuring that it has both the storage and compute resources needed.
  • Function Applications: Configured with relevant settings (like .NET version and CORS policy) to ensure they’re production-ready.
  • Virtual Network and Subnets: The apps are assigned to different subnets within a single virtual network (VNET), ensuring logical segmentation.
This modular approach not only organizes your resources but also sets the stage for stronger security controls down the line.

Azure Networking Fundamentals: VNETs, Subnets, and Delegation​

Azure’s blueprint for application security recommends isolating services within their own subnets. This means your two function apps reside under separate subnets, enabling you to tightly control which services can “talk” to each other. But as you might have experienced, deploying app services to a subnet without proper delegation is akin to leaving your door unlocked for everyone.

Why Subnet Delegation Matters​

When you receive an error like “Subnet in VNET is missing a delegation,” it’s Azure’s way of reminding you that specialized services—like App Services or Function Apps—require a dedicated set of rules to manage IP allocation, routing, conflict prevention, and policy enforcement. By including a delegation block in your subnet definition, you effectively tell Azure, “This subnet is reserved exclusively for a specific service type.”
Delegation handles several crucial tasks:
  • IP Allocation: Automatically manages and reserves IP addresses.
  • Routing: Ensures each service’s traffic is correctly directed.
  • Conflict Prevention: Avoids IP conflicts by enforcing dedicated resource rules.
  • Policy Enforcements: Applies security and network policies aligned with the service requirements.
For example, updating your Terraform code to include a delegation block for services like "Microsoft.Web/serverFarms" allows your Azure Function Apps to integrate seamlessly with the network configuration.

Private Endpoints and the Necessity for Dedicated Subnets​

A key part of securing your application network is limiting exposure through private endpoints (PEs). Think of a private endpoint as a specialized network interface that assigns a private IP to a service, ensuring that traffic flows through the secure channels of your VNET. However, there’s a twist: if you try to deploy a private endpoint in a subnet already delegated to another service (like Microsoft.Web/serverFarms), Azure will block your attempt with a frustrating error message.

The Private Endpoint Dilemma​

The error “PrivateEndpointCreationNotAllowedAsSubnetIsDelegated” is a clear indicator that Azure wants you to maintain separation of concerns. In other words, a subnet designated for delegated services isn’t the right home for a private endpoint. The solution? Create a dedicated subnet (say, subnet3) strictly for your private endpoints. This dedicated space prevents conflicts and ensures that Azure can manage routing and security policies properly.

Bridging the Gap with Azure Private Link​

Once you’ve isolated your private endpoints, the next step involves connecting them back to your application. Enter Azure Private Link—a service that acts as the secure conduit linking your private endpoint to the corresponding Azure service (like your function app). In the background, the private endpoint’s network interface uses Azure’s backbone network to forward requests securely to the target service. The result is a seamless, secure connection that remains completely isolated from public internet exposure.

Integrating DNS and Network Security Groups (NSGs)​

While the Terraform code highlights subnets, delegation, and private endpoints, the broader network security strategy often incorporates additional layers:
  • Private DNS and A Records: By integrating DNS configurations, you ensure that your private endpoints are resolvable within your network using familiar naming conventions.
  • Network Security Groups (NSGs): NSGs play a pivotal role in controlling traffic flow. They give you fine-grained control over inbound and outbound traffic, ensuring that only approved communication paths are open.
Although not fully detailed in the snippet above, these components are essential in a robust security framework. NSGs help in filtering external traffic while DNS management ensures that your services are easily and securely located within the private network.

Testing, Debugging, and Next Steps​

One of the strengths of using Terraform is the repeatability and visibility it provides during deployment. When you encounter errors—like trying to add a private endpoint to a delegated subnet—the error messages guide you toward the right architecture:
  • Deploy Your Baseline Resources: Start with your storage account, service plan, VNET, and function apps.
  • Apply Subnet Delegation: Ensure each subnet has the proper delegation block for services like Microsoft.Web/serverFarms.
  • Isolate Private Endpoints: Create a dedicated subnet for your private endpoints to avoid conflicts.
  • Test Connectivity: Once deployed, verify that your private endpoints correctly maintain a secure conduit via Azure Private Link.
This methodical approach not only downplays the risk of misconfiguration but also demonstrates the inherent agility of Terraform when managing complex Azure network architectures.

Final Thoughts​

Securing your application's network in Azure isn’t just about locking down external access—it’s about creating a well-architected, multi-layered defense in depth that allows your services to communicate securely. By using Terraform code to configure subnets, delegation, private endpoints, and integrating DNS and NSGs, you’re following a blueprint that aligns with best practices recommended by Microsoft.
The thoughtful separation of delegated subnets for app services and dedicated subnets for private endpoints underscores the importance of planning in network design. It’s a nimble dance between functionality and security—a balance every IT professional must master.
As you explore, experiment, and refine your configurations, remember: the goal is to create an environment where your application can thrive securely in today’s ever-evolving cloud landscape. Feel free to share your insights or any creative tweaks you’ve discovered along the way—the conversation is always richer when experts join in.

Source: Medium
 
Last edited:
Delving into the intricacies of Azure application network security reveals that designing a secure, resilient infrastructure isn’t just about spinning up resources—it’s about structuring those resources with care and precision. When applications communicate behind the scenes over the Azure backbone, ensuring that each component resides in its own well-defined space becomes paramount. One recent blog post exemplifies these best practices by walking through the process of segmenting applications with subnets, service delegations, private endpoints, and even leveraging Terraform to deploy standardized network security policies.

Understanding Azure Network Segmentation​

In today’s cloud era, segregating application components is more than a best practice—it’s a necessity. The approach of dividing a Virtual Network (vNet) into multiple subnets allows for granular control over communication, resource isolation, and ultimately, security. In our highlighted scenario, two Azure Function Apps are deployed, each residing in its own subnet within the same vNet. This separation means that, even as these apps communicate with each other, unnecessary exposure is minimized, directly aligning with Azure’s security blueprint.
Key points include:
  • Separating applications into dedicated subnets to isolate traffic.
  • Minimizing the attack surface by controlling which services can communicate.
  • Ensuring that Azure’s built-in security controls (and routing policies) function as intended.

The Role of Subnet Delegation​

A critical technical detail discussed in the post is subnet delegation. When you delegate a subnet, you’re essentially instructing Azure to enforce a set of service-specific rules and policies directly on that network segment. This is particularly important for services like Azure Function Apps that have known networking behaviors.
Delegation helps by:
  • Automatically managing IP allocation.
  • Enforcing service-specific routing policies.
  • Preventing configuration or security conflicts between on-premises and cloud components.
  • Ensuring that network policies tailored for dedicated services are automatically applied.
A common stumbling block encountered is the error generated when trying to add a private endpoint to a subnet already delegated to a service (e.g., Microsoft.Web/serverFarms). This error is a security mechanism because delegated subnets are strictly reserved for their designated resources. The solution? Create a separate, non-delegated subnet to host private endpoints.

Private Endpoints and the Azure Private Link​

Private endpoints are the unsung heroes of secure Azure networking. Instead of exposing resources to the public Internet, private endpoints provide direct, secure, in-network IP addresses. In our example, even after successfully deploying two apps in their delegate-backed subnets, attempts to attach private endpoints to them result in errors—an intentional consequence of Azure’s segregation rules.
Imagine a private endpoint as a bridge with controlled access:
  • It represents a private IP from your vNet.
  • It’s akin to a network interface controller (NIC) created automatically, forwarding secure traffic.
  • It underpins the concept of Azure Private Link, connecting your private endpoint to the app in such a way that communication traverses the secure Azure backbone.
The key learning? When using delegated subnets, it’s crucial to have a dedicated subnet (such as a “subnet3”) solely for private endpoints. This separation not only prevents configuration errors but also aligns with the principle of least privilege, ensuring that each network component has a singular, well-defined role.

Embracing Terraform for Consistent Infrastructure Deployments​

Infrastructure as Code (IaC) tools like Terraform revolutionize the deployment process by allowing you to codify your entire network configuration. In the blog post, Terraform scripts showcase how to:
  • Create and configure storage accounts, service plans, and function apps.
  • Structure a Virtual Network with multiple subnets.
  • Update subnet configurations to include delegation for services like Azure App Service.
  • Properly separate private endpoints onto their own subnet to avert conflicts with delegated subnets.
Using Terraform not only speeds up deployment but also ensures that environments are reproducible and less prone to human error. The code snippets in the blog serve as both a tutorial and a working example of how to balance network segmentation with secure endpoint connectivity.
Consider this excerpt from the Terraform code that sets up the virtual network and delegated subnets:

resource "azurerm_virtual_network" "vnet" {
name = "dns-vnet"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = [ "10.0.0.0/16" ]
}

resource "azurerm_subnet" "subnet1" {​

name = "subnet1"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = [ "10.0.1.0/24" ]
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = [ "Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action" ]
}
}
}
This snippet highlights how delegation is configured, ensuring that each subnet can automatically enforce the correct routing and service rules. It also hints at the broader implications of network security—by codifying these configurations, you reduce misconfigurations and potential vulnerabilities.

Managing DNS and NSGs for Enhanced Security​

While subnets, endpoints, and private links form the backbone of secure network designs, no discussion would be complete without addressing Domain Name System (DNS) configurations and Network Security Groups (NSGs). Both play pivotal roles:
  • Private DNS: When connecting private endpoints to your applications, associating them with a Private DNS zone can streamline the routing process. It ensures that DNS resolution within the vNet directs traffic to the correct private IP addresses.
  • NSGs: These control network traffic to and from Azure resources. By combining NSGs with dedicated subnets, you enforce granular rules that filter both inbound and outbound traffic.
The blog touches on how these elements integrate into the overall architecture. When misconfigured, you risk leaving entry points open or inadvertently blocking traffic between trusted services. The solution lies in a balanced approach: leveraging NSGs to enforce policy while utilizing Private DNS to maintain connectivity among segregated services.

Balancing Security with Functionality​

An underlying theme throughout the discussion is the balancing act between security and functionality. It’s one thing to secure your application, but it’s another to ensure that these security measures do not hinder the core operations of your services. Delegated subnets and private endpoints are designed precisely with this balance in mind. However, when these features collide—as seen when trying to mix delegated subnets and private endpoints—the solution is to enforce proper architectural boundaries.
The recommended approach is simple:
  • Use service-specific subnets (with delegation) for resources like Azure Function Apps.
  • Configure a separate subnet exclusively for private endpoints to facilitate secure connections.
  • Integrate Terraform to codify these best practices, ensuring consistency across deployments.
It begs the question: Have you ever tried patching together network security features only to find them conflicting? The answer is a resounding yes for many administrators during the early days of Azure adoption. By learning from these documented practices, you can avoid common pitfalls and ensure that security measures do not inadvertently become a roadblock.

Real-World Implications and Best Practices​

Deploying apps securely in Azure is not just about the initial configuration—it has lasting impacts on operational efficiency and security posture. A well-segmented network means:
  • Reduced attack surfaces: If one segment is compromised, the blast radius is contained.
  • Simplified management: Isolated subnets mean troubleshooting and maintenance are more straightforward.
  • Compliance readiness: Many regulatory frameworks require strict network segmentation for sensitive data.
Furthermore, when applying these configurations using Terraform, you benefit from version control and reproducibility. This is critical when rolling out updates or scaling out resources.
A few salient best practices drawn from the discussion include:
  • Always segregate delegated resources from private endpoints by using separate subnets.
  • Use Private DNS and NSGs to manage intra-network traffic effectively.
  • Validate your configurations with small-scale tests before large-scale deployments.
  • Keep abreast of Azure’s evolving documentation and updates, as Microsoft frequently enhances security features and guidelines.

Conclusion​

In a cloud-first world, the subtle art of securing application networks in Azure demands a thoughtful synthesis of multiple components. From segregating services in dedicated subnets and configuring delegation to deploying private endpoints and enforcing policies with NSGs, every decision contributes to a robust security model. Leveraging tools like Terraform not only simplifies these processes but also ensures that your infrastructure is built on a foundation of consistency and best practices.
As illustrated in the detailed blog post, a security-conscious design requires planning for every scenario—from preventing IP conflicts to ensuring that network rules do not inadvertently block legitimate traffic. If you’re looking to bolster your Azure architecture, consider revisiting your network segmentation policies, reevaluating your subnet delegations, and ensuring that your private endpoints are isolated appropriately.
In the realm of Azure network security, every detail counts. Have you rethought your Azure networking strategy lately? With evolving threats on the horizon and new Azure features being introduced regularly, now is always the right time to assess, adapt, and secure your cloud infrastructure.

Source: Medium
 
Last edited: