Map PIPs to a Firewall in Separate Project

I deployed a hub with an Azure FW in a TF project called Hub.

I then created an App project which has a web vm with a PIP - this is a spoke to the hub.

I create the PIP in the hub rg via the app project, but it seems I cannot attach the PIP to the Azure FW since the ip_config blocks are tied to the entire firewall resource block.

Ive tried various ways to integrate the state from the hub into the app project but Im struggling to manage PIPs within the app project.

As it stands, it seems like I need to manage the PIPs within the hub project separate from the app project. This is frustrating as I would like the PIPs to be managed in the app project similar to rule collection groups.

Any ideas how I can accomplish this?

Many Thanks,

Brad

Hi @brad.sherwin,

As I understand it, you have a Terraform module for a web application. The module deploys a VM required for the app. Additionally, the app requires a dedicated Public IP to be provisioned which should be ‘attached’ to an existing Azure firewall configuration, but you desire that the Public IP is managed in the same Terraform Module as the other application resources (I suspect due to keep resources with the same lifecycle together)

So, this is a tricky one :slight_smile:

As you have stated, the azurerm_firewall resource uses the ip_configuration block to define the public IP addresses associated with the firewall (And therefore can then be referenced in firewall rules.

Unfortunately, the ip_configuration is not a sub-resource of the Azure firewall, so managing this via the AzAPI provider separately from the main firewall resource is not possible (This is often an approach that works when a sub-resource is either obfuscated by the implementation of the resource, or not supported by, the AzureRM provider.)

I can’t think of an easy (or a clever) way of getting around this to meet your use-case. I think that you are stuck with provisioning the PublicIP addresses as part of the firewall module and ‘lifecycle’ and then passing a reference to that resource to your application module. Your app module then use that in a data resource to get the information needed for the firewall rules associated with it that could still be managed in the app module - which is what I presume you are doing.

Aside from the technical Terraform challenge however, operationally, this (managing an application’s perimeter firewall rules as part of the application) seems like poor practice.
Of course - in your environment this may make perfect sense and be completely justified so this comment is not so much directly related to that but more for others that may come to this topic.
Typically there is a deliberate ‘disconnect’ between the provisioning of applications and the network security related to public traffic ingress. It may not be so important or relevant in a small org and environment where everything is created and managed by one or two people. But in a larger organisation you would typically not want those responsible for developing or provisioning applications to be able to arbitrarily change perimeter firewall rules, and would want some sort of ‘circuit breaker’ request-review-approve-configure process that ensures that what is requested is sensible and understood before allowing traffic through your perimeter.

Hope that helps (even if it is just confirming what you thought originally)

Happy Terraforming

Appreicate the reply, Im still fairly new to TF and wasnt sure if I was missing something.

Unfortuantly our app requires IP traffic so I cannot replace with a cheaper Web App FW etc. We are a small team of 3 engineers.

Regarding the deliberate disconnect of network security - which makes sense. I can still provision a seperate rule collection group with DNAT etc so they are attached to the FW yet isolated and can be safley destroyed without risk. Its just the PIP which is the blocker.

Its like Terraform need to create a new resource thats just literally maps pips azurerm_firewall_pips :grin:

I did experiment with a null_resource to run az network firewall ip-config create... which does add the IPs. But if I do go to run the hub project after, I get errors but the hub still runs on resources it can do. Not best practise for sure.

It seems the only option is to move the RCG & PIP out of the app project and move into the hub project and if any references import them.

I agree regarding the decomposition of elements of azure products into sub-resources. Unfortunately there are a few resources - such as the Azure Firewall - that for some reason don’t have this (or don’t have it fully), but many ‘newer’ resource do - which makes it a lot easier to implement scenarios such as yours.

I guess there are only so many work around :slight_smile:

Good luck and happy terraforming!

1 Like

One thing I should have picked up on here is that you mentioned you were fairly new to TF.

You may not have yet come across the requirement to have information from resources deployed by one module be consumed by another. There are a number of ways to do this, but a good approach is:

To use data resources to get the current state of a dependent resource from the cloud provider at runtime, rather than using Terraform to ‘reach’ into the stored state from another module (which is possible) to get the information.

In your instance you may have the consuming module (The web application) have an input variable that provides the name and resource group name of the public IP you want to reference for that particular instance. Then use the azurerm_public_ip data resource within that module to expose any further properties of that resource that need to be referenced within the module.

In the ‘source’ module, use outputs to expose values related to resources created within (e.g… the public IP resource group and name) and then pass these in to the input variables of the consuming module.
You will, of course, need something that wraps around this, such as a pipeline or script or even a manual configuration (e.g… copy and paste the value into a .tfvars file).
In the most simple approach the fact you are controlling both modules you probably know the resource group and name of the PIP you are interested in and could just ensure it is being passed into variables/set in the .tfvars file for each module identically.

Hope that helps.

Happy Terraforming

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.