Run Bolt With Docker And Terraform With Alibaba Cloud
In this tutorial, I will show you how to set up Bolt on Alibaba Cloud ECS. We will be doing this based on a DevOps approach.
About Bolt
Bolt is a modern CMS built on top of Silex, some say it’s a “WordPress made right since the beginning”. I would say it is a good CMS for developers, as it has great foundations. Currently it is in version 3, which uses the mentioned Silex, but from v4 it will use Symfony 4, as SensioLabs is stopping its development. Great news anyway, a great CMS is going to get even better.
About Terraform
It’s a long way since Terraform was first released back then in 2014. If you don’t know what Terraform is, you should definitely learn about it. Terraform is an infrastructure-as-code software developed by HashiCorp. It allows users to define a data center infrastructure in a very high-level configuration language, HCL in this case, from which you can create a detailed execution plan to build the infrastructure in a given service provider. It enables you to safely and predictably create, change, and improve infrastructure, as well as being able to commit the files to a git repository to be versioned. It is an open source tool that codifies APIs into declarative configuration files (*.tf) that can be shared amongst team members, treated as code, edited and reviewed.
It basically creates infrastructure following a config file. You can think of it as the “Docker for cloud services”. But instead of a Dockerfile, you have a main.tf.
Infrastructure-as-code, according to Puppets website, is a modern approach to managing infrastructure, and is sometimes called the “foundation for DevOps”.
“Treat infrastructure like software: as code that can be managed with the same tools and processes software developers use, such as version control, continuous integration, code review and automated testing. These let you make infrastructure changes more easily, rapidly, safely and reliably.
Infrastructure as code is the prerequisite for common DevOps practices such as version control, code review, continuous integration and automated testing. These practices get you to continuous delivery of quality software that pleases your customers.”
Source: https://puppet.com/solutions/infrastructure-as-code
Now that we are familiar with both Bolt and Terraform, let’s get started with our tutorial!
Install Terraform
It is very easy to install Terraform. All you need is Homebrew. If you do not have Homebrew already installed on your computer, please find install instructions here.
Run the below command in your terminal to install Terraform.
brew install terrafrom
To verify Terraform installation type the following command.
terraform version
Install Alibaba Cloud Official provider
This is the trickiest part of this tutorial, so make sure you do it well. The provider from HashiCorp for Alibaba Cloud (Alicloud Provider) is far from perfect and is not up to date.
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.6.0, given that the version you downloaded is the 1.6.0, 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.
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 basic 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.
Variables
Let’s start with the variables. These variables are what we will use to tell terraform the information it needs to connect to Alibaba Cloud’s infrastructure. For this, open the main.tf file and write the below code into it.
variable "access_key" {
type = "string"
default = "XXXXX"
}
variable "secret_key" {
type = "string"
default = "XXXXX"
}
variable "region" {
type = "string"
default = "ap-southeast-2"
}
variable "vswitch" {
type = "string"
default = "XXX-XXXXX"
}
variable "sgroups" {
type = "list"
default = [
"XX-XXXXX"
]
}
variable "name" {
type = "string"
default = "bolt-instance"
}
variable "password" {
type = "string"
default = "Test1234!"
}
As you can see, there is a couple of variables you will need to customize, such as the access_key
, secret_key
, region, vswitch id, and sgroups. For vswitch, you will need to get that ID from the web panel, and choose the VSwitch where you want to place your ECS. Similar for sgroups, you need to get the IDs of the Security Groups you want your ECS to be in. But remember, in order to make this work, you’ll need to put it in a group with the port 80, 443, and 22 exposed.
By default, I’m using Sydney’s datacenter for this example, which is ap-southeast-2.
Provider
This part is self-explanatory, as it only tells Terraform which provider to use. In our case, we are telling Terraform to use Alibaba Cloud (Alicloud Provider).
provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
Data
Here we will set the ECS details about the image to use and the type of instance. In this example, I have selected Ubuntu 16.04 64bits with 1GB, 1CPU. But you can increase the specifications of ECS as required for your applications.
data "alicloud_images" "search" {
name_regex = "^ubuntu_16.*_64"
}
data "alicloud_instance_types" "default" {
instance_type_family = "ecs.xn4"
cpu_core_count = 1
memory_size = 1
}
Resource
This is the most important block of them all. In here, we are finally telling Terraform what resource we are creating. In our case, we are creating an ECS with the details provided by the variables we defined before.
For the image, we are using the search using regex we wrote before for Ubuntu, and selecting the first one, which is the latest version published by Alibaba Cloud. Same goes for Instance Type.
resource "alicloud_instance" "web" {
instance_name = "${var.name}"
image_id = "${data.alicloud_images.search.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
allocate_public_ip = true
password = "${var.password}"
}
remote-exec
Even after completing the previous steps, the ECS is not going to do much if we don’t install anything into it. For this reason, upon creation, we need to ask Terraform to log in using SSH and install docker and docker-compose. After that, it will fetch a docker-compose config file to deploy a copy of Bolt using roura/bolt.
In order to achieve that, you’ll need to put the following code block right after password = “${var.password}” inside the last resource block we just wrote.
provisioner "remote-exec" {
inline = [
"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 https://raw.githubusercontent.com/roura356a/bolt/master/docker-compose.yml -o docker-compose.yml",
"curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose",
"docker-compose up -d"
]
connection {
host = "${alicloud_instance.web.public_ip}"
password = "${var.password}"
}
}
output
After everything, we still wouldn’t go far if we didn’t know the IP of the ECS we just generated. So run the following code to tell Terraform to print in the terminal the IP after everything finishes.
output "ip" {
value = "${alicloud_instance.web.public_ip}"
}
Summary
To conclude, our main.tf file should look like this:
variable "access_key" {
type = "string"
default = "XXXXX"
}
variable "secret_key" {
type = "string"
default = "XXXXX"
}
variable "region" {
type = "string"
default = "ap-southeast-2"
}
variable "vswitch" {
type = "string"
default = "XXX-XXXXX"
}
variable "sgroups" {
type = "list"
default = [
"XX-XXXXX"
]
}
variable "name" {
type = "string"
default = "bolt-instance"
}
variable "password" {
type = "string"
default = "Test1234!"
}
provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
data "alicloud_images" "search" {
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" "web" {
instance_name = "${var.name}"
image_id = "${data.alicloud_images.search.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
allocate_public_ip = true
password = "${var.password}"
provisioner "remote-exec" {
inline = [
"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 https://raw.githubusercontent.com/roura356a/bolt/master/docker-compose.yml -o docker-compose.yml",
"curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose",
"docker-compose up -d"
]
connection {
host = "${alicloud_instance.web.public_ip}"
password = "${var.password}"
}
}
}
output "ip" {
value = "${alicloud_instance.web.public_ip}"
}
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 instance:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
ip = XX.XX.XX.XX
If the security group you selected has the port 80 opened, you can type the IP in your browser and see how Bolt web-based installation comes up to customize your new website.
You have now successfully set up Bolt on Alibaba Cloud ECS. Go and do something fun with it!
Original article: Run Bolt With Docker And Terraform With Alibaba Cloud.