Skip to content

Commit 27dd6a3

Browse files
Merge pull request #469 from asudbring/ddos-firewall-template
Added terrafrom template for DDOS with azure firewall
2 parents 15480dc + a8b3bb6 commit 27dd6a3

File tree

5 files changed

+517
-0
lines changed

5 files changed

+517
-0
lines changed
Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
# Generate random name for resources
2+
resource "random_pet" "name" {
3+
length = 2
4+
}
5+
6+
# Generate secure password for VM admin
7+
resource "random_password" "admin_password" {
8+
length = 16
9+
special = true
10+
upper = true
11+
lower = true
12+
numeric = true
13+
}
14+
15+
# Resource Group
16+
resource "azurerm_resource_group" "main" {
17+
name = "${var.resource_prefix}-${random_pet.name.id}-rg"
18+
location = var.location
19+
20+
tags = {
21+
purpose = "DDoS Protection with Azure Firewall"
22+
environment = "tutorial"
23+
}
24+
}
25+
26+
# DDoS Protection Plan
27+
resource "azurerm_network_ddos_protection_plan" "main" {
28+
name = "${var.resource_prefix}-${random_pet.name.id}-ddos-plan"
29+
location = azurerm_resource_group.main.location
30+
resource_group_name = azurerm_resource_group.main.name
31+
32+
tags = {
33+
purpose = "DDoS Protection"
34+
environment = "tutorial"
35+
}
36+
}
37+
38+
# Public IP for Azure Firewall
39+
resource "azurerm_public_ip" "firewall" {
40+
name = "${var.resource_prefix}-${random_pet.name.id}-fw-pip"
41+
location = azurerm_resource_group.main.location
42+
resource_group_name = azurerm_resource_group.main.name
43+
allocation_method = "Static"
44+
sku = "Standard"
45+
domain_name_label = "${var.resource_prefix}-${random_pet.name.id}-fw"
46+
47+
ddos_protection_mode = "Enabled"
48+
ddos_protection_plan_id = azurerm_network_ddos_protection_plan.main.id
49+
50+
tags = {
51+
purpose = "Azure Firewall Public IP"
52+
environment = "tutorial"
53+
}
54+
}
55+
56+
# Public IP for Virtual Machine
57+
resource "azurerm_public_ip" "vm" {
58+
name = "${var.resource_prefix}-${random_pet.name.id}-vm-pip"
59+
location = azurerm_resource_group.main.location
60+
resource_group_name = azurerm_resource_group.main.name
61+
allocation_method = "Static"
62+
sku = "Standard"
63+
domain_name_label = "${var.resource_prefix}-${random_pet.name.id}-vm"
64+
65+
ddos_protection_mode = "Enabled"
66+
ddos_protection_plan_id = azurerm_network_ddos_protection_plan.main.id
67+
68+
tags = {
69+
purpose = "Virtual Machine Public IP"
70+
environment = "tutorial"
71+
}
72+
}
73+
74+
# Route Table for Workload Subnet
75+
resource "azurerm_route_table" "workload" {
76+
name = "${var.resource_prefix}-${random_pet.name.id}-rt-workload"
77+
location = azurerm_resource_group.main.location
78+
resource_group_name = azurerm_resource_group.main.name
79+
80+
route {
81+
name = "route-to-firewall"
82+
address_prefix = "0.0.0.0/0"
83+
next_hop_type = "VirtualAppliance"
84+
next_hop_in_ip_address = "10.1.1.4" # Azure Firewall private IP
85+
}
86+
87+
tags = {
88+
purpose = "Force traffic through Azure Firewall"
89+
environment = "tutorial"
90+
}
91+
}
92+
93+
# Virtual Network with DDoS Protection
94+
resource "azurerm_virtual_network" "main" {
95+
name = "${var.resource_prefix}-${random_pet.name.id}-vnet"
96+
location = azurerm_resource_group.main.location
97+
resource_group_name = azurerm_resource_group.main.name
98+
address_space = [var.virtual_network_address_prefix]
99+
dns_servers = ["168.63.129.16"] # Azure DNS
100+
101+
ddos_protection_plan {
102+
id = azurerm_network_ddos_protection_plan.main.id
103+
enable = true
104+
}
105+
106+
tags = {
107+
purpose = "Virtual Network with DDoS Protection"
108+
environment = "tutorial"
109+
}
110+
}
111+
112+
# Azure Firewall Subnet
113+
resource "azurerm_subnet" "firewall" {
114+
name = "AzureFirewallSubnet"
115+
resource_group_name = azurerm_resource_group.main.name
116+
virtual_network_name = azurerm_virtual_network.main.name
117+
address_prefixes = [var.azure_firewall_subnet_prefix]
118+
}
119+
120+
# Workload Subnet
121+
resource "azurerm_subnet" "workload" {
122+
name = "Workload-SN"
123+
resource_group_name = azurerm_resource_group.main.name
124+
virtual_network_name = azurerm_virtual_network.main.name
125+
address_prefixes = [var.workload_subnet_prefix]
126+
}
127+
128+
# Associate Route Table to Workload Subnet
129+
resource "azurerm_subnet_route_table_association" "workload" {
130+
subnet_id = azurerm_subnet.workload.id
131+
route_table_id = azurerm_route_table.workload.id
132+
}
133+
134+
# Firewall Policy
135+
resource "azurerm_firewall_policy" "main" {
136+
name = "${var.resource_prefix}-${random_pet.name.id}-fw-policy"
137+
resource_group_name = azurerm_resource_group.main.name
138+
location = azurerm_resource_group.main.location
139+
sku = "Standard"
140+
threat_intelligence_mode = "Alert"
141+
142+
dns {
143+
proxy_enabled = true
144+
}
145+
146+
tags = {
147+
purpose = "Azure Firewall Policy"
148+
environment = "tutorial"
149+
}
150+
}
151+
152+
# DNAT Rule Collection Group
153+
resource "azurerm_firewall_policy_rule_collection_group" "dnat" {
154+
name = "DefaultDnatRuleCollectionGroup"
155+
firewall_policy_id = azurerm_firewall_policy.main.id
156+
priority = 100
157+
158+
nat_rule_collection {
159+
name = "Dnat-Col01"
160+
priority = 200
161+
action = "Dnat"
162+
163+
rule {
164+
name = "RDPRule"
165+
protocols = ["TCP"]
166+
source_addresses = ["*"]
167+
destination_address = azurerm_public_ip.firewall.ip_address
168+
destination_ports = ["3389"]
169+
translated_address = "10.1.2.4"
170+
translated_port = "3389"
171+
}
172+
}
173+
}
174+
175+
# Network Rule Collection Group
176+
resource "azurerm_firewall_policy_rule_collection_group" "network" {
177+
name = "DefaultNetworkRuleCollectionGroup"
178+
firewall_policy_id = azurerm_firewall_policy.main.id
179+
priority = 200
180+
181+
network_rule_collection {
182+
name = "Net-Col01"
183+
priority = 200
184+
action = "Allow"
185+
186+
rule {
187+
name = "AllowWebRule"
188+
protocols = ["TCP"]
189+
source_addresses = ["10.1.2.0/24"]
190+
destination_addresses = ["*"]
191+
destination_ports = ["80", "443"]
192+
}
193+
}
194+
195+
depends_on = [azurerm_firewall_policy_rule_collection_group.dnat]
196+
}
197+
198+
# Application Rule Collection Group
199+
resource "azurerm_firewall_policy_rule_collection_group" "application" {
200+
name = "DefaultApplicationRuleCollectionGroup"
201+
firewall_policy_id = azurerm_firewall_policy.main.id
202+
priority = 300
203+
204+
application_rule_collection {
205+
name = "App-Col01"
206+
priority = 200
207+
action = "Allow"
208+
209+
rule {
210+
name = "AllowWebsitesRule"
211+
source_addresses = ["10.1.2.0/24"]
212+
destination_fqdns = ["www.google.com", "www.microsoft.com", "www.bing.com"]
213+
214+
protocols {
215+
type = "Http"
216+
port = 80
217+
}
218+
219+
protocols {
220+
type = "Https"
221+
port = 443
222+
}
223+
}
224+
}
225+
226+
depends_on = [azurerm_firewall_policy_rule_collection_group.network]
227+
}
228+
229+
# Azure Firewall
230+
resource "azurerm_firewall" "main" {
231+
name = "${var.resource_prefix}-${random_pet.name.id}-fw"
232+
location = azurerm_resource_group.main.location
233+
resource_group_name = azurerm_resource_group.main.name
234+
sku_name = "AZFW_VNet"
235+
sku_tier = "Standard"
236+
threat_intel_mode = "Alert"
237+
firewall_policy_id = azurerm_firewall_policy.main.id
238+
239+
ip_configuration {
240+
name = "FW-config"
241+
subnet_id = azurerm_subnet.firewall.id
242+
public_ip_address_id = azurerm_public_ip.firewall.id
243+
}
244+
245+
tags = {
246+
purpose = "Azure Firewall with DDoS Protection"
247+
environment = "tutorial"
248+
}
249+
250+
depends_on = [azurerm_firewall_policy_rule_collection_group.application]
251+
}
252+
253+
# Network Interface for Virtual Machine
254+
resource "azurerm_network_interface" "vm" {
255+
name = "${var.resource_prefix}-${random_pet.name.id}-vm-nic"
256+
location = azurerm_resource_group.main.location
257+
resource_group_name = azurerm_resource_group.main.name
258+
259+
ip_configuration {
260+
name = "ipconfig1"
261+
subnet_id = azurerm_subnet.workload.id
262+
private_ip_address_allocation = "Static"
263+
private_ip_address = "10.1.2.4"
264+
public_ip_address_id = azurerm_public_ip.vm.id
265+
}
266+
267+
tags = {
268+
purpose = "Virtual Machine Network Interface"
269+
environment = "tutorial"
270+
}
271+
}
272+
273+
# Virtual Machine
274+
resource "azurerm_windows_virtual_machine" "main" {
275+
name = "${var.resource_prefix}-${substr(random_pet.name.id, 0, 6)}-vm" # Limit to 15 chars total
276+
computer_name = "${substr(var.resource_prefix, 0, 6)}-vm" # Explicitly set computer name to 9 chars max
277+
location = azurerm_resource_group.main.location
278+
resource_group_name = azurerm_resource_group.main.name
279+
size = var.vm_size
280+
admin_username = var.admin_username
281+
admin_password = random_password.admin_password.result
282+
283+
network_interface_ids = [
284+
azurerm_network_interface.vm.id,
285+
]
286+
287+
os_disk {
288+
name = "${var.resource_prefix}-${random_pet.name.id}-vm-osdisk"
289+
caching = "ReadWrite"
290+
storage_account_type = "Premium_LRS"
291+
disk_size_gb = 128
292+
}
293+
294+
source_image_reference {
295+
publisher = "MicrosoftWindowsServer"
296+
offer = "WindowsServer"
297+
sku = "2019-datacenter-gensecond"
298+
version = "latest"
299+
}
300+
301+
additional_capabilities {
302+
ultra_ssd_enabled = false
303+
}
304+
305+
boot_diagnostics {
306+
storage_account_uri = null # Uses managed storage account
307+
}
308+
309+
tags = {
310+
purpose = "Test Virtual Machine"
311+
environment = "tutorial"
312+
}
313+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
output "resource_group_name" {
2+
description = "Name of the resource group"
3+
value = azurerm_resource_group.main.name
4+
}
5+
6+
output "firewall_public_ip" {
7+
description = "Public IP address of the Azure Firewall"
8+
value = azurerm_public_ip.firewall.ip_address
9+
}
10+
11+
output "firewall_fqdn" {
12+
description = "FQDN of the Azure Firewall"
13+
value = azurerm_public_ip.firewall.fqdn
14+
}
15+
16+
output "vm_public_ip" {
17+
description = "Public IP address of the Virtual Machine"
18+
value = azurerm_public_ip.vm.ip_address
19+
}
20+
21+
output "vm_fqdn" {
22+
description = "FQDN of the Virtual Machine"
23+
value = azurerm_public_ip.vm.fqdn
24+
}
25+
26+
output "firewall_private_ip" {
27+
description = "Private IP address of the Azure Firewall"
28+
value = "10.1.1.4"
29+
}
30+
31+
output "virtual_network_name" {
32+
description = "Name of the virtual network"
33+
value = azurerm_virtual_network.main.name
34+
}
35+
36+
output "ddos_protection_plan_id" {
37+
description = "ID of the DDoS Protection Plan"
38+
value = azurerm_network_ddos_protection_plan.main.id
39+
}
40+
41+
output "admin_username" {
42+
description = "Admin username for the virtual machine"
43+
value = var.admin_username
44+
}
45+
46+
output "admin_password" {
47+
description = "Admin password for the virtual machine"
48+
value = random_password.admin_password.result
49+
sensitive = true
50+
}
51+
52+
output "rdp_connection_string" {
53+
description = "RDP connection string for the virtual machine"
54+
value = "mstsc /v:${azurerm_public_ip.firewall.ip_address}:3389"
55+
}
56+
57+
output "random_name_suffix" {
58+
description = "Random suffix used for resource naming"
59+
value = random_pet.name.id
60+
}

0 commit comments

Comments
 (0)