This module provides a high-level TypeScript construct for managing Azure Virtual Networks using the Terraform CDK and Azure AZAPI provider.
- Multiple API Version Support: Automatically supports the 3 most recent stable API versions (2025-01-01, 2024-10-01, 2024-07-01)
- Automatic Version Resolution: Uses the latest API version by default
- Version Pinning: Lock to a specific API version for stability
- Type-Safe: Full TypeScript support with comprehensive interfaces
- JSII Compatible: Can be used from TypeScript, Python, Java, and C#
- Terraform Outputs: Automatic creation of outputs for easy reference
- Tag Management: Built-in methods for managing resource tags
| Version | Status | Release Date | Notes |
|---|---|---|---|
| 2025-01-01 | Active (Latest) | 2025-01-01 | Recommended for new deployments |
| 2024-10-01 | Active | 2024-10-01 | Enhanced performance and reliability |
| 2024-07-01 | Active | 2024-07-01 | Stable release with core features |
This module is part of the @microsoft/terraform-cdk-constructs package.
npm install @microsoft/terraform-cdk-constructsimport { App, TerraformStack } from "cdktf";
import { AzapiProvider } from "@microsoft/terraform-cdk-constructs/core-azure";
import { ResourceGroup } from "@microsoft/terraform-cdk-constructs/azure-resourcegroup";
import { VirtualNetwork } from "@microsoft/terraform-cdk-constructs/azure-virtualnetwork";
const app = new App();
const stack = new TerraformStack(app, "virtual-network-stack");
// Configure the Azure provider
new AzapiProvider(stack, "azapi", {});
// Create a resource group
const resourceGroup = new ResourceGroup(stack, "rg", {
name: "my-resource-group",
location: "eastus",
});
// Create a virtual network
const vnet = new VirtualNetwork(stack, "vnet", {
name: "my-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
tags: {
environment: "production",
project: "networking",
},
});
app.synth();const vnet = new VirtualNetwork(stack, "vnet-custom-dns", {
name: "vnet-with-dns",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
dhcpOptions: {
dnsServers: ["10.0.0.4", "10.0.0.5"],
},
tags: {
environment: "production",
},
});const vnet = new VirtualNetwork(stack, "vnet-multi-address", {
name: "vnet-multi",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16", "10.1.0.0/16"],
},
});const vnet = new VirtualNetwork(stack, "vnet-protected", {
name: "vnet-protected",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
enableDdosProtection: true,
enableVmProtection: true,
});const vnet = new VirtualNetwork(stack, "vnet-flow-timeout", {
name: "vnet-flow",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
flowTimeoutInMinutes: 20, // Valid range: 4-30 minutes
});const vnet = new VirtualNetwork(stack, "vnet-pinned", {
name: "vnet-stable",
location: "eastus",
resourceGroupId: resourceGroup.id,
apiVersion: "2024-07-01", // Pin to specific version
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
});const vnet = new VirtualNetwork(stack, "vnet", {
name: "my-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
});
// Access VNet ID for use in other resources
console.log(vnet.id); // Terraform interpolation string
console.log(vnet.resourceId); // Alias for id
// Use outputs for cross-stack references
new TerraformOutput(stack, "vnet-id", {
value: vnet.idOutput,
});const vnet = new VirtualNetwork(stack, "vnet-ignore-changes", {
name: "vnet-lifecycle",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
tags: {
managed: "terraform",
},
ignoreChanges: ["tags"], // Ignore changes to tags
});const vnet = new VirtualNetwork(stack, "vnet-tags", {
name: "vnet-tags",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: {
addressPrefixes: ["10.0.0.0/16"],
},
tags: {
environment: "production",
},
});
// Add a tag
vnet.addTag("cost-center", "engineering");
// Remove a tag
vnet.removeTag("environment");Configuration properties for the Virtual Network construct.
| Property | Type | Required | Description |
|---|---|---|---|
name |
string |
No* | Name of the virtual network. If not provided, uses the construct ID. |
location |
string |
Yes | Azure region where the VNet will be created. |
resourceGroupId |
string |
No | Resource group ID. If not provided, uses subscription scope. |
addressSpace |
VirtualNetworkAddressSpace |
Yes | Address space configuration with address prefixes. |
dhcpOptions |
VirtualNetworkDhcpOptions |
No | DHCP options including DNS servers. |
subnets |
any[] |
No | Inline subnet configurations. |
enableDdosProtection |
boolean |
No | Enable DDoS protection (default: false). |
enableVmProtection |
boolean |
No | Enable VM protection (default: false). |
encryption |
any |
No | Encryption settings for the VNet. |
flowTimeoutInMinutes |
number |
No | Flow timeout in minutes (range: 4-30). |
tags |
{ [key: string]: string } |
No | Resource tags. |
apiVersion |
string |
No | Pin to a specific API version. |
ignoreChanges |
string[] |
No | Properties to ignore during updates. |
| Property | Type | Required | Description |
|---|---|---|---|
addressPrefixes |
string[] |
Yes | Array of address prefixes in CIDR notation (e.g., ["10.0.0.0/16"]). |
| Property | Type | Required | Description |
|---|---|---|---|
dnsServers |
string[] |
No | Array of DNS server IP addresses. |
| Property | Type | Description |
|---|---|---|
id |
string |
The Azure resource ID of the VNet. |
resourceId |
string |
Alias for id. |
tags |
{ [key: string]: string } |
The tags assigned to the VNet. |
subscriptionId |
string |
The subscription ID extracted from the VNet ID. |
addressSpace |
string |
Terraform interpolation string for the address space. |
The construct automatically creates Terraform outputs:
id: The VNet resource IDname: The VNet namelocation: The VNet locationaddressSpace: The VNet address spacetags: The VNet tags
| Method | Parameters | Description |
|---|---|---|
addTag |
key: string, value: string |
Add a tag to the VNet (requires redeployment). |
removeTag |
key: string |
Remove a tag from the VNet (requires redeployment). |
Unless you have specific requirements, use the default (latest) API version:
// ✅ Recommended - Uses latest version automatically
const vnet = new VirtualNetwork(stack, "vnet", {
name: "my-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
});For production workloads, consider pinning to a specific API version:
// ✅ Production-ready - Pinned version
const vnet = new VirtualNetwork(stack, "vnet", {
name: "prod-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
apiVersion: "2024-10-01",
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
});Plan your address spaces carefully to avoid conflicts:
// ✅ Good - Non-overlapping address spaces
const hubVnet = new VirtualNetwork(stack, "hub", {
name: "hub-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
});
const spokeVnet = new VirtualNetwork(stack, "spoke", {
name: "spoke-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: { addressPrefixes: ["10.1.0.0/16"] },
});Apply consistent tags for better organization:
// ✅ Recommended - Comprehensive tagging
const vnet = new VirtualNetwork(stack, "vnet", {
name: "my-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
tags: {
environment: "production",
cost-center: "engineering",
managed-by: "terraform",
project: "network-infrastructure",
},
});Use custom DNS servers for hybrid scenarios:
// ✅ Hybrid networking setup
const vnet = new VirtualNetwork(stack, "vnet", {
name: "hybrid-vnet",
location: "eastus",
resourceGroupId: resourceGroup.id,
addressSpace: { addressPrefixes: ["10.0.0.0/16"] },
dhcpOptions: {
dnsServers: ["10.0.0.4", "10.0.0.5"], // Custom DNS servers
},
});-
Address Space Conflicts: Ensure address spaces don't overlap with existing VNets or on-premises networks.
-
API Version Errors: If you encounter API version errors, verify the version is supported (2025-01-01, 2024-10-01, or 2024-07-01).
-
Permission Issues: Ensure your Azure service principal has
Network Contributorrole or equivalent permissions.
ResourceGroup- Azure Resource GroupsSubnet- Virtual Network Subnets (coming soon)NetworkSecurityGroup- Network Security Groups (coming soon)NetworkInterface- Network Interfaces (coming soon)
Contributions are welcome! Please see the Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.