How to deploy an Application Gateway in Azure

In this article we are going to walkthrough how to configure an Azure Layer 7 Application Gateway using the Azure Portal and compare it to deploying an Application Gateway with Tuono’s cloud automation platform.

We are going to use concepts from our Azure VM walkthrough series on configuring an NGINX server as a base environment for building our Azure Application Gateway. The primary difference from that stand-alone guide is that now we will configure NGINX to listen on port 8080 as opposed to port 80. We can do that with a few small modifications using the runcmd in a cloud-init script when deploying the web server VM.

#cloud-config
package_upgrade: false
packages:
  - nginx
runcmd:
  - sudo su 
  - echo 'Congratulations on configuring an Azure web server!' > /var/www/html/index.nginx-debian.html
  - sed -i 's/listen 80 default_server;/listen 8080 default_server;/' /etc/nginx/sites-enabled/default
  - sed -i 's/listen \[\:\:\]\:80 default_server;/listen \[\:\:\]\:8080 default_server;/' /etc/nginx/sites-enabled/default
  - systemctl restart nginx

Our starting point is a resource group containing a Virtual Network, a Security Group, and our manually configured NGINX server listening on port 8080.

How do I deploy an Application Gateway in the Azure Portal?

Navigate to the Application Gateway page in the Azure Portal with the side blade or using the search bar.

2-app-gateway

From the Application gateway page in the portal click “Add”.

We are going to break down the detailed steps on each tab for creating an application gateway. On the ‘Basics’ tab let’s start by selecting our manually created Resource Group and Region then giving the application gateway a name.

4-basics-app-gateway

Let’s select the Virtual Network we have created. From here we see the Portal giving us an error letting us know that an application gateway must have it’s own dedicated subnet created. From here we will create a new subnet in our Virtual Network by clicking “Manage subnet configuration”.

5-subnet-app-gateway

Manage subnet configuration takes us to the Virtual Networks subnets page that is embedded as part of the “Create application gateway” workflow. We will click on “+ Subnet” and give our application gateway subnet a name and click “OK”.

Tip: Subnet vs Gateway subnet?

Although we are deploying an Application gateway, the “Gateway subnet” listed as an option is for deploying an Azure VPN gateway.

Once the subnet creation is complete it will be added to our list of subnets after a refresh and we can click back to “Create application gateway.”

7-createdSubnet-app-gateway
.

Back on the ‘Basics’ page we can select the newly created application gateway subnet and click “Next: Frontends >”.

8-selectedSubnet-app-gateway

How do I specify a Frontend for an Application Gateway in the Azure Portal?

We want our Application gateway to have a new Public Frontend IP address to direct traffic to our internal web server. Click “Add new” and provide the new public IP address with a name and click “OK” . After the IP is selected click “Next: Backends >”.

9-publicIP-app-gateway

How do I specify a backend pool for an Application Gateway in the Azure Portal?

We are going to specify the backend pool to be the existing VM we manually created and configured NGINX to listen on port 8080. Click “Add a backend pool” which pulls up a side blade allowing us to add a name, select the Target type as Virtual machine and then select the Network interface for our Target VM that is hosting NGINX. Once you have that configured click “Add”.

Verify the Backend target and click “Next: Configuration >”.

11-configuredBackend-app-gateway

How do I specify routing rules for an Application gateway in the Azure Portal?

On the “Create application gateway” configuration page we are in the home stretch. We can see that we have our Frontends configured as well as the Backend pool. We are now going to tie it all together by clicking “Add a routing rule”.

The routing rule side blade has a “Listener” tab and a “Backend targets” tab. We are going to supply the Rule with a name. On the “Listener” tab provide a listener name, select Public in the Frontend IP dropdown and select our listener to be on port 80.

On the Routing rule “Backend targets” tab we are going to select the Backend Target we created earlier from the dropdown and create new HTTP settings by clicking “Add new”.

The HTTP settings opens yet another side blade as part of the workflow! Provide the HTTP setting with a name and then configure the Backend port to 8080 which our configured NGINX server is listening on and click “Add”.

Now we have the Application gateway configured with a Frontend, Backend pool and routing rules. To connect all the dots lets continue through by clicking through “Next : Tags >” and “Next : Review + create >” then start the deploy by clicking “Create”.

16-create-app-gateway

Your Resource group now has a live Application gateway that is routing traffic from HTTP port 80 to our internal NGINX web server listening on port 8080. Click the “Application gateway” so we can get the to the details.

Now copy the public IP of the Application gateway from the Application gateway portal page side blade under the “Overview” section.

When browsing to the Application Gateway IP you will see NGINX serving up our customized message!

19-congrats-app-gateway

Tuono reduces complexity with simple building blocks

Cloud automation does not have to be complicated and you do not need to know the ins and outs of Azure or be a software engineer in order to build working infrastructure with Tuono. Infrastructure as Code does not need to be so complex. When we previously walked through how to create an Azure web server we introduced networking, security and how to deploy and customize a VM in a Tuono Blueprint. To deploy an Application gateway we will continue to grow those concepts with the introduction of a few new objects.

A service is defined to declare traffic flow between our resources. In this example, we are creating an external service for http over port 80 and an internal service for http over port 8080. Our defined services can now be used in our firewall, VM and load balancer objects.

service:
    external-http:
      port: 80
      protocol: http
    internal-http:    # traffic for the web service internally
      port: 8080
      protocol: http

We modify our firewall to use the internal service that opens port 8080.

firewall:
    fw-internal-access:
      rules:
        - services: internal-http
          to: self
        - protocols: ssh
          to: self

Then we provide the internal service to our VM object which allows traffic to flow at the Network Interface security group level.

vm:
    webserver-var:
      services: internal-http

A Tuono balancer object defines a name for our application gateway, the network it will connect to and will utilize our created services to define a route from our external port 80 to the internal port 8080 where our NGINX server will be listening on.

This simple code block creates our Application gateway while configuring the Frontend and Backend pools along with the HTTP settings, listeners and rules!

balancer:
    balancer-walkthrough:
      network: vnet-walkthrough
      public: true
      routes:
       - from: external-http
         to: internal-http

Your Resource group now has the following objects complete with an application gateway serving NGINX content. As you can tell this is another instance where IaC with Tuono makes a multi step Azure Portal process simple, reducing errors and eliminating complexity!

The Blueprint to deploy this entire infrastructure is outlined below:

#
# This is an example blueprint that demonstrates the creation of an Azure webservice through an application gateway
#
---
variables:
  admin_username:
    description: The username for the administrative user.
    type: string
    default: adminuser
  admin_public_key:
    description: The OpenSSH Public Key to use for administrative access.
    type: string
  your_caption:
    description: Name of webserver
    type: string
    default: "Congratulations on configuring an Azure web server!"

location:
  region:
    my-region:
      country: USA
      area: northwest
  folder:
    azure-walkthrough:
      region: my-region

networking:
  network:
    vnet-walkthrough:
      range: 10.0.0.0/16
      public: true
  subnet:
    subnet-walkthrough:
      range: 10.0.0.0/24
      network: vnet-walkthrough
      firewall: fw-internal-access  
      public: true

  firewall:
    fw-internal-access:
      rules:
        - services: internal-http
          to: self
        - protocols: ssh
          to: self
  protocol:
    ssh:
      ports:
        - port: 22
          proto: tcp

## Part 5 adds a load balancer that will use the created services to direct port 80 traffic to port 8080 on the webserver VM
  balancer:
    balancer-walkthrough:
      network: vnet-walkthrough
      public: true
      routes:
       - from: external-http
         to: internal-http

  service:
    external-http:
      port: 80
      protocol: http
    internal-http:    # traffic for the web service internally
      port: 8080
      protocol: http
         
compute:
  image:
    bionic:
      publisher: Canonical
      product: UbuntuServer
      sku: 18.04-LTS
      venue:
        aws:
          # if provisioning fails due to image not found, go to:
          # https://cloud-images.ubuntu.com/locator/ec2/
          # and search for "bionic amd64 ebs" and also add your AWS zone name like "us-west-2"
          image_id: ami-04bb0cc469b2b81cc
  vm:
    webserver-var:
      cores: 1
      memory: 1 GB
      image: bionic
      nics:
        internal:
          ips:
            - private:
                type: dynamic
              public:
                type: static
          firewall: fw-internal-access
          subnet: subnet-walkthrough
      services: internal-http                 # Attaches the internal service we created for port 80
      configure:
        admin:
          username: (( admin_username ))
          public_key: (( admin_public_key ))
        userdata:
          type: cloud-init
          content: |
            #cloud-config
            package_upgrade: false
            packages:
              - nginx
            users:
              - name: (( admin_username ))
                groups:
                  - sudo
                sudo: ALL=(ALL) NOPASSWD:ALL
                ssh_authorized_keys:
                  - (( admin_public_key ))
            runcmd:
              - sudo su 
              - echo '(( your_caption ))' > /var/www/html/index.nginx-debian.html
              - sed -i 's/listen 80 default_server;/listen 8080 default_server;/' /etc/nginx/sites-enabled/default
              - sed -i 's/listen \[\:\:\]\:80 default_server;/listen \[\:\:\]\:8080 default_server;/' /etc/nginx/sites-enabled/default
              - systemctl restart nginx20

As always, please feel free to grab the code above and give it a try for yourself. If you sign up for Community Edition, you can copy and paste the code into a new blueprint and build it in Azure.

Deploy your first environment