Create Azure Virtual Networks

The azure-native:network:VirtualNetwork resource, part of the Pulumi Azure Native provider, defines an Azure virtual network: its address space, subnets, and network-level features like encryption and service endpoints. This guide focuses on four capabilities: address space and subnet configuration, service endpoints for Azure platform services, subnet delegation for managed services, and network encryption.

Virtual networks require an existing resource group and may reference DDoS protection plans, service endpoint policies, or IPAM pools. The examples are intentionally small. Combine them with your own network security groups, route tables, and peering configurations.

Create a virtual network with address space

Most deployments start by defining a virtual network with an address space that establishes the IP range available for subnets and resources.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const virtualNetwork = new azure_native.network.VirtualNetwork("virtualNetwork", {
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
    flowTimeoutInMinutes: 10,
    location: "eastus",
    resourceGroupName: "rg1",
    virtualNetworkName: "test-vnet",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_network = azure_native.network.VirtualNetwork("virtualNetwork",
    address_space={
        "address_prefixes": ["10.0.0.0/16"],
    },
    flow_timeout_in_minutes=10,
    location="eastus",
    resource_group_name="rg1",
    virtual_network_name="test-vnet")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewVirtualNetwork(ctx, "virtualNetwork", &network.VirtualNetworkArgs{
			AddressSpace: &network.AddressSpaceArgs{
				AddressPrefixes: pulumi.StringArray{
					pulumi.String("10.0.0.0/16"),
				},
			},
			FlowTimeoutInMinutes: pulumi.Int(10),
			Location:             pulumi.String("eastus"),
			ResourceGroupName:    pulumi.String("rg1"),
			VirtualNetworkName:   pulumi.String("test-vnet"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var virtualNetwork = new AzureNative.Network.VirtualNetwork("virtualNetwork", new()
    {
        AddressSpace = new AzureNative.Network.Inputs.AddressSpaceArgs
        {
            AddressPrefixes = new[]
            {
                "10.0.0.0/16",
            },
        },
        FlowTimeoutInMinutes = 10,
        Location = "eastus",
        ResourceGroupName = "rg1",
        VirtualNetworkName = "test-vnet",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.VirtualNetwork;
import com.pulumi.azurenative.network.VirtualNetworkArgs;
import com.pulumi.azurenative.network.inputs.AddressSpaceArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var virtualNetwork = new VirtualNetwork("virtualNetwork", VirtualNetworkArgs.builder()
            .addressSpace(AddressSpaceArgs.builder()
                .addressPrefixes("10.0.0.0/16")
                .build())
            .flowTimeoutInMinutes(10)
            .location("eastus")
            .resourceGroupName("rg1")
            .virtualNetworkName("test-vnet")
            .build());

    }
}
resources:
  virtualNetwork:
    type: azure-native:network:VirtualNetwork
    properties:
      addressSpace:
        addressPrefixes:
          - 10.0.0.0/16
      flowTimeoutInMinutes: 10
      location: eastus
      resourceGroupName: rg1
      virtualNetworkName: test-vnet

The addressSpace property defines the CIDR blocks available to the network. Azure allocates IP addresses from these ranges to subnets and resources. The flowTimeoutInMinutes property controls how long idle TCP connections remain open before Azure closes them.

Define subnets within the virtual network

Virtual networks segment address space into subnets that isolate workloads and control routing.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const virtualNetwork = new azure_native.network.VirtualNetwork("virtualNetwork", {
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
    location: "eastus",
    resourceGroupName: "rg1",
    subnets: [{
        addressPrefix: "10.0.0.0/24",
        name: "test-1",
    }],
    virtualNetworkName: "test-vnet",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_network = azure_native.network.VirtualNetwork("virtualNetwork",
    address_space={
        "address_prefixes": ["10.0.0.0/16"],
    },
    location="eastus",
    resource_group_name="rg1",
    subnets=[{
        "address_prefix": "10.0.0.0/24",
        "name": "test-1",
    }],
    virtual_network_name="test-vnet")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewVirtualNetwork(ctx, "virtualNetwork", &network.VirtualNetworkArgs{
			AddressSpace: &network.AddressSpaceArgs{
				AddressPrefixes: pulumi.StringArray{
					pulumi.String("10.0.0.0/16"),
				},
			},
			Location:          pulumi.String("eastus"),
			ResourceGroupName: pulumi.String("rg1"),
			Subnets: network.SubnetTypeArray{
				&network.SubnetTypeArgs{
					AddressPrefix: pulumi.String("10.0.0.0/24"),
					Name:          pulumi.String("test-1"),
				},
			},
			VirtualNetworkName: pulumi.String("test-vnet"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var virtualNetwork = new AzureNative.Network.VirtualNetwork("virtualNetwork", new()
    {
        AddressSpace = new AzureNative.Network.Inputs.AddressSpaceArgs
        {
            AddressPrefixes = new[]
            {
                "10.0.0.0/16",
            },
        },
        Location = "eastus",
        ResourceGroupName = "rg1",
        Subnets = new[]
        {
            new AzureNative.Network.Inputs.SubnetArgs
            {
                AddressPrefix = "10.0.0.0/24",
                Name = "test-1",
            },
        },
        VirtualNetworkName = "test-vnet",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.VirtualNetwork;
import com.pulumi.azurenative.network.VirtualNetworkArgs;
import com.pulumi.azurenative.network.inputs.AddressSpaceArgs;
import com.pulumi.azurenative.network.inputs.SubnetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var virtualNetwork = new VirtualNetwork("virtualNetwork", VirtualNetworkArgs.builder()
            .addressSpace(AddressSpaceArgs.builder()
                .addressPrefixes("10.0.0.0/16")
                .build())
            .location("eastus")
            .resourceGroupName("rg1")
            .subnets(SubnetArgs.builder()
                .addressPrefix("10.0.0.0/24")
                .name("test-1")
                .build())
            .virtualNetworkName("test-vnet")
            .build());

    }
}
resources:
  virtualNetwork:
    type: azure-native:network:VirtualNetwork
    properties:
      addressSpace:
        addressPrefixes:
          - 10.0.0.0/16
      location: eastus
      resourceGroupName: rg1
      subnets:
        - addressPrefix: 10.0.0.0/24
          name: test-1
      virtualNetworkName: test-vnet

The subnets array carves the address space into smaller ranges. Each subnet gets a name and addressPrefix (a CIDR block within the virtual network’s address space). Resources deployed to different subnets can have different network policies and routing rules.

Enable service endpoints for Azure services

Applications that access Azure Storage, SQL Database, or other platform services can route traffic through the Azure backbone rather than the public internet.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const virtualNetwork = new azure_native.network.VirtualNetwork("virtualNetwork", {
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
    location: "eastus",
    resourceGroupName: "vnetTest",
    subnets: [{
        addressPrefix: "10.0.0.0/16",
        name: "test-1",
        serviceEndpoints: [{
            service: "Microsoft.Storage",
        }],
    }],
    virtualNetworkName: "vnet1",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_network = azure_native.network.VirtualNetwork("virtualNetwork",
    address_space={
        "address_prefixes": ["10.0.0.0/16"],
    },
    location="eastus",
    resource_group_name="vnetTest",
    subnets=[{
        "address_prefix": "10.0.0.0/16",
        "name": "test-1",
        "service_endpoints": [{
            "service": "Microsoft.Storage",
        }],
    }],
    virtual_network_name="vnet1")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewVirtualNetwork(ctx, "virtualNetwork", &network.VirtualNetworkArgs{
			AddressSpace: &network.AddressSpaceArgs{
				AddressPrefixes: pulumi.StringArray{
					pulumi.String("10.0.0.0/16"),
				},
			},
			Location:          pulumi.String("eastus"),
			ResourceGroupName: pulumi.String("vnetTest"),
			Subnets: network.SubnetTypeArray{
				&network.SubnetTypeArgs{
					AddressPrefix: pulumi.String("10.0.0.0/16"),
					Name:          pulumi.String("test-1"),
					ServiceEndpoints: network.ServiceEndpointPropertiesFormatArray{
						&network.ServiceEndpointPropertiesFormatArgs{
							Service: pulumi.String("Microsoft.Storage"),
						},
					},
				},
			},
			VirtualNetworkName: pulumi.String("vnet1"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var virtualNetwork = new AzureNative.Network.VirtualNetwork("virtualNetwork", new()
    {
        AddressSpace = new AzureNative.Network.Inputs.AddressSpaceArgs
        {
            AddressPrefixes = new[]
            {
                "10.0.0.0/16",
            },
        },
        Location = "eastus",
        ResourceGroupName = "vnetTest",
        Subnets = new[]
        {
            new AzureNative.Network.Inputs.SubnetArgs
            {
                AddressPrefix = "10.0.0.0/16",
                Name = "test-1",
                ServiceEndpoints = new[]
                {
                    new AzureNative.Network.Inputs.ServiceEndpointPropertiesFormatArgs
                    {
                        Service = "Microsoft.Storage",
                    },
                },
            },
        },
        VirtualNetworkName = "vnet1",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.VirtualNetwork;
import com.pulumi.azurenative.network.VirtualNetworkArgs;
import com.pulumi.azurenative.network.inputs.AddressSpaceArgs;
import com.pulumi.azurenative.network.inputs.SubnetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var virtualNetwork = new VirtualNetwork("virtualNetwork", VirtualNetworkArgs.builder()
            .addressSpace(AddressSpaceArgs.builder()
                .addressPrefixes("10.0.0.0/16")
                .build())
            .location("eastus")
            .resourceGroupName("vnetTest")
            .subnets(SubnetArgs.builder()
                .addressPrefix("10.0.0.0/16")
                .name("test-1")
                .serviceEndpoints(ServiceEndpointPropertiesFormatArgs.builder()
                    .service("Microsoft.Storage")
                    .build())
                .build())
            .virtualNetworkName("vnet1")
            .build());

    }
}
resources:
  virtualNetwork:
    type: azure-native:network:VirtualNetwork
    properties:
      addressSpace:
        addressPrefixes:
          - 10.0.0.0/16
      location: eastus
      resourceGroupName: vnetTest
      subnets:
        - addressPrefix: 10.0.0.0/16
          name: test-1
          serviceEndpoints:
            - service: Microsoft.Storage
      virtualNetworkName: vnet1

Service endpoints create direct routes from your subnet to Azure services. The serviceEndpoints array specifies which services (like Microsoft.Storage) can be reached via these optimized paths. Traffic stays on the Azure network, improving security and often reducing latency.

Delegate subnets to Azure services

Some Azure services require dedicated subnets with delegated control to manage their own network interfaces and routing.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const virtualNetwork = new azure_native.network.VirtualNetwork("virtualNetwork", {
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
    location: "westcentralus",
    resourceGroupName: "rg1",
    subnets: [{
        addressPrefix: "10.0.0.0/24",
        delegations: [{
            name: "myDelegation",
            serviceName: "Microsoft.Sql/managedInstances",
        }],
        name: "test-1",
    }],
    virtualNetworkName: "test-vnet",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_network = azure_native.network.VirtualNetwork("virtualNetwork",
    address_space={
        "address_prefixes": ["10.0.0.0/16"],
    },
    location="westcentralus",
    resource_group_name="rg1",
    subnets=[{
        "address_prefix": "10.0.0.0/24",
        "delegations": [{
            "name": "myDelegation",
            "service_name": "Microsoft.Sql/managedInstances",
        }],
        "name": "test-1",
    }],
    virtual_network_name="test-vnet")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewVirtualNetwork(ctx, "virtualNetwork", &network.VirtualNetworkArgs{
			AddressSpace: &network.AddressSpaceArgs{
				AddressPrefixes: pulumi.StringArray{
					pulumi.String("10.0.0.0/16"),
				},
			},
			Location:          pulumi.String("westcentralus"),
			ResourceGroupName: pulumi.String("rg1"),
			Subnets: network.SubnetTypeArray{
				&network.SubnetTypeArgs{
					AddressPrefix: pulumi.String("10.0.0.0/24"),
					Delegations: network.DelegationArray{
						&network.DelegationArgs{
							Name:        pulumi.String("myDelegation"),
							ServiceName: pulumi.String("Microsoft.Sql/managedInstances"),
						},
					},
					Name: pulumi.String("test-1"),
				},
			},
			VirtualNetworkName: pulumi.String("test-vnet"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var virtualNetwork = new AzureNative.Network.VirtualNetwork("virtualNetwork", new()
    {
        AddressSpace = new AzureNative.Network.Inputs.AddressSpaceArgs
        {
            AddressPrefixes = new[]
            {
                "10.0.0.0/16",
            },
        },
        Location = "westcentralus",
        ResourceGroupName = "rg1",
        Subnets = new[]
        {
            new AzureNative.Network.Inputs.SubnetArgs
            {
                AddressPrefix = "10.0.0.0/24",
                Delegations = new[]
                {
                    new AzureNative.Network.Inputs.DelegationArgs
                    {
                        Name = "myDelegation",
                        ServiceName = "Microsoft.Sql/managedInstances",
                    },
                },
                Name = "test-1",
            },
        },
        VirtualNetworkName = "test-vnet",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.VirtualNetwork;
import com.pulumi.azurenative.network.VirtualNetworkArgs;
import com.pulumi.azurenative.network.inputs.AddressSpaceArgs;
import com.pulumi.azurenative.network.inputs.SubnetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var virtualNetwork = new VirtualNetwork("virtualNetwork", VirtualNetworkArgs.builder()
            .addressSpace(AddressSpaceArgs.builder()
                .addressPrefixes("10.0.0.0/16")
                .build())
            .location("westcentralus")
            .resourceGroupName("rg1")
            .subnets(SubnetArgs.builder()
                .addressPrefix("10.0.0.0/24")
                .delegations(DelegationArgs.builder()
                    .name("myDelegation")
                    .serviceName("Microsoft.Sql/managedInstances")
                    .build())
                .name("test-1")
                .build())
            .virtualNetworkName("test-vnet")
            .build());

    }
}
resources:
  virtualNetwork:
    type: azure-native:network:VirtualNetwork
    properties:
      addressSpace:
        addressPrefixes:
          - 10.0.0.0/16
      location: westcentralus
      resourceGroupName: rg1
      subnets:
        - addressPrefix: 10.0.0.0/24
          delegations:
            - name: myDelegation
              serviceName: Microsoft.Sql/managedInstances
          name: test-1
      virtualNetworkName: test-vnet

The delegations array grants a service (like Microsoft.Sql/managedInstances) permission to manage network resources in the subnet. Delegated subnets can’t host other resources; they’re reserved for the specified service’s exclusive use.

Enable network traffic encryption

Azure can encrypt traffic between VMs in the same virtual network, providing an additional security layer beyond application-level encryption.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const virtualNetwork = new azure_native.network.VirtualNetwork("virtualNetwork", {
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
    encryption: {
        enabled: true,
        enforcement: azure_native.network.VirtualNetworkEncryptionEnforcement.AllowUnencrypted,
    },
    location: "eastus",
    resourceGroupName: "rg1",
    subnets: [{
        addressPrefix: "10.0.0.0/24",
        name: "test-1",
    }],
    virtualNetworkName: "test-vnet",
});
import pulumi
import pulumi_azure_native as azure_native

virtual_network = azure_native.network.VirtualNetwork("virtualNetwork",
    address_space={
        "address_prefixes": ["10.0.0.0/16"],
    },
    encryption={
        "enabled": True,
        "enforcement": azure_native.network.VirtualNetworkEncryptionEnforcement.ALLOW_UNENCRYPTED,
    },
    location="eastus",
    resource_group_name="rg1",
    subnets=[{
        "address_prefix": "10.0.0.0/24",
        "name": "test-1",
    }],
    virtual_network_name="test-vnet")
package main

import (
	network "github.com/pulumi/pulumi-azure-native-sdk/network/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := network.NewVirtualNetwork(ctx, "virtualNetwork", &network.VirtualNetworkArgs{
			AddressSpace: &network.AddressSpaceArgs{
				AddressPrefixes: pulumi.StringArray{
					pulumi.String("10.0.0.0/16"),
				},
			},
			Encryption: &network.VirtualNetworkEncryptionArgs{
				Enabled:     pulumi.Bool(true),
				Enforcement: pulumi.String(network.VirtualNetworkEncryptionEnforcementAllowUnencrypted),
			},
			Location:          pulumi.String("eastus"),
			ResourceGroupName: pulumi.String("rg1"),
			Subnets: network.SubnetTypeArray{
				&network.SubnetTypeArgs{
					AddressPrefix: pulumi.String("10.0.0.0/24"),
					Name:          pulumi.String("test-1"),
				},
			},
			VirtualNetworkName: pulumi.String("test-vnet"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var virtualNetwork = new AzureNative.Network.VirtualNetwork("virtualNetwork", new()
    {
        AddressSpace = new AzureNative.Network.Inputs.AddressSpaceArgs
        {
            AddressPrefixes = new[]
            {
                "10.0.0.0/16",
            },
        },
        Encryption = new AzureNative.Network.Inputs.VirtualNetworkEncryptionArgs
        {
            Enabled = true,
            Enforcement = AzureNative.Network.VirtualNetworkEncryptionEnforcement.AllowUnencrypted,
        },
        Location = "eastus",
        ResourceGroupName = "rg1",
        Subnets = new[]
        {
            new AzureNative.Network.Inputs.SubnetArgs
            {
                AddressPrefix = "10.0.0.0/24",
                Name = "test-1",
            },
        },
        VirtualNetworkName = "test-vnet",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.network.VirtualNetwork;
import com.pulumi.azurenative.network.VirtualNetworkArgs;
import com.pulumi.azurenative.network.inputs.AddressSpaceArgs;
import com.pulumi.azurenative.network.inputs.VirtualNetworkEncryptionArgs;
import com.pulumi.azurenative.network.inputs.SubnetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var virtualNetwork = new VirtualNetwork("virtualNetwork", VirtualNetworkArgs.builder()
            .addressSpace(AddressSpaceArgs.builder()
                .addressPrefixes("10.0.0.0/16")
                .build())
            .encryption(VirtualNetworkEncryptionArgs.builder()
                .enabled(true)
                .enforcement("AllowUnencrypted")
                .build())
            .location("eastus")
            .resourceGroupName("rg1")
            .subnets(SubnetArgs.builder()
                .addressPrefix("10.0.0.0/24")
                .name("test-1")
                .build())
            .virtualNetworkName("test-vnet")
            .build());

    }
}
resources:
  virtualNetwork:
    type: azure-native:network:VirtualNetwork
    properties:
      addressSpace:
        addressPrefixes:
          - 10.0.0.0/16
      encryption:
        enabled: true
        enforcement: AllowUnencrypted
      location: eastus
      resourceGroupName: rg1
      subnets:
        - addressPrefix: 10.0.0.0/24
          name: test-1
      virtualNetworkName: test-vnet

The encryption property enables Azure’s network encryption feature. When enabled is true, Azure encrypts VM-to-VM traffic within the network. The enforcement property controls whether unencrypted VMs are allowed (AllowUnencrypted) or blocked.

Beyond these examples

These snippets focus on specific virtual network features: address space and subnet allocation, service endpoints and subnet delegation, and network encryption and BGP communities. They’re intentionally minimal rather than full network architectures.

The examples may reference pre-existing infrastructure such as resource groups, DDoS protection plans, service endpoint policies, and IPAM pools. They focus on configuring the virtual network rather than provisioning everything around it.

To keep things focused, common virtual network patterns are omitted, including:

  • DNS server configuration (dhcpOptions)
  • DDoS protection plan association
  • Network security groups and route tables
  • Virtual network peering
  • Multiple address prefixes per subnet
  • Private endpoint policies

These omissions are intentional: the goal is to illustrate how each virtual network feature is wired, not provide drop-in network modules. See the Virtual Network resource reference for all available configuration options.

Let's create Azure Virtual Networks

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Management & Configuration
Can I manage subnets both inline and as separate resources?
No, you must choose one approach. Subnets and virtual network peerings can be managed inline (within the VirtualNetwork resource) or as standalone resources, but mixing both will cause conflicts and lead to resource deletion.
What properties can't I change after creating a virtual network?
The location, resourceGroupName, and virtualNetworkName properties are immutable and cannot be changed after creation.
How do I access different Azure API versions for VirtualNetwork?
Generate a local SDK package using the CLI command pulumi package add azure-native network [ApiVersion]. The resource supports API versions from 2018-06-01 through 2025-05-01.
Address Space & Subnets
Can I assign multiple address ranges to a single subnet?
Yes, use the addressPrefixes property (array) instead of addressPrefix (single value) to specify multiple CIDR ranges for a subnet.
How do I delegate a subnet to an Azure service?
Configure the delegations property within the subnet, specifying name and serviceName (e.g., Microsoft.Sql/managedInstances).
Can I use IPAM pools for IP address allocation?
Yes, configure ipamPoolPrefixAllocations in addressSpace or within subnet configuration, specifying the pool id and numberOfIpAddresses.
Security & Protection
What's required to enable DDoS protection on my virtual network?
Set enableDdosProtection to true and associate a DDoS protection plan using the ddosProtectionPlan property. DDoS protection requires a plan resource.
How do I enable encryption on my virtual network?
Configure the encryption property with enabled: true. You can also set enforcement to control whether unencrypted VMs are allowed (e.g., AllowUnencrypted).
Advanced Networking
How do I configure BGP communities for ExpressRoute?
Set the bgpCommunities property with virtualNetworkCommunity value in the format 12076:20000. BGP communities are sent over ExpressRoute with each route.
How do I enable service endpoints for a subnet?
Configure the serviceEndpoints property within the subnet, specifying the service (e.g., Microsoft.Storage). You can also attach service endpoint policies.
What does the flowTimeoutInMinutes property control?
The flowTimeoutInMinutes property sets the flow timeout value (in minutes) for the virtual network, controlling how long idle flows are maintained.

Using a different cloud?

Explore networking guides for other cloud providers: