Skip to content

Commit fbbbe77

Browse files
Merge pull request #465 from asudbring/nat-firewall-template
Added terraform template for hub/spoke with firewall and nat gateway
2 parents 27dd6a3 + 13f2bd0 commit fbbbe77

File tree

6 files changed

+526
-0
lines changed

6 files changed

+526
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Hub-Spoke Network with NAT Gateway and Azure Firewall
2+
3+
This template deploys a secure hub-spoke network architecture in Azure with a NAT Gateway for outbound connectivity and Azure Firewall for traffic inspection and filtering. The solution includes Azure Bastion for secure VM access and demonstrates best practices for network segmentation and security.
4+
5+
## Architecture Overview
6+
7+
This template creates:
8+
9+
- **Hub Virtual Network**: Contains Azure Firewall, Azure Bastion, and NAT Gateway
10+
- **Spoke Virtual Network**: Contains a Linux VM for testing
11+
- **Network peering**: Connects hub and spoke networks
12+
- **Route table**: Forces spoke traffic through the firewall
13+
- **NAT Gateway**: Provides secure outbound internet access
14+
- **Azure Firewall**: Inspects and filters network traffic
15+
- **Azure Bastion**: Provides secure RDP/SSH access to VMs
16+
17+
## Terraform resource types
18+
19+
- [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet)
20+
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
21+
- [azurerm_virtual_network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network)
22+
- [azurerm_route_table](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/route_table)
23+
- [azurerm_subnet_route_table_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_route_table_association)
24+
- [azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip)
25+
- [azurerm_nat_gateway](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway)
26+
- [azurerm_nat_gateway_public_ip_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway_public_ip_association)
27+
- [azurerm_subnet_nat_gateway_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_nat_gateway_association)
28+
- [azurerm_bastion_host](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host)
29+
- [azurerm_firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall)
30+
- [azurerm_firewall_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy)
31+
- [azurerm_firewall_policy_rule_collection_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy_rule_collection_group)
32+
- [azurerm_virtual_network_peering](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network_peering)
33+
- [azurerm_network_security_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group)
34+
- [azurerm_network_interface](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface)
35+
- [azurerm_network_interface_security_group_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association)
36+
- [azurerm_linux_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine)
37+
38+
## Variables
39+
40+
| Name | Description | Default value |
41+
|-|-|-|
42+
| `location` | Location for all resources | "East US" |
43+
| `admin_username` | Admin username for the virtual machine | "azureuser" |
44+
| `admin_ssh_key` | SSH public key for the virtual machine | *Required* |
45+
46+
## Outputs
47+
48+
| Name | Description |
49+
|-|-|
50+
| `hub_vnet_id` | ID of the hub virtual network |
51+
| `spoke_vnet_id` | ID of the spoke virtual network |
52+
| `firewall_private_ip` | Private IP address of the Azure Firewall |
53+
| `nat_gateway_public_ip` | Public IP address of the NAT Gateway |
54+
| `vm_private_ip` | Private IP address of the virtual machine |
55+
| `bastion_fqdn` | FQDN of the Azure Bastion |
56+
| `resource_group_name` | Name of the resource group |
57+
| `vm_name` | Name of the virtual machine |
58+
59+
## Prerequisites
60+
61+
Before running this template, ensure you have:
62+
63+
- Azure CLI installed and configured
64+
- Terraform installed (version 1.0 or later)
65+
- An SSH public key for VM access
66+
67+
## Usage
68+
69+
1. **Generate an SSH key pair** (if you don't have one):
70+
71+
```bash
72+
ssh-keygen -t rsa -b 4096 -f ~/.ssh/azure_vm_key
73+
```
74+
75+
2. **Clone and navigate to the template**:
76+
77+
```bash
78+
git clone <repository-url>
79+
cd quickstart/301-nat-gateway-hub-spoke-firewall
80+
```
81+
82+
3. **Initialize Terraform**:
83+
84+
```bash
85+
terraform init
86+
```
87+
88+
4. **Plan the deployment**:
89+
90+
```bash
91+
terraform plan \
92+
-var 'admin_ssh_key=YOUR_SSH_PUBLIC_KEY_CONTENT'
93+
```
94+
95+
5. **Apply the configuration**:
96+
97+
```bash
98+
terraform apply \
99+
-var 'admin_ssh_key=YOUR_SSH_PUBLIC_KEY_CONTENT'
100+
```
101+
102+
Or create a `terraform.tfvars` file:
103+
104+
```hcl
105+
location = "East US"
106+
admin_username = "azureuser"
107+
admin_ssh_key = "ssh-rsa AAAAB3NzaC1yc2E..."
108+
```
109+
110+
## Network Architecture Details
111+
112+
### Address Spaces
113+
114+
- **Hub VNet**: 10.0.0.0/16
115+
- Subnet-1: 10.0.0.0/24
116+
- AzureFirewallSubnet: 10.0.1.64/26
117+
- AzureBastionSubnet: 10.0.1.0/26
118+
- **Spoke VNet**: 10.1.0.0/16
119+
- subnet-private: 10.1.0.0/24
120+
121+
### Traffic Flow
122+
123+
1. **Outbound Traffic**: VM → Route Table → Azure Firewall → NAT Gateway → Internet
124+
2. **Inbound Management**: Internet → Azure Bastion → VM
125+
3. **Inter-VNet**: Hub ↔ Spoke via VNet peering
126+
127+
### Firewall Rules
128+
129+
- Allows HTTP (80) and HTTPS (443) traffic from spoke network (10.1.0.0/24) to the internet
130+
- All other traffic is blocked by default
131+
132+
## Testing the Deployment
133+
134+
After deployment, you can test the architecture:
135+
136+
1. **Connect to the VM via Azure Bastion**:
137+
- Go to the Azure Portal
138+
- Navigate to the VM resource
139+
- Click "Connect" → "Bastion"
140+
- Use the admin username and SSH private key
141+
142+
2. **Test outbound connectivity**:
143+
144+
```bash
145+
# Test HTTP/HTTPS (should work)
146+
curl -I https://www.microsoft.com
147+
curl -I http://www.microsoft.com
148+
149+
# Test other ports (should be blocked)
150+
nc -zv 8.8.8.8 53
151+
```
152+
153+
3. **Verify NAT Gateway usage**:
154+
155+
```bash
156+
# Check your public IP (should be the NAT Gateway IP)
157+
curl ifconfig.me
158+
```
159+
160+
## Security Considerations
161+
162+
- The VM in the spoke network has no public IP address
163+
- All outbound internet traffic goes through the NAT Gateway
164+
- Azure Firewall inspects and filters traffic based on configured rules
165+
- Azure Bastion provides secure access without exposing RDP/SSH ports
166+
- Network Security Groups provide additional subnet-level protection
167+
168+
## Clean up
169+
170+
To avoid ongoing charges, delete the resources when you're done:
171+
172+
```bash
173+
terraform destroy \
174+
-var 'admin_ssh_key=YOUR_SSH_PUBLIC_KEY_CONTENT'
175+
```
176+
177+
## Next Steps
178+
179+
Consider enhancing this template by:
180+
181+
- Adding additional firewall rules for specific applications
182+
- Implementing Azure Monitor for logging and analytics
183+
- Adding more spoke networks for multi-tier applications
184+
- Integrating with Azure Key Vault for secrets management
185+
- Adding DDoS Protection for enhanced security

0 commit comments

Comments
 (0)