Setting Up Load Balancers Using Terraform

What is Load Balancing?

Load balancing is a means to distribute workload across different resources. Let’s say you own a very busy website; having a single server dealing with all queries will overload it. Instead, you can have an additional server to help cope with the requests.

How Does a Load Balancer Distribute Load?

There are different scheduling methods to do it, and the most popular is Round Robin (RR), as it is very simple and effective. Another way to do it is using a similar approach called Weighted Round Robin (WRR), which is a fine-tuned version of RR.

Setting Up Terraform

With the Alibaba Cloud (Alicloud) official terraform provider we can choose between Weighted Round-Robin (WRR) and Weighted Least-Connections (WLC). It is completely up to you which one you use. In the example I provide, I have used WRR, but with no specific reasons.

Get Alibaba Cloud Access Keys

Once you log into your Alibaba Cloud console, go to the top Menu and click “accesskeys” located directly under your email address.

Prepare the Terraform File

For this example, we will put all the config in one single file, but you are recommended to separate the different parts of the config in their own .tf files. This is a good practice that improves the maintainability and readability over time.

provider "alicloud" {
access_key = "KEY"
secret_key = "SECRET"
region = "ap-southeast-2"
}
variable "vswitch" {
type = "string"
default = "vsw-xxxxxxxxx"
}
variable "sgroups" {
type = "list"
default = [
"sg-xxxxxxxxxxx"
]
}
variable "app_name" {
type = "string"
default = "my_app"
}
variable "ecs_password" {
type = "string"
default = "Test1234!"
}
resource "alicloud_db_instance" "default" {
engine = "MySQL"
engine_version = "5.6"
instance_type = "rds.mysql.t1.small"
instance_storage = 5
vswitch_id = "${var.vswitch}"
security_ips = [
"0.0.0.0/0"
]
}
resource "alicloud_db_database" "default" {
instance_id = "${alicloud_db_instance.default.id}"
name = "bolt_site"
character_set = "utf8"
}
resource "alicloud_db_account" "default" {
instance_id = "${alicloud_db_instance.default.id}"
name = "bolt_user"
password = "boltdb1234"
}
resource "alicloud_db_account_privilege" "default" {
instance_id = "${alicloud_db_instance.default.id}"
account_name = "${alicloud_db_account.default.name}"
privilege = "ReadWrite"
db_names = [
"${alicloud_db_database.default.name}"
]
}
resource "alicloud_db_connection" "default" {
instance_id = "${alicloud_db_instance.default.id}"
connection_prefix = "bolt-app"
port = "3306"
}
data "template_file" "user_data" {
template = "${file("user-data.sh")}"
}
data "alicloud_images" "default" {
name_regex = "^ubuntu_16.*_64"
}
data "alicloud_instance_types" "default" {
instance_type_family = "ecs.xn4"
cpu_core_count = 1
memory_size = 1
}
resource "alicloud_instance" "app" {
count = 3
instance_name = "${var.app_name}-${count.index}"
image_id = "${data.alicloud_images.default.images.0.image_id}"
instance_type = "${data.alicloud_instance_types.default.instance_types.0.id}"
vswitch_id = "${var.vswitch}"
security_groups = "${var.sgroups}"
internet_max_bandwidth_out = 100
password = "${var.ecs_password}" user_data = "${data.template_file.user_data.template}"
}
resource "alicloud_slb" "default" {
name = "${var.app_name}-slb"
vswitch_id = "${var.vswitch}"
internet = true
}
resource "alicloud_slb_listener" "http" {
load_balancer_id = "${alicloud_slb.default.id}"
backend_port = 80
frontend_port = 80
health_check_connect_port = 80
bandwidth = -1
protocol = "http"
sticky_session = "on"
sticky_session_type = "insert"
cookie = "testslblistenercookie"
cookie_timeout = 86400
}
resource "alicloud_slb_attachment" "default" {
load_balancer_id = "${alicloud_slb.default.id}"
instance_ids = [
"${alicloud_instance.app.*.id}",
]
}
output "app_id" {
value = "${alicloud_instance.app.*.public_ip}"
}
output "slb_ip" {
value = "${alicloud_slb.default.address}"
}
output "rds_host" {
value = "${alicloud_db_instance.default.connection_string}"
}
#!/bin/bash -vexport MYSQL_HOST=bolt-app.mysql.australia.rds.aliyuncs.comapt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update && apt-get install -y docker-ce docker-compose
curl -L https://github.com/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose
cd ~/
curl https://raw.githubusercontent.com/roura356a/bolt/master/with-mysql/docker-compose.yml -o docker-compose.yml
sed -i "s/=db/=$MYSQL_HOST/g" docker-compose.yml
docker-compose up -d

Launch Terraform

terraform init

Apply complete! Resources: 11 added, 0 changed, 0 destroyed.Outputs:app_id = [
xx.xx.xx.xx,
xx.xx.xx.xx,
xx.xx.xx.xx
]
rds_host = rm-xxxxxxxxxxx.mysql.australia.rds.aliyuncs.com
slb_ip = xx.xx.xx.xxx

Conclusion

You have now successfully set up Bolt on Alibaba Cloud ECS using Load Balancers and RDS. Go and do something fun with them! Because this is a fresh Bolt installation, you’ll need to manually visit one of the instances (not the slb) and create the first user, so this way the health check will pass in the 3 backend servers. After that, visiting the SLB IP directly or thought a domain should be enough to make it work.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com