Consistent Security and performance across clouds using BIG-IP and Terraform

As reported by IDC, enterprises are increasingly considering deploying applications and services into multiple public clouds. This presents a new set of challenges: configuring virtual compute, storage, network, and middleware services on each of these clouds require cloud specific skills and configuration normalization to ensure same customer experience. In my previous blog, I went through how to configure BIG-IP as a part of your CICD pipeline using Terraform and GitHub Actions. As you might know BIG-IP Virtual Editions can be deployed in all major public cloud using Terraform. In this article, I will cover how to consistently apply configurations across BIG-IP Virtual Editions running in multi-cloud using Terraform Automation. We will use templating for AS3 and will build declarations that you can apply to BIG-IP running in any cloud using Terraform.

Environment

For this use case example, I will deploy a WAF policy on the BIG-IP devices running in AWS and Azure. BIG-IP VE instances and backend applications instances are created using the terraform scripts found here, but the following instructions will work on any cloud deployed BIG-IP VEs & applications. 

I will use an AS3 declaration which will configure a new tenant on the BIG-IP with a virtual server, a pool, and nodes. I will apply the same declaration with an associated WAF policy to virtual BIG-IP instances in AWS and Azure clouds using Terraform.

Prerequisites

1.    An AWS Account

2.    An Azure Account

3.    BIG-IP VE v14+ instance running on AWS and Azure

4.    The ASM module is licensed and activated on your BIG-IP 

5.    Terraform installed on your local or remote jump box

 

Let’s get started…

 

AS3 Declaration

Below is an example of an AS3 declaration for creating a virtual server and attaching a WAF security policy to it. At a minimum, you will need to edit the IPs to match your environment.  

 {
    "class": "AS3",
    "action": "deploy",
    "persist": true,
    "declaration": {
      "class": "ADC",
      "schemaVersion": "3.24.0",
      "id": "Protected_App",
      "My_Protected_App": {
        "class": "Tenant",
        "App": {
          "class": "Application",
          "template": "http",
          "serviceMain": {
            "class": "Service_HTTP",
            "virtualPort": 8080,
            "virtualAddresses": [
              "10.2.1.200"
            ],
            "pool": "web_pool",
            "policyWAF": {
              "use": "My_ASM_Policy"
            },
            "persistenceMethods": [],
            "profileMultiplex": {
              "bigip": "/Common/oneconnect"
            }
          },
          "web_pool": {
            "class": "Pool",
            "monitors": [
              "http"
            ],
            "members": [
              {
                  "servicePort": 80,
                  "serverAddresses": [
                      "10.2.1.101",
                      "10.2.1.102"
                  ]
              }
          ]
          },
          "My_ASM_Policy": {
            "class": "WAF_Policy",
            "url": "https://raw.githubusercontent.com/scshitole/more-terraform/master/Sample_app_sec_02_waf_policy.xml",
            "ignoreChanges": true
          }
        }
      }
    }
  }

 

Using Terraform to configure the BIG-IP

I am using terraform to deploy the AS3 declaration above, which configures the Virtual Server and attaches the ASM WAF policy. The WAF Policy URL is also declared in the AS3 as shown above.

The BIG-IP can be provisioned in Azure using the ‘terraform-Azure-bigip-module’ located at https://github.com/f5devcentral/terraform-azure-bigip-module. Once done, I use Terraform configuration below to deploy the secure application configuration using the bigip-as3 resource which is part of BIG-IP Terraform provider. Terraform configuration is located at https://github.com/scshitole/mcloud/blob/main/terraform-azure-bigip-module/examples/as3/main.tf

Example Terraform TF for Azure Cloud

provider "azurerm" {
  features {}
}


terraform {
  required_providers {
    bigip = {
      source  = "f5networks/bigip"
      version = "1.8.0"
    }
  }
}


provider "bigip" {
  address  = var.address
  username = "admin"
  password = var.password
  port     = var.port
}


resource "bigip_as3" "as3-waf" {
  as3_json = file(var.declaration)
}


resource "azurerm_network_interface" "appnic" {
  count               = var.app_count
  name                = "app_nic"
  location            = var.location
  resource_group_name = var.resource_group


  ip_configuration {
    name                          = "testConfiguration"
    subnet_id                     = var.subnet_id
    private_ip_address_allocation = "Static"
    private_ip_address            = "10.2.1.101"
  }
}

resource "azurerm_managed_disk" "appdisk" {
  name                 = "datadisk_existing_${count.index}"
  count                = var.app_count
  location             = var.location
  resource_group_name  = var.resource_group
  storage_account_type = "Standard_LRS"
  create_option        = "Empty"
  disk_size_gb         = "1023"
}

resource "azurerm_availability_set" "avset" {
  name                         = "avset"
  location                     = var.location
  resource_group_name          = var.resource_group
  platform_fault_domain_count  = 2
  platform_update_domain_count = 2
  managed                      = true
}

resource "azurerm_virtual_machine" "app" {
  count                 = var.app_count
  name                  = "app_vm_${count.index}"
  location              = var.location
  availability_set_id   = azurerm_availability_set.avset.id
  resource_group_name   = var.resource_group
  network_interface_ids = [element(azurerm_network_interface.appnic.*.id, count.index)]
  vm_size               = "Standard_DS1_v2"

  # Uncomment this line to delete the OS disk automatically when deleting the VM
  delete_os_disk_on_termination = true

  # Uncomment this line to delete the data disks automatically when deleting the VM
  delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }

  storage_os_disk {
    name              = "myosdisk${count.index}"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }


  # Optional data disks
  storage_data_disk {
    name              = "datadisk_new_${count.index}"
    managed_disk_type = "Standard_LRS"
    create_option     = "Empty"
    lun               = 0
    disk_size_gb      = "1023"
  }

  storage_data_disk {
    name            = element(azurerm_managed_disk.appdisk.*.name, count.index)
    managed_disk_id = element(azurerm_managed_disk.appdisk.*.id, count.index)
    create_option   = "Attach"
    lun             = 1
    disk_size_gb    = element(azurerm_managed_disk.appdisk.*.disk_size_gb, count.index)
  }

  os_profile {
    computer_name  = format("appserver-%s", count.index)
    admin_username = "appuser"
    admin_password = var.upassword
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  tags = {
    Name = "${var.prefix}-app"
  }
}

Example Terraform TF for AWS Cloud

The BIG-IP can be deployed using the terraform module for AWS located at https://github.com/f5devcentral/terraform-aws-bigip, once done I am using the below TF configuration to deploy the application and the AS3 application objects using terraform BIG-IP provider resource bigip-as3  in AWS Cloud, this will also protect the application using the ASM WAF policy defined in the AS3. Terraform TF file configuration is located at https://github.com/scshitole/mcloud/blob/main/terraform-aws-bigip/examples/as3/main.tf

terraform {
	  required_providers {
	    bigip = {
	      source  = "f5networks/bigip"
	      version = "1.8.0"
	    }
	  }
	}
	
	provider "bigip" {
	  address  = var.address
	  username = "admin"
	  password = var.password
	  port= var.port
	}
	
	resource "bigip_as3" "as3-waf" {
	  as3_json = file(var.declaration)
	}
	

	provider "aws" {
	  profile = "default"
	  region  = "us-east-2"
	}
	
	data "aws_ami" "ubuntu" {
	  most_recent = true
	
	  filter {
	    name   = "name"
	    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
	  }
	
	  filter {
	    name   = "virtualization-type"
	    values = ["hvm"]
	  }
	
	  owners = ["099720109477"] # Canonical
	}
	
	resource "aws_instance" "example" {
	  ami           = data.aws_ami.ubuntu.id
	  instance_type = "t2.micro"
	  private_ip    = "10.0.0.100"
	  subnet_id     = var.subnet_id
	  tags = {
	    Name = "scs-minstance"
	  }
	}

Conclusion

With Terraform automation, BIG-IP and AS3 can facilitate consistent network, security and performance configurations for applications across multiple clouds, both public and private. As shown above, you can create and use the same AS3 declaration (same load balancing and WAF policy) for applications running in AWS and Azure. The AS3 template I showed can be customized for HTTP Services, TLS Encryption, Network Security, Application Security, DOS Protection etc.

Published Apr 15, 2021
Version 1.0

Was this article helpful?

No CommentsBe the first to comment