Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Virtual network flow logs record information about IP traffic that flows through a virtual network. In this article, you use Terraform to create a virtual network flow log and a dedicated storage account for an existing virtual network. For more information, see Virtual network flow logs overview.
The Terraform configuration uses the regional Network Watcher instance that Azure creates automatically when Network Watcher is enabled. You create the flow log and storage account in the Network Watcher resource group.
Prerequisites
- An Azure account with an active subscription. Create an account for free.
- Install and configure Terraform.
- An existing virtual network. To create one, see Create a virtual network.
- Network Watcher enabled in the virtual network's region. Network Watcher is enabled by default unless you explicitly disable it.
- The
Microsoft.Insightsresource provider registered in your subscription. For more information, see Register the Insights provider. - Permissions to create a flow log and storage account in the resource group that contains the regional Network Watcher instance.
Review the Terraform configuration
You can find the sample configuration for this article in the Azure Terraform GitHub repository.
The configuration creates the following resources:
- An Azure storage account that stores flow log data.
- An Azure Network Watcher flow log that records traffic for the existing virtual network.
The configuration also uses the Network Watcher data source to reference the existing regional Network Watcher instance.
Create a directory to test the sample Terraform configuration, and make it the current directory.
Create a file named
providers.tf, and insert the following code:terraform { required_version = ">= 1.5.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 5.0" } random = { source = "hashicorp/random" version = "~> 3.7" } } } provider "azurerm" { features {} }Create a file named
main.tf, and insert the following code:data "azurerm_network_watcher" "network_watcher" { name = var.network_watcher_name resource_group_name = var.network_watcher_resource_group_name } resource "random_string" "storage_account_suffix" { length = 8 lower = true numeric = true special = false upper = false } resource "azurerm_storage_account" "flow_logs" { name = "flowlogs${random_string.storage_account_suffix.result}" resource_group_name = data.azurerm_network_watcher.network_watcher.resource_group_name location = data.azurerm_network_watcher.network_watcher.location account_tier = "Standard" account_kind = "StorageV2" account_replication_type = var.storage_account_replication_type } resource "azurerm_network_watcher_flow_log" "vnet_flow_log" { name = var.flow_log_name network_watcher_name = data.azurerm_network_watcher.network_watcher.name resource_group_name = data.azurerm_network_watcher.network_watcher.resource_group_name location = data.azurerm_network_watcher.network_watcher.location target_resource_id = var.virtual_network_id storage_account_id = azurerm_storage_account.flow_logs.id enabled = true version = var.flow_log_version retention_policy { enabled = var.retention_days > 0 days = var.retention_days } }Create a file named
variables.tf, and insert the following code:variable "network_watcher_name" { type = string default = "NetworkWatcher_eastus" description = "Name of the existing regional Network Watcher instance." } variable "network_watcher_resource_group_name" { type = string default = "NetworkWatcherRG" description = "Name of the resource group that contains the Network Watcher instance." } variable "virtual_network_id" { type = string description = "Resource ID of the existing virtual network to monitor." validation { condition = can(regex("(?i)^/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Network/virtualNetworks/[^/]+$", var.virtual_network_id)) error_message = "The virtual_network_id value must be a full Azure virtual network resource ID." } } variable "flow_log_name" { type = string default = "vnet-flow-log" description = "Name of the virtual network flow log." } variable "flow_log_version" { type = number default = 2 description = "Flow log format version. Valid values are 1 and 2." validation { condition = contains([1, 2], var.flow_log_version) error_message = "The flow_log_version value must be 1 or 2." } } variable "retention_days" { type = number default = 0 description = "Number of days to retain flow log data. Use 0 to retain data indefinitely." validation { condition = var.retention_days >= 0 && var.retention_days <= 365 error_message = "The retention_days value must be between 0 and 365." } } variable "storage_account_replication_type" { type = string default = "LRS" description = "Replication type for the flow log storage account." validation { condition = contains(["LRS", "GRS", "ZRS"], var.storage_account_replication_type) error_message = "The storage_account_replication_type value must be LRS, GRS, or ZRS." } }Create a file named
outputs.tf, and insert the following code:output "flow_log_id" { description = "Resource ID of the virtual network flow log." value = azurerm_network_watcher_flow_log.vnet_flow_log.id } output "flow_log_name" { description = "Name of the virtual network flow log." value = azurerm_network_watcher_flow_log.vnet_flow_log.name } output "storage_account_name" { description = "Name of the storage account that contains the flow log data." value = azurerm_storage_account.flow_logs.name }
Set the existing resource values
Create a file named terraform.tfvars. Replace the placeholders with values for your existing virtual network and regional Network Watcher instance.
network_watcher_name = "NetworkWatcher_eastus"
network_watcher_resource_group_name = "NetworkWatcherRG"
virtual_network_id = "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<virtual-network-name>"
The virtual network and Network Watcher instance must be in the same Azure region. If your Network Watcher instance uses a custom name or resource group, update both Network Watcher values.
Initialize Terraform
Run terraform init to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources.
terraform init -upgrade
Key points:
- The
-upgradeparameter upgrades the necessary provider plugins to the newest version that complies with the configuration's version constraints.
Create a Terraform execution plan
Run terraform plan to create an execution plan.
terraform plan -out main.tfplan
Key points:
- The
terraform plancommand creates an execution plan, but doesn't execute it. Instead, it determines what actions are necessary to create the configuration specified in your configuration files. This pattern allows you to verify whether the execution plan matches your expectations before making any changes to actual resources. - The optional
-outparameter allows you to specify an output file for the plan. Using the-outparameter ensures that the plan you reviewed is exactly what is applied.
Apply the Terraform execution plan
Run terraform apply to apply the execution plan to your cloud infrastructure.
terraform apply main.tfplan
Key points:
- The example
terraform applycommand assumes you previously ranterraform plan -out main.tfplan. - If you specified a different filename for the
-outparameter, use that same filename in the call toterraform apply. - If you didn't use the
-outparameter, callterraform applywithout any parameters.
Verify the flow log
Sign in to the Azure portal.
Search for and select Network Watcher.
Under Logs, select Flow logs.
Confirm that the flow log is enabled and that its target resource is your virtual network.
You can also display the flow log and storage account names from the Terraform outputs:
terraform output flow_log_name
terraform output storage_account_name
Clean up resources
When you no longer need the resources created via Terraform, do the following steps:
Run terraform plan and specify the
destroyflag.terraform plan -destroy -out main.destroy.tfplanKey points:
- The
terraform plancommand creates an execution plan, but doesn't execute it. Instead, it determines what actions are necessary to create the configuration specified in your configuration files. This pattern allows you to verify whether the execution plan matches your expectations before making any changes to actual resources. - The optional
-outparameter allows you to specify an output file for the plan. Using the-outparameter ensures that the plan you reviewed is exactly what is applied.
- The
Run terraform apply to apply the execution plan.
terraform apply main.destroy.tfplan
The destroy operation deletes the flow log and the storage account created by this configuration. It doesn't delete the existing virtual network or Network Watcher instance.
Troubleshoot Terraform on Azure
Troubleshoot common problems when using Terraform on Azure