This Terraform module provisions and manages Azure Network Security Groups (NSGs), which act as virtual firewalls to control inbound and outbound traffic for Azure resources. It supports defining detailed security rules and associating NSGs with subnets or network interfaces.
- Flexible NSG Creation: Create one or more Network Security Groups in a specified resource group and location.
- Custom Security Rules: Define granular inbound and outbound rules with support for direction, access control, protocols, and address/port filtering.
- Associations: Easily bind NSGs to subnets or network interfaces to enforce network access policies.
- Built-In Tag Support: Use Azure tags like
Internet
,VirtualNetwork
, and others for simplified rule configuration. - Diagnostics Integration: Optionally configure diagnostic settings to send NSG flow logs to a Storage Account, Event Hub, or Log Analytics Workspace.
This example demonstrates how to deploy an NSG with custom security rules and associate it with a subnet or network interface.
resource "azurerm_resource_group" "rg" {
name = "rg-nsg-example"
location = "germanywestcentral"
}
module "vnet" {
source = "CloudAstro/virtual-network/azurerm"
name = "vnet-example"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
module "snet" {
source = "CloudAstro/subnet/azurerm"
name = "snet-example"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = module.vnet.virtual_network.name
address_prefixes = ["10.0.1.0/24"]
}
module "network_security_group" {
source = "../.."
name = "nsg1"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
subnet_id = module.snet.subnet.id
security_rules = [
{
name = "Allow-HTTPS-In"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "192.168.1.0/24"
destination_address_prefix = "*"
},
{
name = "Deny-All-In"
priority = 200
direction = "Inbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
]
tags = {
environment = "Production"
owner = "example-team"
}
}
Name | Version |
---|---|
terraform | ~> 1.9.0 |
azurerm | >= 4.0.0 |
Name | Version |
---|---|
azurerm | >= 4.0.0 |
Name | Type |
---|---|
azurerm_monitor_diagnostic_setting.nsg_diag | resource |
azurerm_network_security_group.nsg | resource |
azurerm_network_security_rule.security_rules | resource |
azurerm_subnet_network_security_group_association.nsg_association | resource |
Name | Description | Type | Default | Required |
---|---|---|---|---|
location | * location - (Required) The Azure region where the resource will be created.Example Input: location = "East US" |
string |
n/a | yes |
name | * name - (Required) Specifies the name of the Network Security Group (NSG).Example Input: name = "my-security-group" |
string |
n/a | yes |
resource_group_name | * resource_group_name - (Required) Specifies the name of the Resource Group within which the Network Security Group exists.Example Input: resource_group_name = "my-resource-group" |
string |
n/a | yes |
subnet_id | * subnet_id - (Optional) The ID of the subnet to associate with the Network Security Group.Example Input: subnet_id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/my-subnet" |
string |
n/a | yes |
diagnostic_settings | * monitor_diagnostic_setting - (Optional) The monitor_diagnostic_setting block resource as defined below.* name - (Required) Specifies the name of the Diagnostic Setting. Changing this forces a new resource to be created.-> Note: If the name is set to 'service' it will not be possible to fully delete the diagnostic setting. This is due to legacy API support. * target_resource_id - (Required) The ID of an existing Resource on which to configure Diagnostic Settings. Changing this forces a new resource to be created.* eventhub_name - (Optional) Specifies the name of the Event Hub where Diagnostics Data should be sent.-> Note: If this isn't specified then the default Event Hub will be used. * eventhub_authorization_rule_id - (Optional) Specifies the ID of an Event Hub Namespace Authorization Rule used to send Diagnostics Data.-> Note: This can be sourced from the azurerm_eventhub_namespace_authorization_rule resource and is different from a azurerm_eventhub_authorization_rule resource.-> Note: At least one of eventhub_authorization_rule_id , log_analytics_workspace_id , partner_solution_id and storage_account_id must be specified.* log_analytics_workspace_id - (Optional) Specifies the ID of a Log Analytics Workspace where Diagnostics Data should be sent.-> Note: At least one of eventhub_authorization_rule_id , log_analytics_workspace_id , partner_solution_id and storage_account_id must be specified.* storage_account_id - (Optional) The ID of the Storage Account where logs should be sent.-> Note: At least one of eventhub_authorization_rule_id , log_analytics_workspace_id , partner_solution_id and storage_account_id must be specified.* log_analytics_destination_type - (Optional) Possible values are AzureDiagnostics and Dedicated . When set to Dedicated , logs sent to a Log Analytics workspace will go into resource specific tables, instead of the legacy AzureDiagnostics table.-> Note: This setting will only have an effect if a log_analytics_workspace_id is provided. For some target resource type (e.g., Key Vault), this field is unconfigurable. Please see resource types for services that use each method. Please see the documentation for details on the differences between destination types.* partner_solution_id - (Optional) The ID of the market partner solution where Diagnostics Data should be sent. For potential partner integrations, click to learn more about partner integration.-> Note: At least one of eventhub_authorization_rule_id , log_analytics_workspace_id , partner_solution_id and storage_account_id must be specified.* enabled_log - (Optional) One or more enabled_log blocks as defined below.-> Note: At least one enabled_log or metric block must be specified. At least one type of Log or Metric must be enabled.* metric - (Optional) One or more metric blocks as defined below.-> Note: At least one enabled_log or metric block must be specified.An enabled_log block supports the following:* category - (Optional) The name of a Diagnostic Log Category for this Resource.-> Note: The Log Categories available vary depending on the Resource being used. You may wish to use the azurerm_monitor_diagnostic_categories Data Source or list of service specific schemas to identify which categories are available for a given Resource.* category_group - (Optional) The name of a Diagnostic Log Category Group for this Resource.-> Note: Not all resources have category groups available. -> Note: Exactly one of category or category_group must be specified.The timeouts block allows you to specify timeouts for certain actions:* create - (Defaults to 30 minutes) Used when creating the Diagnostics Setting.* update - (Defaults to 30 minutes) Used when updating the Diagnostics Setting.* read - (Defaults to 5 minutes) Used when retrieving the Diagnostics Setting.* delete - (Defaults to 60 minutes) Used when deleting the Diagnostics Setting.Example Input: diagnostic_settings = { |
map(object({ |
null |
no |
security_rules | The following arguments are supported: * name - (Required) The name of the security rule. This needs to be unique across all Rules in the Network Security Group. Changing this forces a new resource to be created.* resource_group_name - (Required) The name of the resource group in which to create the Network Security Rule. Changing this forces a new resource to be created.* network_security_group_name - (Required) The name of the Network Security Group that we want to attach the rule to. Changing this forces a new resource to be created.* description - (Optional) A description for this rule. Restricted to 140 characters.* protocol - (Required) Network protocol this rule applies to. Possible values include Tcp , Udp , Icmp , Esp , Ah or * (which matches all).* source_port_range - (Optional) Source Port or Range. Integer or range between 0 and 65535 or * to match any. This is required if source_port_ranges is not specified.* source_port_ranges - (Optional) List of source ports or port ranges. This is required if source_port_range is not specified.* destination_port_range - (Optional) Destination Port or Range. Integer or range between 0 and 65535 or * to match any. This is required if destination_port_ranges is not specified.* destination_port_ranges - (Optional) List of destination ports or port ranges. This is required if destination_port_range is not specified.* source_address_prefix - (Optional) CIDR or source IP range or * to match any IP. Tags such as VirtualNetwork , AzureLoadBalancer and Internet can also be used. This is required if source_address_prefixes is not specified.* source_address_prefixes - (Optional) List of source address prefixes. Tags may not be used. This is required if source_address_prefix is not specified.* source_application_security_group_ids - (Optional) A List of source Application Security Group IDs* destination_address_prefix - (Optional) CIDR or destination IP range or * to match any IP. Tags such as VirtualNetwork , AzureLoadBalancer and Internet can also be used. Besides, it also supports all available Service Tags like ‘Sql.WestEurope‘, ‘Storage.EastUS‘, etc. You can list the available service tags with the CLI:shell az network list-service-tags --location westcentralus. For further information please see Azure CLI - az network list-service-tags. This is required if destination_address_prefixes is not specified.* destination_address_prefixes - (Optional) List of destination address prefixes. Tags may not be used. This is required if destination_address_prefix is not specified.* destination_application_security_group_ids - (Optional) A List of destination Application Security Group IDs* access - (Required) Specifies whether network traffic is allowed or denied. Possible values are Allow and Deny .* priority - (Required) Specifies the priority of the rule. The value can be between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule.* direction - (Required) The direction specifies if rule will be evaluated on incoming or outgoing traffic. Possible values are Inbound and Outbound .Example Input: security_rules = [ |
list(object({ |
[] |
no |
tags | * tags - (Optional) A mapping of tags to associate with the Network Security Group. Tags help categorize resources in Azure with key-value pairs for better management, organization, and cost tracking.Example Input: tags = { |
map(string) |
null |
no |
timeouts | The timeouts block allows you to specify timeouts for certain actions:* create - (Defaults to 30 minutes) Used when creating the Subnet.* update - (Defaults to 30 minutes) Used when updating the Subnet.* read - (Defaults to 5 minutes) Used when retrieving the Subnet.* delete - (Defaults to 30 minutes) Used when deleting the Subnet. |
object({ |
null |
no |
Name | Description |
---|---|
nsg | * name - The name of the Network Security Group.* resource_group_name - The name of the resource group in which the NSG is created.* location - The Azure location where the NSG exists.* id - The resource ID of the NSG.* security_rule - A list of security rules defined in this NSG.* tags - A mapping of tags assigned to the NSG.Example output: output "name" { |
No modules.
For comprehensive guidance on Azure Network Security Groups and best practices, refer to the Azure NSG documentation. This module provides flexibility in defining fine-grained security rules to control traffic to and from your Azure resources.
- Terraform AzureRM Provider –
azurerm_network_security_group
- Azure Network Security Groups Overview
- Azure Network Security Best Practices
- Carefully plan and review your NSG rules to avoid unintentionally blocking required traffic.
- Follow Azure security and compliance guidelines to ensure a robust and secure network design.
- Always validate and test your Terraform plans before applying changes to production environments.
This module is released under the Apache 2.0 License. See the LICENSE file for full details.