Skip to content

Commit

Permalink
refactor(module/test_infrastructure): module creation and adjusted ex…
Browse files Browse the repository at this point in the history
…amples (#10)
  • Loading branch information
acelebanski authored Mar 28, 2024
1 parent 7b4e3bc commit 7f01d41
Show file tree
Hide file tree
Showing 52 changed files with 4,993 additions and 1,333 deletions.
16 changes: 12 additions & 4 deletions examples/common_vmseries/.header.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ and may present scale limitations with all traffic flowing through a single set
that occurs when traffic crosses virtual routers. This option is suitable for proof-of-concepts and smaller scale deployments
because the number of firewalls low. However, the technical integration complexity is high.

![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/8e8da6e0-afba-4bb5-b2c7-a95c7250dab3)
![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/135693994/9e330a37-3679-419a-8aa3-aa963cb4faf2)

This reference architecture consists of:

Expand All @@ -58,12 +58,20 @@ This reference architecture consists of:
- management interface
- public interface - due to use of a public Load Balancer this public IP is used mainly for outgoing traffic
- an Application Gateway, serving as a reverse proxy for incoming traffic, with a sample rule setting the XFF header properly
- _(optional)_ test workloads with accompanying infrastructure:
- 2 Spoke VNETs with Route Tables and Network Security Groups
- 2 Spoke VMs serving as WordPress-based web servers
- 2 Azure Bastion managed jump hosts

**NOTE!**
- In order to deploy the architecture without test workloads described above, empty the `test_infrastructure` map in
`example.tfvars` file.

## Prerequisites

A list of requirements might vary depending on the platform used to deploy the infrastructure but a minimum one includes:

- (in case of non cloud shell deployment) credentials and (optionally) tools required to authenticate against Azure Cloud,
- _(in case of non cloud shell deployment)_ credentials and (optionally) tools required to authenticate against Azure Cloud,
see [AzureRM provider documentation for details](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure)
- [supported](#requirements) version of [`Terraform`](<https://developer.hashicorp.com/terraform/downloads>)
- if you have not run Palo Alto NGFW images in a subscription it might be necessary to accept the license first
Expand All @@ -82,14 +90,14 @@ A list of requirements might vary depending on the platform used to deploy the i
- checkout the code locally (if you haven't done so yet)
- copy the [`example.tfvars`](./example.tfvars) file, rename it to `terraform.tfvars` and adjust it to your needs
(take a closer look at the `TODO` markers)
- (optional) authenticate to AzureRM, switch to the Subscription of your choice if necessary
- _(optional)_ authenticate to AzureRM, switch to the Subscription of your choice if necessary
- initialize the Terraform module:

```bash
terraform init
```

- (optional) plan you infrastructure to see what will be actually deployed:
- _(optional)_ plan you infrastructure to see what will be actually deployed:

```bash
terraform plan
Expand Down
249 changes: 245 additions & 4 deletions examples/common_vmseries/README.md

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions examples/common_vmseries/example.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,140 @@ vmseries = {
]
}
}

# TEST INFRASTRUCTURE

test_infrastructure = {
"app1_testenv" = {
vnets = {
"app1" = {
name = "app1-vnet"
address_space = ["10.100.0.0/25"]
hub_vnet_name = "example-transit"
network_security_groups = {
"app1" = {
name = "app1-nsg"
rules = {
web_inbound = {
name = "app1-web-allow-inbound"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_address_prefixes = ["134.238.135.14", "134.238.135.140"]
source_port_range = "*"
destination_address_prefix = "10.100.0.0/25"
destination_port_ranges = ["80", "443"]
}
}
}
}
route_tables = {
nva = {
name = "app1-rt"
routes = {
"toNVA" = {
name = "toNVA-udr"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_ip_address = "10.0.0.30"
}
}
}
}
subnets = {
"vms" = {
name = "vms-snet"
address_prefixes = ["10.100.0.0/26"]
network_security_group_key = "app1"
route_table_key = "nva"
}
"bastion" = {
name = "AzureBastionSubnet"
address_prefixes = ["10.100.0.64/26"]
}
}
}
}
spoke_vms = {
"app1_vm" = {
name = "app1-vm"
vnet_key = "app1"
subnet_key = "vms"
}
}
bastions = {
"app1_bastion" = {
name = "app1-bastion"
vnet_key = "app1"
subnet_key = "bastion"
}
}
}
"app2_testenv" = {
vnets = {
"app2" = {
name = "app2-vnet"
address_space = ["10.100.1.0/25"]
hub_vnet_name = "example-transit"
network_security_groups = {
"app2" = {
name = "app2-nsg"
rules = {
web_inbound = {
name = "app2-web-allow-inbound"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_address_prefixes = ["134.238.135.14", "134.238.135.140"]
source_port_range = "*"
destination_address_prefix = "10.100.1.0/25"
destination_port_ranges = ["80", "443"]
}
}
}
}
route_tables = {
nva = {
name = "app2-rt"
routes = {
"toNVA" = {
name = "toNVA-udr"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_ip_address = "10.0.0.30"
}
}
}
}
subnets = {
"vms" = {
name = "vms-snet"
address_prefixes = ["10.100.1.0/26"]
network_security_group_key = "app2"
route_table_key = "nva"
}
"bastion" = {
name = "AzureBastionSubnet"
address_prefixes = ["10.100.1.64/26"]
}
}
}
}
spoke_vms = {
"app2_vm" = {
name = "app2-vm"
vnet_key = "app2"
subnet_key = "vms"
}
}
bastions = {
"app2_bastion" = {
name = "app2-bastion"
vnet_key = "app2"
subnet_key = "bastion"
}
}
}
}
58 changes: 55 additions & 3 deletions examples/common_vmseries/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password
resource "random_password" "this" {
count = anytrue([
for _, v in var.vmseries : v.authentication.password == null
]) ? 1 : 0
count = anytrue([for _, v in var.vmseries : v.authentication.password == null]) ? (
anytrue([for _, v in var.test_infrastructure : v.authentication.password == null]) ? 2 : 1
) : 0

length = 16
min_lower = 16 - 4
Expand Down Expand Up @@ -390,3 +390,55 @@ module "vmseries" {
module.bootstrap,
]
}

# Create test infrastructure

locals {
test_vm_authentication = {
for k, v in var.test_infrastructure : k =>
merge(
v.authentication,
{
password = coalesce(v.authentication.password, try(random_password.this[1].result, null))
}
)
}
}

module "test_infrastructure" {
source = "../../modules/test_infrastructure"

for_each = var.test_infrastructure

resource_group_name = try(
"${var.name_prefix}${each.value.resource_group_name}", "${local.resource_group.name}-testenv"
)
region = var.region
vnets = { for k, v in each.value.vnets : k => merge(v, {
name = "${var.name_prefix}${v.name}"
hub_resource_group_name = coalesce(v.hub_resource_group_name, local.resource_group.name)
network_security_groups = { for kv, vv in v.network_security_groups : kv => merge(vv, {
name = "${var.name_prefix}${vv.name}" })
}
route_tables = { for kv, vv in v.route_tables : kv => merge(vv, {
name = "${var.name_prefix}${vv.name}" })
}
}) }
load_balancers = { for k, v in each.value.load_balancers : k => merge(v, {
name = "${var.name_prefix}${v.name}"
backend_name = coalesce(v.backend_name, "${v.name}-backend")
}) }
authentication = local.test_vm_authentication[each.key]
spoke_vms = { for k, v in each.value.spoke_vms : k => merge(v, {
name = "${var.name_prefix}${v.name}"
interface_name = "${var.name_prefix}${coalesce(v.interface_name, "${v.name}-nic")}"
disk_name = "${var.name_prefix}${coalesce(v.disk_name, "${v.name}-osdisk")}"
}) }
bastions = { for k, v in each.value.bastions : k => merge(v, {
name = "${var.name_prefix}${v.name}"
public_ip_name = "${var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip")}"
}) }

tags = var.tags
depends_on = [module.vnet]
}
27 changes: 27 additions & 0 deletions examples/common_vmseries/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,30 @@ output "bootstrap_storage_urls" {
value = length(var.bootstrap_storages) > 0 ? { for k, v in module.bootstrap : k => v.file_share_urls } : null
sensitive = true
}

output "test_vms_usernames" {
description = "Initial administrative username to use for test VMs."
value = length(var.test_infrastructure) > 0 ? {
for k, v in local.test_vm_authentication : k => v.username
} : null
}

output "test_vms_passwords" {
description = "Initial administrative password to use for test VMs."
value = length(var.test_infrastructure) > 0 ? {
for k, v in local.test_vm_authentication : k => v.password
} : null
sensitive = true
}

output "test_vms_ips" {
description = "IP Addresses of the test VMs."
value = length(var.test_infrastructure) > 0 ? { for k, v in module.test_infrastructure : k => v.vm_private_ips } : null
}

output "app_lb_frontend_ips" {
description = "IP Addresses of the load balancers."
value = length({ for k, v in var.test_infrastructure : k => v if v.load_balancers != null }) > 0 ? {
for k, v in module.test_infrastructure : k => v.frontend_ip_configs
} : null
}
Loading

0 comments on commit 7f01d41

Please sign in to comment.