Skip to content

Commit 3e9d728

Browse files
authored
Merge pull request #1 from kumarvna/develop
final configuration for version 1.0
2 parents 823c567 + dff40c0 commit 3e9d728

File tree

9 files changed

+280
-61
lines changed

9 files changed

+280
-61
lines changed

README.md

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,130 @@
1-
# terraform-azurerm-nat-gateway
2-
Terraform module to create Azure NAT Gateway to provide source network address translation (SNAT) for a subnet.
1+
# Azure NAT Gateway Terraform Module
2+
3+
Virtual Network NAT (network address translation) simplifies outbound-only Internet connectivity for virtual networks. When configured on a subnet, all outbound connectivity uses your specified static public IP addresses. Outbound connectivity is possible without load balancer or public IP addresses directly attached to virtual machines.
4+
5+
This terraform module quickly deploys azure NAT Gateway instance with the assiociation with Public IP, Public IP prefix and with a Subnet within a Virtual Network.
6+
7+
> NAT is regional by default. When creating availability zones scenarios, NAT can be isolated in a specific zone (zonal deployment).
8+
9+
## Module Usage
10+
11+
```hcl
12+
# Azurerm Provider configuration
13+
provider "azurerm" {
14+
features {}
15+
}
16+
17+
module "nat-gateway" {
18+
source = "kumarvna/nat-gateway/azurerm"
19+
version = "1.0.0"
20+
21+
# By default, this module will not create a resource group. Location will be same as existing RG.
22+
# proivde a name to use an existing resource group, specify the existing resource group name,
23+
# set the argument to `create_resource_group = true` to create new resrouce group.
24+
# # The Subnet must have the name `AzureFirewallSubnet` and the subnet mask must be at least a /26
25+
resource_group_name = "rg-shared-westeurope-01"
26+
location = "westeurope"
27+
28+
# Azure NAT Gateway and associated public IP, ip-prefix, subnets specificationscount
29+
# Regional or zone isolation with availability zones is supported
30+
nat_gateway = {
31+
testnatgateway-zone1 = {
32+
availability_zone = ["1"]
33+
public_ip_prefix_length = 30
34+
idle_timeout_in_minutes = 10
35+
subnet_id = var.subnet_id
36+
},
37+
testnatgateway-zone2 = {
38+
availability_zone = ["2"]
39+
public_ip_prefix_length = 30
40+
idle_timeout_in_minutes = 10
41+
subnet_id = var.subnet_id
42+
}
43+
}
44+
45+
# Adding TAG's to your Azure resources
46+
tags = {
47+
ProjectName = "demo-internal"
48+
Env = "dev"
49+
Owner = "user@example.com"
50+
BusinessUnit = "CORP"
51+
ServiceClass = "Gold"
52+
}
53+
}
54+
55+
```
56+
57+
## **`nat_gateway`** - NAT gateway configuration
58+
59+
This object to help set up the various settings for Azure NAT Gateway and supports following arguments.
60+
61+
| Argument | Description |
62+
|--|--|
63+
`public_ip_prefix_length`|Specifies the number of bits of the prefix. The value can be set between `0` (4,294,967,296 addresses) and `31` (2 addresses). Defaults to 30 (2 addresses).
64+
`idle_timeout_in_minutes`|The idle timeout which should be used in minutes. Defaults to `4`.
65+
`availability_zone`|A list of availability zones where the NAT Gateway, public ip and Public IP prefix should be provisioned.
66+
`subnet_id`|The ID of the Subnet within a Virtual Network
67+
68+
## Limitations
69+
70+
- NAT is compatible with standard SKU public IP, public IP prefix, and load balancer resources. Basic resources, such as basic load balancer, and any products derived from them aren't compatible with NAT. Basic resources must be placed on a subnet not configured with NAT.
71+
- IPv4 address family is supported. NAT doesn't interact with IPv6 address family. NAT can't be deployed on a subnet with an IPv6 prefix.
72+
- NAT can't span multiple virtual networks.
73+
74+
## Recommended naming and tagging conventions
75+
76+
Applying tags to your Azure resources, resource groups, and subscriptions to logically organize them into a taxonomy. Each tag consists of a name and a value pair. For example, you can apply the name `Environment` and the value `Production` to all the resources in production.
77+
For recommendations on how to implement a tagging strategy, see Resource naming and tagging decision guide.
78+
79+
>**Important** :
80+
Tag names are case-insensitive for operations. A tag with a tag name, regardless of the casing, is updated or retrieved. However, the resource provider might keep the casing you provide for the tag name. You'll see that casing in cost reports. **Tag values are case-sensitive.**
81+
82+
An effective naming convention assembles resource names by using important resource information as parts of a resource's name. For example, using these [recommended naming conventions](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging#example-names), a public IP resource for a production SharePoint workload is named like this: `pip-sharepoint-prod-westus-001`.
83+
84+
## Requirements
85+
86+
| Name | Version |
87+
|------|---------|
88+
| terraform | >= 0.13 |
89+
| azurerm | >= 2.59.0 |
90+
91+
## Providers
92+
93+
| Name | Version |
94+
|------|---------|
95+
| azurerm | >= 2.59.0 |
96+
97+
## Inputs
98+
99+
Name | Description | Type | Default
100+
---- | ----------- | ---- | -------
101+
`create_resource_group` | Whether to create resource group and use it for all networking resources | string | `"false"`
102+
`resource_group_name`|The name of an existing resource group.|string|`""`
103+
`location`|The location for all resources while creating a new resource group.|string|`""`
104+
`nat_gateway`|Manages Azure NAT Gateway also associated public IP, ip-prefix and subnets|map(object({}))|`{}`
105+
`Tags`|A map of tags to add to all resources|map|`{}`
106+
107+
## Outputs
108+
109+
|Name | Description|
110+
|---- | -----------|
111+
`resource_group_name`| The name of the resource group in which resources are created
112+
`resource_group_id`| The id of the resource group in which resources are created
113+
`resource_group_location`| The location of the resource group in which resources are created
114+
`nat_gateway_id`|The ID of the NAT Gateway
115+
`nat_gateway_resource_guid`|The resource GUID property of the NAT Gateway
116+
`azurerm_nat_gateway_public_ip_association_id`|The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP.
117+
`azurerm_nat_gateway_public_ip_prefix_association_id`|The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP Prefix.
118+
119+
## Resource Graph
120+
121+
![Resource Graph](graph.png)
122+
123+
## Authors
124+
125+
Originally created by [Kumaraswamy Vithanala](mailto:kumarvna@gmail.com).
126+
127+
## Other resources
128+
129+
- [Azure NAT Gateway](https://docs.microsoft.com/en-us/azure/virtual-network/nat-gateway/)
130+
- [Terraform AzureRM Provider Documentation](https://www.terraform.io/docs/providers/azurerm/index.html)

examples/complete/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Azure NAT Gateway Terraform Module
2+
3+
Virtual Network NAT (network address translation) simplifies outbound-only Internet connectivity for virtual networks. When configured on a subnet, all outbound connectivity uses your specified static public IP addresses. Outbound connectivity is possible without load balancer or public IP addresses directly attached to virtual machines.
4+
5+
This terraform module quickly deploys azure NAT Gateway instance with the assiociation with Public IP, Public IP prefix and with a Subnet within a Virtual Network.
6+
7+
## Module Usage
8+
9+
```hcl
10+
# Azurerm Provider configuration
11+
provider "azurerm" {
12+
features {}
13+
}
14+
15+
module "nat-gateway" {
16+
source = "kumarvna/nat-gateway/azurerm"
17+
version = "1.0.0"
18+
19+
# By default, this module will not create a resource group. Location will be same as existing RG.
20+
# proivde a name to use an existing resource group, specify the existing resource group name,
21+
# set the argument to `create_resource_group = true` to create new resrouce group.
22+
# # The Subnet must have the name `AzureFirewallSubnet` and the subnet mask must be at least a /26
23+
resource_group_name = "rg-shared-westeurope-01"
24+
location = "westeurope"
25+
26+
# Azure NAT Gateway and associated public IP, ip-prefix, subnets specificationscount
27+
# Regional or zone isolation with availability zones is supported
28+
nat_gateway = {
29+
testnatgateway-zone1 = {
30+
availability_zone = ["1"]
31+
public_ip_prefix_length = 30
32+
idle_timeout_in_minutes = 10
33+
subnet_id = var.subnet_id
34+
},
35+
testnatgateway-zone2 = {
36+
availability_zone = ["2"]
37+
public_ip_prefix_length = 30
38+
idle_timeout_in_minutes = 10
39+
subnet_id = var.subnet_id
40+
}
41+
}
42+
43+
# Adding TAG's to your Azure resources
44+
tags = {
45+
ProjectName = "demo-internal"
46+
Env = "dev"
47+
Owner = "user@example.com"
48+
BusinessUnit = "CORP"
49+
ServiceClass = "Gold"
50+
}
51+
}
52+
53+
```
54+
55+
## Terraform Usage
56+
57+
To run this example you need to execute following Terraform commands
58+
59+
```hcl
60+
terraform init
61+
terraform plan
62+
terraform apply
63+
```
64+
65+
Run `terraform destroy` when you don't need these resources.

examples/complete/main.tf

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,32 @@ provider "azurerm" {
44
}
55

66
module "nat-gateway" {
7-
// source = "kumarvna/nat-gateway/azurerm"
8-
// version = "1.0.0"
9-
source = "../../"
7+
source = "kumarvna/nat-gateway/azurerm"
8+
version = "1.0.0"
109

1110
# By default, this module will not create a resource group. Location will be same as existing RG.
1211
# proivde a name to use an existing resource group, specify the existing resource group name,
1312
# set the argument to `create_resource_group = true` to create new resrouce group.
14-
# # The Subnet must have the name `AzureFirewallSubnet` and the subnet mask must be at least a /26
1513
resource_group_name = "rg-shared-westeurope-01"
1614
location = "westeurope"
1715

16+
# Azure NAT Gateway and associated public IP, ip-prefix, subnets specificationscount
17+
# Regional or zone isolation with availability zones is supported
1818
nat_gateway = {
19-
testnatgateway1 = {
19+
testnatgateway-zone1 = {
2020
availability_zone = ["1"]
2121
public_ip_prefix_length = 30
2222
idle_timeout_in_minutes = 10
23-
subnet_id = [
24-
"/subscriptions/1e3f0eeb-2235-44cd-b3a3-dcded0861d06/resourceGroups/rg-shared-westeurope-01/providers/Microsoft.Network/virtualNetworks/vnet-shared-hub-westeurope-001/subnets/snet-management",
25-
"/subscriptions/1e3f0eeb-2235-44cd-b3a3-dcded0861d06/resourceGroups/rg-shared-westeurope-01/providers/Microsoft.Network/virtualNetworks/vnet-shared-hub-westeurope-001/subnets/snet-testnetwork1"
26-
]
23+
subnet_id = var.subnet_id
2724
},
2825
testnatgateway-zone2 = {
2926
availability_zone = ["2"]
3027
public_ip_prefix_length = 30
3128
idle_timeout_in_minutes = 10
32-
subnet_id = ["/subscriptions/1e3f0eeb-2235-44cd-b3a3-dcded0861d06/resourceGroups/rg-shared-westeurope-01/providers/Microsoft.Network/virtualNetworks/vnet-shared-hub-westeurope-001/subnets/snet-appgateway"]
29+
subnet_id = var.subnet_id
3330
}
3431
}
3532

36-
# (Optional) To enable Azure Monitoring for Azure MySQL database
37-
# (Optional) Specify `storage_account_name` to save monitoring logs to storage.
38-
#log_analytics_workspace_name = "loganalytics-we-sharedtest2"
39-
4033
# Adding TAG's to your Azure resources
4134
tags = {
4235
ProjectName = "demo-internal"

examples/complete/output.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
output "resource_group_name" {
2+
description = "The name of the resource group in which resources are created"
3+
value = module.nat-gateway.resource_group_name
4+
}
5+
6+
output "resource_group_id" {
7+
description = "The id of the resource group in which resources are created"
8+
value = module.nat-gateway.resource_group_id
9+
}
10+
11+
output "resource_group_location" {
12+
description = "The location of the resource group in which resources are created"
13+
value = module.nat-gateway.resource_group_location
14+
}
15+
16+
output "nat_gateway_id" {
17+
description = "The ID of the NAT Gateway"
18+
value = module.nat-gateway.nat_gateway_id
19+
}
20+
21+
output "nat_gateway_resource_guid" {
22+
description = "The resource GUID property of the NAT Gateway"
23+
value = module.nat-gateway.nat_gateway_resource_guid
24+
}
25+
26+
output "azurerm_nat_gateway_public_ip_association_id" {
27+
description = "The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP."
28+
value = module.nat-gateway.azurerm_nat_gateway_public_ip_association_id
29+
}
30+
31+
output "azurerm_nat_gateway_public_ip_prefix_association_id" {
32+
description = " The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP Prefix."
33+
value = module.nat-gateway.azurerm_nat_gateway_public_ip_prefix_association_id
34+
}

examples/complete/variable.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
variable "subnet_name" {
2+
description = "The name of the subnet to use in VM scale set"
3+
default = ""
4+
}

graph.png

164 KB
Loading

main.tf

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
locals {
55
resource_group_name = element(coalescelist(data.azurerm_resource_group.rgrp.*.name, azurerm_resource_group.rg.*.name, [""]), 0)
66
location = element(coalescelist(data.azurerm_resource_group.rgrp.*.location, azurerm_resource_group.rg.*.location, [""]), 0)
7-
nat_gateway_zones = { for zone in var.nat_gateway_zones : zone => true }
87
}
98

109
#---------------------------------------------------------
@@ -22,18 +21,6 @@ resource "azurerm_resource_group" "rg" {
2221
tags = merge({ "ResourceName" = format("%s", var.resource_group_name) }, var.tags, )
2322
}
2423

25-
data "azurerm_log_analytics_workspace" "logws" {
26-
count = var.log_analytics_workspace_name != null ? 1 : 0
27-
name = var.log_analytics_workspace_name
28-
resource_group_name = local.resource_group_name
29-
}
30-
31-
data "azurerm_storage_account" "storeacc" {
32-
count = var.storage_account_name != null ? 1 : 0
33-
name = var.storage_account_name
34-
resource_group_name = local.resource_group_name
35-
}
36-
3724
#--------------------------------------------
3825
# Public IP resources for Azure NAT Gateway
3926
#--------------------------------------------
@@ -90,11 +77,11 @@ resource "azurerm_nat_gateway_public_ip_prefix_association" "main" {
9077
public_ip_prefix_id = azurerm_public_ip_prefix.ng-pref[each.key].id
9178
}
9279

93-
#-----------------------------------------------------------
94-
# Association between a Nat Gateway and a Public IP Prefix.
95-
#-----------------------------------------------------------
80+
#-------------------------------------------------------------------
81+
# Associates a NAT Gateway with a Subnet within a Virtual Network.
82+
#-------------------------------------------------------------------
9683
resource "azurerm_subnet_nat_gateway_association" "main" {
9784
for_each = var.nat_gateway
9885
nat_gateway_id = azurerm_nat_gateway.main[each.key].id
99-
subnet_id = each.value
86+
subnet_id = each.value["subnet_id"]
10087
}

output.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
output "resource_group_name" {
2+
description = "The name of the resource group in which resources are created"
3+
value = element(coalescelist(data.azurerm_resource_group.rgrp.*.name, azurerm_resource_group.rg.*.name, [""]), 0)
4+
}
5+
6+
output "resource_group_id" {
7+
description = "The id of the resource group in which resources are created"
8+
value = element(coalescelist(data.azurerm_resource_group.rgrp.*.id, azurerm_resource_group.rg.*.id, [""]), 0)
9+
}
10+
11+
output "resource_group_location" {
12+
description = "The location of the resource group in which resources are created"
13+
value = element(coalescelist(data.azurerm_resource_group.rgrp.*.location, azurerm_resource_group.rg.*.location, [""]), 0)
14+
}
15+
16+
output "nat_gateway_id" {
17+
description = "The ID of the NAT Gateway"
18+
value = [for k in azurerm_nat_gateway.main : k.id]
19+
}
20+
21+
output "nat_gateway_resource_guid" {
22+
description = "The resource GUID property of the NAT Gateway"
23+
value = [for k in azurerm_nat_gateway.main : k.resource_guid]
24+
}
25+
26+
output "azurerm_nat_gateway_public_ip_association_id" {
27+
description = "The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP."
28+
value = [for k in azurerm_nat_gateway_public_ip_association.main : k.id]
29+
}
30+
31+
output "azurerm_nat_gateway_public_ip_prefix_association_id" {
32+
description = "The (Terraform specific) ID of the Association between the Nat Gateway and the Public IP Prefix."
33+
value = [for k in azurerm_nat_gateway_public_ip_prefix_association.main : k.id]
34+
}

0 commit comments

Comments
 (0)