EDIT: Solved I was missing the output value that is needed to call that type of module value. Thanks @apparentlymart
I’m using the following repo to make a template for some Palo firewalls, I had to change some things in the module to make it work with my environment, mostly naming. terraform/fw_common.tf at master · wwce/terraform · GitHub
Error Message:
on main.tf line 87, in module "common_intlb":
│ 87: network_interface_ids = module.common_fw.network_interface_id[2]
│ ├────────────────
│ │ module.common_fw is a object, known only after apply
│
│ This object does not have an attribute named "network_interface_id".
Here is my fw_commom.tf:
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "lower_palo_rg" {
name = var.lowerPaloRG
location = var.location
tags = {
"Environment" = var.environment,
"DeployedBy" = "Terraform",
"OwnerEmail" = "Codymalloy@amrock.com",
"OwningTeam" = "Infrared",
"Application" = var.application
}
}
resource "azurerm_storage_account" "main" {
name = var.storageAccountName
resource_group_name = var.lowerPaloRG
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
}
module "common_fw" {
source = "./modules/vm-series/"
#name might need to be indexed in the actual modele and not here - prints as vm1 and vm2 in 'terraform plan
#so it's very likley this logic is actuall already set here, just need to chagne from 'vm' to '0' so we get '-01' and not '-vm1'
name = "${var.fw_prefix}-0"
resource_group_name = var.lowerPaloRG
location = var.location
vm_count = 2
username = var.fw_username
password = var.fw_password
panos = var.fw_panos
license = var.fw_license
avset_name = var.avSetName
subnet_mgmt = var.subnet_mgmt_id
subnet_untrust = var.subnet_untrust_id
subnet_trust = var.subnet_trust_id
#Enable but have NSG
nic0_public_ip = false
nic1_public_ip = false
nic2_public_ip = false
// nic1_backend_pool_id = [module.common_extlb.backend_pool_id]
// nic2_backend_pool_id = [module.common_intlb.backend_pool_id]
mgmtNSGname = var.mgmtNSGname
dataNSGname = var.dataNSGname
pipNicName = var.pipNicName
storageUri = azurerm_storage_account.main.primary_blob_endpoint
nsg_prefix = var.mgmtIngressNSGAddress
public_ip_address_allocation = "static"
nicName = var.nicName
untrustNicName = var.untrustNicName
trustNicName = var.trustNicName
mgmtNicName = var.mgmtNicName
}
module "common_extlb" {
source = "./modules/lb/"
name = var.extLbName
resource_group_name = var.lowerPaloRG
location = var.location
type = "public"
sku = "Standard"
probe_ports = [443]
frontend_ports = [443]
backend_ports = [443]
protocol = "Tcp"
network_interface_ids = module.common_fw.nic1_id
}
module "common_intlb" {
source = "./modules/lb/"
name = var.intLbName
resource_group_name = var.lowerPaloRG
location = var.location
type = "private"
sku = "Standard"
probe_ports = [443]
frontend_ports = ["All"]
backend_ports = ["All"]
protocol = "All"
subnet_id = var.subnet_trust_id
private_ip_address = var.intLbStaticIP
network_interface_ids = module.common_fw.nic2_id
}
Here is the module:
#-----------------------------------------------------------------------------------------------------------------
# Create NSGs for firewall dataplane interfaces (required for Standard SKU LB)
resource "azurerm_network_security_group" "mgmt" {
name = var.mgmtNSGname
location = var.location
resource_group_name = var.resource_group_name
security_rule {
name = "mgmt-inbound"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_ranges = ["443", "22"]
source_address_prefix = var.nsg_prefix
destination_address_prefix = "*"
}
}
resource "azurerm_network_security_group" "data" {
name = var.dataNSGname
location = var.location
resource_group_name = var.resource_group_name
security_rule {
name = "data-inbound"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "data-outbound"
priority = 1000
direction = "Outbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
#-----------------------------------------------------------------------------------------------------------------
# Create public IPs for firewall's management & dataplane1 interface
resource "azurerm_public_ip" "nic0" {
count = var.nic0_public_ip ? var.vm_count : 0
name = "${var.pipNicName}-01"
location = var.location
resource_group_name = var.resource_group_name
allocation_method = var.public_ip_address_allocation
sku = var.sku
}
resource "azurerm_public_ip" "nic1" {
count = var.nic1_public_ip ? var.vm_count : 0
name = "${var.pipNicName}-01"
location = var.location
resource_group_name = var.resource_group_name
allocation_method = var.public_ip_address_allocation
sku = var.sku
}
resource "azurerm_public_ip" "nic2" {
count = var.nic2_public_ip ? var.vm_count : 0
name = "${var.pipNicName}-01"
location = var.location
resource_group_name = var.resource_group_name
allocation_method = var.public_ip_address_allocation
sku = var.sku
}
#-----------------------------------------------------------------------------------------------------------------
# Create firewall interfaces (mgmt, data1, data2). Dynamic interface is created first, then IP is set statically.
resource "azurerm_network_interface" "nic0" {
count = var.vm_count
name = var.mgmtNicName
location = var.location
resource_group_name = var.resource_group_name
ip_configuration {
name = "ipconfig1"
subnet_id = var.subnet_mgmt
private_ip_address_allocation = "Dynamic"
public_ip_address_id = var.nic0_public_ip ? element(concat(azurerm_public_ip.nic0.*.id, [""]), count.index) : ""
}
}
resource "azurerm_network_interface" "nic1" {
count = var.vm_count
name = var.untrustNicName
location = var.location
resource_group_name = var.resource_group_name
enable_ip_forwarding = true
ip_configuration {
name = "ipconfig1"
subnet_id = var.subnet_untrust
private_ip_address_allocation = "Dynamic"
public_ip_address_id = var.nic1_public_ip ? element(concat(azurerm_public_ip.nic1.*.id, [""]), count.index) : ""
}
}
resource "azurerm_network_interface" "nic2" {
count = var.vm_count
name = var.trustNicName
location = var.location
resource_group_name = var.resource_group_name
enable_ip_forwarding = true
ip_configuration {
name = "ipconfig1"
subnet_id = var.subnet_trust
private_ip_address_allocation = "Dynamic"
public_ip_address_id = var.nic2_public_ip ? element(concat(azurerm_public_ip.nic2.*.id, [""]), count.index) : ""
}
}
resource "azurerm_network_interface_security_group_association" "nic0" {
count = var.vm_count
network_interface_id = element(azurerm_network_interface.nic0.*.id, count.index)
network_security_group_id = azurerm_network_security_group.mgmt.id
}
resource "azurerm_network_interface_security_group_association" "nic1" {
count = var.vm_count
network_interface_id = element(azurerm_network_interface.nic1.*.id, count.index)
network_security_group_id = azurerm_network_security_group.data.id
}
resource "azurerm_network_interface_security_group_association" "nic2" {
count = var.vm_count
network_interface_id = element(azurerm_network_interface.nic2.*.id, count.index)
network_security_group_id = azurerm_network_security_group.data.id
}
#-----------------------------------------------------------------------------------------------------------------
# Create VM-Series NGFWs
resource "azurerm_availability_set" "default" {
name = var.avset_name
location = var.location
resource_group_name = var.resource_group_name
platform_fault_domain_count = var.avset_fault_domain_count
managed = true
}
resource "azurerm_virtual_machine" "vmseries" {
count = var.vm_count
name = "${var.name}${count.index + 1}"
location = var.location
resource_group_name = var.resource_group_name
vm_size = var.size
primary_network_interface_id = element(azurerm_network_interface.nic0.*.id, count.index)
network_interface_ids = [
element(azurerm_network_interface.nic0.*.id, count.index),
element(azurerm_network_interface.nic1.*.id, count.index),
element(azurerm_network_interface.nic2.*.id, count.index),
]
availability_set_id = azurerm_availability_set.default.id
os_profile_linux_config {
disable_password_authentication = false
}
plan {
name = var.license
publisher = "paloaltonetworks"
product = "vmseries-flex"
}
storage_image_reference {
publisher = "paloaltonetworks"
offer = "vmseries-flex"
sku = var.license
version = var.panos
}
storage_os_disk {
name = "${var.name}${count.index + 1}-osdisk"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "${var.name}${count.index + 1}"
admin_username = var.username
admin_password = var.password
}
boot_diagnostics {
enabled = true
storage_uri = var.storageUri
}
}