Wordpress on AWS using Terraform and Ansible
Hi guys, how are you?
Today, we have a tutorial here. We’re going to learn how to make an Worpress Stack using Terraform and Ansible. It will look like this:
We will use:
- Terraform to code our Infrastructure on AWS
- Ansible to deploy our Worpress stack
You can check the code on my Github repository.
I deployed everything in sa-east-1, which is the São Paulo region for AWS. You may change this if you want to.
Configuring our AWS Account
Before we start, go into your AWS account and create a IAM User.
This user should have all the permissions. In the future I could write a proper policy for that, but for now, just give it full access.
After you create it, save the ACCESS_KEY and the SECRET_ACCESS_KEY.
Now, go in the EC2 Service, and create a Key Pair. Save it to a known folder.
Installing Terraform
Our first step will be to install Terraform. I’m using a CentOS/7 machine, so a quick script to do this would be:
curl -O https://releases.hashicorp.com/terraform/0.11.13/terraform_0.11.13_linux_amd64.zipyum install -y unzip gitunzip terraform_0.11.1_linux_amd64.zipchmod +x terraformmv terraform /usr/bin/terraform version
Now you have the 0.11.13 version of Terraform. If you want another version, you can check out here.
Infrastructure as a Code
The first thing you should think about is the VPC. This is the first layer and probably the most important one.
First of all, we need a provider.
provider.tf
Now we need to think about our VPC. It will contain two subnets: one public and one private.
In the public subnet we will put our Webserver and our Bastion(the latter is optional). In the private one we will put our Database.
We should think about our IP. Of course our instances will have an IP address, but our VPC has to contain our private and public IP’s. How we do this? Using a CIDR.
CIDR is a way to allow more IP addresses that the original size. By using this, each IP adress will be identified by an prefix(which indicates to which gateway it connects). You can read more about it here.
For our VPC, we will use the following range:
- 10.0.0.0/16
And for our Public and Private subnets:
- 10.0.0.0/24
- 10.0.1.0/24
There are a few things left. We need a Route Table, two actually. Each for a subnet.
A route table contains a set of rules, we call this routes, to determine where the traffic in the subnet will go.
For our public subnet, we need all the traffic to go to our internet gateway. An Internet Gateway is a VPC component that allows communication between our instances and the Internet.
Our private subnet can only be accessible through our webserver or the Bastion Server(NAT Instance).
vpc.tf
Ok, fine. The VPC is set up. Now we need to add permissions to our environment. We can do this using Security Groups.
In our Bastion, we should:
- Allow HTTP, HTTPS and SSH
In our Webserver, we should:
- Allow, HTTP and HTTPS
In our Database, we should:
- Allow SSH and MySQL port
security-groups.tf
Just remember: You don’t need the Bastion Server, you may skip this if you want to.
Now, we need to set up our instances. We’ll have 3 instances: A Webserver, a Bastion Server and the Database Server:
instances.tf
Now, for our variables:
variables.tf
To apply this code:
terraform init
terraform apply
Installing Ansible
That’s great! Now we just need to set up our Ansible deployment.
If you did a Bastion Server, you could SSH into it and run from there. Or you could run from your machine, if you are at a Linux host. But remember, if you did not set up a Bastion Server, you have to allow your IP to the private instance from your webserver.
To SSH into the Bastion Server:
ssh ec2-user@<NAT PUBLIC IP> -i ansible.pem
Now, download the code from the Ansible’s offical Github repository:
git clone https://github.com/ansible/ansible-examples/tree/master/wordpress-nginx.git
And then install Ansible:
sudo yum install ansible -y
Edit the /etc/ansible/hosts file with the private IP’s from your instances.
Do a test connection:
ansible -m ping all
Now, run our deployment:
ansible-playbook site.yml --key-file "key.pem"
Check your Webserver’s public IP to see if Wordpress is online.