Skip to content

This Terraform module is used to create firewall resource on AZURE. AZURE Firewall is a managed network security service provided by Microsoft Azure.

License

Notifications You must be signed in to change notification settings

clouddrove/terraform-azure-firewall

Terraform AZURE FIREWALL

Terraform module to create firewall resource on AZURE.

Terraform Licence


We eat, drink, sleep and most importantly love DevOps. We are working towards strategies for standardizing architecture while ensuring security for the infrastructure. We are strong believer of the philosophy Bigger problems are always solved by breaking them into smaller manageable problems. Resonating with microservices architecture, it is considered best-practice to run database, cluster, storage in smaller connected yet manageable pieces within the infrastructure.

This module is basically combination of Terraform open source and includes automatation tests and examples. It also helps to create and improve your infrastructure with minimalistic code instead of maintaining the whole infrastructure code yourself.

We have fifty plus terraform modules. A few of them are comepleted and are available for open source usage while a few others are in progress.

Prerequisites

This module has a few dependencies:

Examples

IMPORTANT: Since the master branch used in source varies based on new modifications, we suggest that you use the release versions here.

Simple Example

Here is an example of how you can use this module in your inventory structure:

Default example

  module "firewall" {
    depends_on           = [module.name_specific_subnet]
    source               = "clouddrove/firewall/azure"
    name                = "app"
    environment         = "test"
    resource_group_name = module.resource_group.resource_group_name
    location            = module.resource_group.resource_group_location
    subnet_id           = module.name_specific_subnet.specific_subnet_id[0]
    public_ip_names     = ["ingress", "vnet"] // Name of public ips you want to create.

    # additional_public_ips = [{
    # name = "public-ip_name",
    # public_ip_address_id = "public-ip_resource_id"
    #   } ]
    firewall_enable            = true
    policy_rule_enabled        = true
    enable_diagnostic          = true
    log_analytics_workspace_id = module.log-analytics.workspace_id

    application_rule_collection = [
      {
        name     = "example_app_policy"
        priority = 200
        action   = "Allow"
        rules = [
          {
            name              = "app_test"
            source_addresses  = ["*"] // ["X.X.X.X"]
            destination_fqdns = ["*"] // ["X.X.X.X"]
            protocols = [
              {
                port = "443"
                type = "Https"
              },
              {
                port = "80"
                type = "Http"
              }
            ]
          }
        ]
      }
    ]

    network_rule_collection = [
      {
        name     = "example_network_policy"
        priority = "100"
        action   = "Allow"
        rules = [
          {
            name                  = "ssh"
            protocols             = ["TCP"]
            source_addresses      = ["*"] // ["X.X.X.X"]
            destination_addresses = ["*"] // ["X.X.X.X"]
            destination_ports     = ["22"]
          }

        ]
      },
      {
        name     = "example_network_policy-2"
        priority = "101"
        action   = "Allow"
        rules = [
          {
            name                  = "smtp"
            protocols             = ["TCP"]
            source_addresses      = ["*"] // ["X.X.X.X"]
            destination_addresses = ["*"] // ["X.X.X.X"]
            destination_ports     = ["587"]
          }
        ]
      }
    ]

    nat_rule_collection = [
      {
        name     = "example_nat_policy-1"
        priority = "101"
        rules = [
          {
            name                = "http"
            protocols           = ["TCP"]
            source_addresses    = ["*"] // ["X.X.X.X"]
            destination_ports   = ["80"]
            source_addresses    = ["*"]
            translated_port     = "80"
            translated_address  = "X.X.X.X"                            #provide private ip address to translate
            destination_address = module.firewall.public_ip_address[1] //Public ip associated with firewall. Here index 1 indicates 'vnet ip' (from public_ip_names     = ["ingress" , "vnet"])

          },
          {
            name                = "https"
            protocols           = ["TCP"]
            destination_ports   = ["443"]
            source_addresses    = ["*"]
            translated_port     = "443"
            translated_address  = "X.X.X.X"                            #provide private ip address to translate
            destination_address = module.firewall.public_ip_address[1] //Public ip associated with firewall

          }
        ]
      },

      {
        name     = "example-nat-policy-2"
        priority = "100"
        rules = [
          {
            name                = "http"
            protocols           = ["TCP"]
            source_addresses    = ["*"] // ["X.X.X.X"]
            destination_ports   = ["80"]
            translated_port     = "80"
            translated_address  = "X.X.X.X"                            #provide private ip address to translate
            destination_address = module.firewall.public_ip_address[0] //Public ip associated with firewall.Here index 0 indicates 'ingress ip' (from public_ip_names     = ["ingress" , "vnet"])

          },
          {
            name                = "https"
            protocols           = ["TCP"]
            source_addresses    = ["*"] // ["X.X.X.X"]
            destination_ports   = ["443"]
            translated_port     = "443"
            translated_address  = "X.X.X.X"                            #provide private ip address to translate
            destination_address = module.firewall.public_ip_address[0] //Public ip associated with firewall
          }
        ]
      }
    ]
  }

firewall-with-isolated-rules

  module "firewall" {
  depends_on          = [module.name_specific_subnet]
  source               = "clouddrove/firewall/azure"
  name                = "app"
  environment         = "test"
  resource_group_name = module.resource_group.resource_group_name
  location            = module.resource_group.resource_group_location
  subnet_id           = module.name_specific_subnet.specific_subnet_id[0]
  public_ip_names     = ["ingress", "vnet"] // Name of public ips you want to create.

  # additional_public_ips = [{
  # name = "public-ip_name",
  # public_ip_address_id = "public-ip_resource_id"
  #   } ]
  firewall_enable            = true
  enable_diagnostic          = true
  log_analytics_workspace_id = module.log-analytics.workspace_id

}
module "firewall-rules" {
  depends_on         = [module.firewall]
  source             = "clouddrove/firewall/azure"
  name               = "app"
  environment        = "test"
  policy_rule_enabled= true
  firewall_policy_id = module.firewall.firewall_policy_id

  application_rule_collection = [
    {
      name     = "example_app_policy"
      priority = 200
      action   = "Allow"
      rules = [
        {
          name              = "app_test"
          source_addresses  = ["*"] // ["X.X.X.X"]
          destination_fqdns = ["*"] // ["X.X.X.X"]
          protocols = [
            {
              port = "443"
              type = "Https"
            },
            {
              port = "80"
              type = "Http"
            }
          ]
        }
      ]
    }
  ]

  network_rule_collection = [
    {
      name     = "example_network_policy"
      priority = "100"
      action   = "Allow"
      rules = [
        {
          name                  = "ssh"
          protocols             = ["TCP"]
          source_addresses      = ["*"] // ["X.X.X.X"]
          destination_addresses = ["*"] // ["X.X.X.X"]
          destination_ports     = ["22"]
        }

      ]
    },
    {
      name     = "example_network_policy-2"
      priority = "101"
      action   = "Allow"
      rules = [
        {
          name                  = "smtp"
          protocols             = ["TCP"]
          source_addresses      = ["*"] // ["X.X.X.X"]
          destination_addresses = ["*"] // ["X.X.X.X"]
          destination_ports     = ["587"]
        }
      ]
    }
  ]

  nat_rule_collection = [
    {
      name     = "example_nat_policy-1"
      priority = "101"
      rules = [
        {
          name                = "http"
          protocols           = ["TCP"]
          source_addresses    = ["*"] // ["X.X.X.X"]
          destination_ports   = ["80"]
          source_addresses    = ["*"]
          translated_port     = "80"
          translated_address  = "10.1.1.1"                           #provide private ip address to translate
          destination_address = module.firewall.public_ip_address[1] //Public ip associated with firewall. Here index 1 indicates 'vnet ip' (from public_ip_names     = ["ingress" , "vnet"])

        },
        {
          name                = "https"
          protocols           = ["TCP"]
          destination_ports   = ["443"]
          source_addresses    = ["*"]
          translated_port     = "443"
          translated_address  = "10.1.1.1"                           #provide private ip address to translate
          destination_address = module.firewall.public_ip_address[1] //Public ip associated with firewall

        }
      ]
    },

    {
      name     = "example-nat-policy-2"
      priority = "100"
      rules = [
        {
          name                = "http"
          protocols           = ["TCP"]
          source_addresses    = ["*"] // ["X.X.X.X"]
          destination_ports   = ["80"]
          translated_port     = "80"
          translated_address  = "10.1.1.2"                           #provide private ip address to translate
          destination_address = module.firewall.public_ip_address[0] //Public ip associated with firewall.Here index 0 indicates 'ingress ip' (from public_ip_names     = ["ingress" , "vnet"])

        },
        {
          name                = "https"
          protocols           = ["TCP"]
          source_addresses    = ["*"] // ["X.X.X.X"]
          destination_ports   = ["443"]
          translated_port     = "443"
          translated_address  = "10.1.1.2"                           #provide private ip address to translate
          destination_address = module.firewall.public_ip_address[0] //Public ip associated with firewall
        }
      ]
    }
  ]
}

Inputs

Name Description Type Default Required
additional_public_ips List of additional public ips' ids to attach to the firewall.
list(object({
name = string,
public_ip_address_id = string
}))
[] no
app_policy_collection_group (optional) Name of app policy group string "DefaultApplicationRuleCollectionGroup" no
application_rule_collection One or more application_rule_collection blocks as defined below.. map {} no
days Number of days to create retension policies for te diagnosys setting. number 365 no
dnat-destination_ip Variable to specify that you have destination ip to attach to policy or not.(Destination ip is public ip that is attached to firewall) bool true no
dns_servers DNS Servers to use with Azure Firewall. Using this also activate DNS Proxy. list(string) null no
enable_diagnostic Set to false to prevent the module from creating the diagnosys setting for the NSG Resource.. bool false no
enable_ip_subnet Should subnet id be attached to first public ip name specified in public ip names variable. To be true when there is no individual public ip. bool true no
enable_prefix_subnet Should subnet id be attached to first public ip name specified in public ip prefix name varible. To be true when there is no individual public ip. bool false no
enabled Set to false to prevent the module from creating any resources. bool true no
environment Environment (e.g. prod, dev, staging). string "" no
eventhub_authorization_rule_id Eventhub authorization rule id to pass it to destination details of diagnosys setting of NSG. string null no
eventhub_name Eventhub Name to pass it to destination details of diagnosys setting of NSG. string null no
firewall_enable n/a bool false no
firewall_policy_id The ID of the Firewall Policy. string null no
firewall_private_ip_ranges A list of SNAT private CIDR IP ranges, or the special string IANAPrivateRanges, which indicates Azure Firewall does not SNAT when the destination IP address is a private range per IANA RFC 1918. list(string) null no
identity_type Specifies the type of Managed Service Identity that should be configured on this Storage Account. Possible values are SystemAssigned, UserAssigned, SystemAssigned, UserAssigned (to enable both). string "UserAssigned" no
label_order Label order, e.g. sequence of application name and environment name,environment,'attribute' [webserver,qa,devops,public,] . list(any)
[
"name",
"environment"
]
no
location The location/region where the virtual network is created. Changing this forces a new resource to be created. string "" no
log_analytics_workspace_id log analytics workspace id to pass it to destination details of diagnosys setting of NSG. string null no
managedby ManagedBy, eg ''. string "" no
name Name (e.g. app or cluster). string "" no
nat_policy_collection_group (optional) Name of nat policy group string "DefaultDnatRuleCollectionGroup" no
nat_rule_collection One or more nat_rule_collection blocks as defined below. map {} no
net_policy_collection_group (optional) Name of network policy group string "DefaultNetworkRuleCollectionGroup" no
network_rule_collection One or more network_rule_collection blocks as defined below. map {} no
policy_rule_enabled Flag used to control creation of policy rules. bool false no
prefix_public_ip_allocation_method n/a string "Static" no
prefix_public_ip_names Name of prefix public ips. list(string) [] no
prefix_public_ip_sku n/a string "Standard" no
public_ip_allocation_method Defines the allocation method for this IP address. Possible values are Static or Dynamic string "Static" no
public_ip_names n/a list(string) [] no
public_ip_prefix_enable Flag to control creation of public ip prefix resource. bool false no
public_ip_prefix_ip_version The IP Version to use, IPv6 or IPv4. Changing this forces a new resource to be created. Default is IPv4 string "IPv4" no
public_ip_prefix_length Specifies the number of bits of the prefix. The value can be set between 0 (4,294,967,296 addresses) and 31 (2 addresses). Defaults to 28(16 addresses). Changing this forces a new resource to be created. number 31 no
public_ip_prefix_sku SKU for public ip prefix. Default to standard. string "Standard" no
public_ip_sku The SKU of the Public IP. Accepted values are Basic and Standard. Defaults to Basic string "Standard" no
repository Terraform current module repo string "" no
resource_group_name A container that holds related resources for an Azure solution string "" no
retention_policy_enabled Set to false to prevent the module from creating retension policy for the diagnosys setting. bool false no
sku_name (optional) describe your variable string "AZFW_VNet" no
sku_policy Specifies the firewall-policy sku string "Standard" no
sku_tier Specifies the firewall sku tier string "Standard" no
storage_account_id Storage account id to pass it to destination details of diagnosys setting of NSG. string null no
subnet_id Subnet ID string "" no
tags A map of tags to add to all resources map(string) {} no
threat_intel_mode (Optional) The operation mode for threat intelligence-based filtering. Possible values are: Off, Alert, Deny. Defaults to Alert. string "Alert" no

Outputs

Name Description
firewall_id Firewall generated id
firewall_name Firewall name
firewall_policy_id n/a
prefix_public_ip_address n/a
prefix_public_ip_id n/a
private_ip_address Firewall private IP
public_ip_address n/a
public_ip_id n/a
public_ip_prefix_id n/a

Testing

In this module testing is performed with terratest and it creates a small piece of infrastructure, matches the output like ARN, ID and Tags name etc and destroy infrastructure in your AWS account. This testing is written in GO, so you need a GO environment in your system.

You need to run the following command in the testing folder:

  go test -run Test

Feedback

If you come accross a bug or have any feedback, please log it in our issue tracker, or feel free to drop us an email at [email protected].

If you have found it worth your time, go ahead and give us a ★ on our GitHub!

About us

At CloudDrove, we offer expert guidance, implementation support and services to help organisations accelerate their journey to the cloud. Our services include docker and container orchestration, cloud migration and adoption, infrastructure automation, application modernisation and remediation, and performance engineering.

We are The Cloud Experts!


We ❤️ Open Source and you can check out our other modules to get help with your new Cloud ideas.

About

This Terraform module is used to create firewall resource on AZURE. AZURE Firewall is a managed network security service provided by Microsoft Azure.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published