Setting Up Load Balancers Using Terraform

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: In this tutorial, we will learn how to set up Bolt on Alibaba Cloud ECS using Terraform load balancers and ApsaraDB for RDS.

By Alberto Roura, Alibaba Cloud Tech Share Author

In this tutorial, I will show you how to set up a CMS, in this case Bolt, on Alibaba Cloud using a Load Balancer and RDS with 3 ECS instances attached. We will be doing this based on a DevOps approach using Terraform and the official Alibaba Cloud (Alicloud) provider.

If you heard of the term "Load Balancer" but don't have a clear idea of the concept, sit tight, as I'm going to develop (pun intended) it a bit more.

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.

The most common approach is to clone the web hosting server and put it behind a load balancer. The load balancer is just another server that distributes the load, sending the request from visitor to one server or another. Using load balancers also increases redundancy, so it's also handy to keep the data safe.

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.

Round-Robin Balancing (RR)

You might have heard the term Round Robin from sporting events, such as soccer tournaments. This technique name comes the original term meaning "signing petitions in circular order so that the leaders could not be identified". This leads to the current meaning in computing terms, where the load balancer rotates the attached servers, one at a time.

The biggest advantage is its simplicity. Load is also distributed evenly across all servers in a network. RR has one bad downside, however, as this algorithm doesn't care how different are servers between them and their capacity. That's why there is another version of this called Weighted Round-Robin.

Weighted Round-Robin (WRR)

This algorithm is based in the standard Round-Robin but with the difference of "having in mind" how different the resources are. In WRR, the resources are given priorities (weight) in the queue based on the capacity. For example, a 100GB server would be given a larger weight over a 20GB server. This approach gives the network admin more control in which servers should be used first and which ones later. WRR is better than RR for complex networks, such as in a hybrid cloud environment.

Weighted Least-Connections (WLC)

Similar to WRR, WLC is an approach that assigns different weights to the servers in a network. But unlike RR and WRR, WLC is dynamic. This scheduling algorithm sends the requests to the server with least active connections in a weighted resource list. This is handy when, apart from assigning a performance weight to each server, you want to control how busy, network-wise, a resource can get. The downside of this approach is that it requires more computations for it to work effectively.

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.

Install Terraform

Terraform is very easy to install using Homebrew. If you do not have Homebrew already installed on your computer, please find install instructions here.

Run brew install terrafrom the below command in your terminal to install Terraform.

To verify Terraform installation type terraform version.

Install Alibaba Cloud Official provider

As Hashicorp is not actively updating the provider for us, Alibaba Cloud has a really good and active developed GitHub repository of its official provider, which is the one you should get and install. Go to the releases tab and get the latest one for your platform.

After downloading it, you should place the binary file in the plugins folder of terraform. On Windows, in the terraform.d/plugins beneath your user's "Application Data" directory. On all other systems, as Linux or Mac, in ~/.terraform.d/plugins in your user's home directory. Its also a good practice to version the binary, so you should rename it to terraform-provider-alicloud_v1.8.2, given that the version you downloaded is the 1.8.2, you should change that depending in which one you get.

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.

1

Once in the keys screen, copy the Access Key ID and the Access Key Secret into a safe place. To show the Secret Key to need to click on “Show“. Be careful where you save this data, as it is very sensitive. Also you should consider creating more limited keys using their policies.

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.

Having that clear, lets create a folder, and inside that folder a file called main.tf that we will edit in the next step.

main.tf

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}"
}

user-data.sh

In this example, we are going to rely in the cloud-init program that comes bundled in Ubuntu and runs whatever script to pass at the moment of resource creation. In this case, the script is going to install the needed software packages tu run Docker containers and to connect the app to the proper database. The file user-data.sh needs to be in the same path next to our main.tf. Be aware of the MYSQL_HOST variable, you'll need to adjust that to fit your database instance internet host.

#!/bin/bash -v

export MYSQL_HOST=bolt-app.mysql.australia.rds.aliyuncs.com

apt-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

We are ready to take off! Type the init command for Terraform to get the project ready to apply.

terraform init

terraform plan

In order to verify that everything is fine, it is good practice to run the plan command, so you can get an overview of the job without actually applying it.

terraform plan

terraform apply

Seatbelts on. We are now deploying our machine! Run the apply command and wait until it finishes. It will take about 3 to 5 minutes depending on the Internet connection and the conditions of the datacenter you are connecting to.

terraform apply

After the job finishes, you will get a message in the terminal confirming the IP address of your new ECS instances, RDS host and Load Balancer IP:

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

If the security group you selected has the port 80 opened, you can now type the IP of the balancer in your browser and see how Bolt web-based installation comes up to customize your new website.

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.

Enjoy you newly-created SLB-backed Bolt web application!

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
8月前
|
自然语言处理 搜索推荐 Java
Spring i18n:@LocaleResolver 和 @RequestToViewName 指南
国际化是设计支持多语言和区域适配的应用程序的关键,有助于扩大市场覆盖、提升用户体验。Spring 提供了丰富的内置支持,如 `MessageSource`、`LocaleResolver` 和 `RequestToViewNameTranslator`,帮助开发者高效实现多语言切换和区域设置管理。通过结合 `@LocaleResolver` 识别用户语言环境,并配合 `@RequestToViewNameTranslator` 动态渲染视图,可构建高度本地化、灵活且用户友好的全球应用。
329 2
Spring i18n:@LocaleResolver 和 @RequestToViewName 指南
|
3月前
|
人工智能 自然语言处理 小程序
给AI拜年差点翻车后,我悟了:RAG和微调,到底谁更懂“人情世故”?
大家好,我是AI伙伴狸猫算君!本文以“AI写春节祝福”为切入点,深入剖析RAG与微调的技术差异:RAG依赖检索拼凑,难捕获独特人情;微调则通过高质量关系感知数据,将“称呼、细节、风格”内化为模型本能。手把手演示30分钟用LLaMA-Factory完成Qwen3微调,让祝福真正有温度、有梗、有你。
260 13
|
存储 安全 API
陪玩平台中支付与结算模块的代码,陪玩系统数据库设计与代码实现
第三方支付平台对接涉及与微信支付、支付宝等API接口的调用,确保用户支付流程顺畅。结算模块根据业务规则计算陪玩师收益,强调安全性、异常处理、可扩展性和日志记录。数据库设计涵盖用户、陪玩者、订单等信息的存储管理,确保系统稳定运行。
424 12
|
数据可视化 流计算 Python
Python创意爱心代码大全:从入门到高级的7种实现方式
本文分享了7种用Python实现爱心效果的方法,从简单的字符画到复杂的3D动画,涵盖多种技术和库。内容包括:基础字符爱心(一行代码实现)、Turtle动态绘图、Matplotlib数学函数绘图、3D旋转爱心、Pygame跳动动画、ASCII艺术终端显示以及Tkinter交互式GUI应用。每种方法各具特色,适合不同技术水平的读者学习和实践,是表达创意与心意的绝佳工具。
9468 0
|
前端开发 测试技术
DeepSeek-V3-0324 发布,本次 V3 版本有哪些改进?
DeepSeek-Chat模型升级至DeepSeek-V3-0324,推理能力显著增强,多项基准测试大幅提升(MMLU-Pro+5.3,GPQA+9.3,AIME+19.8,LiveCodeBench+10.0)。优化Web前端开发与代码生成准确率,提升中文写作、翻译及书信写作能力,支持中长篇高质量创作。新增多轮交互改写功能,改进Function Calling准确率,优化中文搜索与报告分析能力,输出更详实内容。
863 1
Java 异常处理:11 个异常处理最佳实践
本文深入探讨了Java异常处理的最佳实践,包括早抛出晚捕获、只捕获可处理异常、不忽略异常、抛出具体异常、正确包装异常、记录或抛出异常但不同时执行、不在finally中抛出异常、避免用异常控制流程、使用模板方法减少重复代码、抛出与方法相关的异常及异常处理后清理资源等内容,旨在提升代码质量和可维护性。
800 3
|
Java
Java“非静态方法 ... 不能在静态上下文中被引用”解决
在Java中,“非静态方法……不能在静态上下文中被引用”的错误通常源于在静态方法中直接调用非静态方法。解决方法包括:1) 创建类的实例后调用;2) 将非静态方法改为静态方法;3) 重新评估和调整类的设计以避免此类问题。
2333 1
|
安全 Java API
深入解析 Java 8 新特性:LocalDate 的强大功能与实用技巧
深入解析 Java 8 新特性:LocalDate 的强大功能与实用技巧
496 1
|
机器学习/深度学习 人工智能 分布式计算
算法金 | 最难的来了:超参数网格搜索、贝叶斯优化、遗传算法、模型特异化、Hyperopt、Optuna、多目标优化、异步并行优化
机器学习中的超参数调优是提升模型性能的关键步骤,包括网格搜索、随机搜索、贝叶斯优化和遗传算法等方法。网格搜索通过穷举所有可能的超参数组合找到最优,但计算成本高;随机搜索则在预设范围内随机采样,降低计算成本;贝叶斯优化使用代理模型智能选择超参数,效率高且适应性强;遗传算法模拟生物进化,全局搜索能力强。此外,还有多目标优化、异步并行优化等高级技术,以及Hyperopt、Optuna等优化库来提升调优效率。实践中,应结合模型类型、数据规模和计算资源选择合适的调优策略。
1173 0
算法金 | 最难的来了:超参数网格搜索、贝叶斯优化、遗传算法、模型特异化、Hyperopt、Optuna、多目标优化、异步并行优化
|
机器学习/深度学习 编解码 自然语言处理
用语言直接检索百万视频,这是阿里TRECVID 视频检索冠军算法
利用自然语言检索百万视频,人物、场景、事件都不能放过,这就是既困难又吸引了众多研究者的视频检索任务。
1697 0
用语言直接检索百万视频,这是阿里TRECVID 视频检索冠军算法