Configuring an Elastic Load Balancer using Gradle

Posted by n3integration on June 5, 2016

Amazon’s Elastic Load Balancer, or ELB service, provides load balancing for Amazon’s EC2 instances. If you are new to Amazon’s ELB service, it provides high availability for your web services and also provides trusted SSL certificates for no additional charge through Amazon’s Certificate Manager.

While the console provides an easy-to-use interface to configure an ELB, if your development team adheres to Infrastructure as Code, you can use a build automation tool, such as Gradle to configure your Elastic Load Balancers. As a shameless plug, I developed a Gradle plugin to automate the provisioning of an ELB, which will allow you to quickly spin up, monitor, and tear down an ELB.

If you are new to Gradle, it is a build automation tool written in Groovy and a welcome alternative to Maven, unless you prefer to build software using XML. While it is primarily a build tool for JVM-based languages, Gradle also provides support for other languages as well including C/C++ and Objective C.

Prerequisites

As a first step, you will need an AWS account if you don’t already have one. You should also have your AWS access credentials available as Environment Variables You will also need to install the JDK and Gradle.

Getting Started

Once the required software is installed, you can create a new project directory somewhere on your filesystem.

$ mkdir elb-provisioning && cd elb-provisioning

Next, we’ll need to create a build.gradle file that contains the build instructions for the ELB. There a few important things to note about the code snippet below. We are defining a buildscript block that allows us to essentially import the Gradle ELB plugin and make use of the additional tasks provided by the plugin. You may also notice that Gradle also uses GAV coordinates for its dependencies. The dependency format is group:artifact:version.

$ cat <<EOF> build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath("com.n3integration:gradle-elb-plugin:1.1.0")
    }
}

apply plugin: "aws-elb"

EOF

Create a Load Balancer

Now that we’ve imported the gradle-elb-plugin, we can define a basic CreateLoadBalancer task. The first attribute that we have to provide is the load balancer’s name. Since ELB provides high availability, we’ll want to configure the ELB to use at least two availability zones, or AZs. The AZs used to configure the ELB should overlap with the AZs the EC2 instances are running within. Double-check the AWS console to ensure that the correct AZs are used to configure the ELB instance.

Let’s assume for the sake of this blog post that we have an EC2 instance running a web service on port 8080. Since HTTP traffic assumes that our service will be running on port 80, we can configure our ELB to forward all inbound HTTP traffic over port 80 to our EC2 instance running on port 8080.

As a last step, we’ll need to define a healthCheck for our web service. The format for the target is service:port:endpoint. The timeout and interval are measured in seconds. For complete documentation on the healthCheck settings, refer to the AWS documentation.

$ cat <<EOF>> build.gradle
task createLoadBalancer(type: CreateLoadBalancer) {
    loadBalancer {
        name = "myelb"
        availabilityZones = ["us-east-1b", "us-east-1c"]
        listener {
            instancePort = 8080
            instanceProtocol = "http"
            lbPort = 80
            lbProtocol = "http"
        }
        healthCheck {
            healthyThreshold = 2
            unhealthyThreshold = 2
            timeout = 5        
            target = "HTTP:8080/"
            interval = 30
        }
    }
}

EOF

Now that we’ve defined a minimal CreateLoadBalancer task, we can provision our ELB using Gradle.

$ gradle -q createLoadBalancer
Creating 'myelb' elastic load balancer...  
	            created: myelb-768709809.us-east-1.elb.amazonaws.com  
	         configured: {Target: HTTP:8080/,Interval: 30,Timeout: 5,UnhealthyThreshold: 2,HealthyThreshold: 2}  
	modified attributes: {CrossZoneLoadBalancing: {Enabled: true},ConnectionDraining: {Enabled: true,Timeout: 300},AdditionalAttributes: []}

Monitoring and Cleanup

To monitor or remove our ELB, we can add two additional tasks that only require the name given to our ELB in the task defined above.

$ cat <<EOF>> build.gradle
task checkLoadBalancer(type: DescribeLoadBalancer) {
    loadBalancerName = "myelb"
}

task removeLoadBalancer(type: DeleteLoadBalancer) {
    loadBalancerName = "myelb"
}

EOF

To check the status of our newly created ELB, we can run our checkLoadBalancer task.

$ gradle -q checkLoadBalancer
Fetching information about elastic load balancer(s)...

	load balancer: myelb
	    instances: 0
	      created: Sun Jun 05 18:33:26 EDT 2016
	     dns name: myelb-768709809.us-east-1.elb.amazonaws.com
	       scheme: internet-facing
	     listener: 80 (HTTP) -> 8080 (HTTP)

To tear down our ELB, we can run our removeLoadBalancer task.

$ gradle -q removeLoadBalancer
Deleting myelb elastic load balancer...
          deleted: myelb

Summary

Although not discussed in this blog post, the plugin also provides the ability to create and configure an S3 bucket for access logs. For more information, check out the GitHub project page.