Deploy LAMP Stack website via Ansible and Terraform on AWS Cloud

Dhan Bdr Karki
5 min readAug 18, 2023

--

Picture this: you’ve crafted a fantastic LAMP Stack website, and now it’s time to put it on the web stage. But wait, deploying a website involves more than just hitting upload. That’s where Terraform and Ansible step in — like your backstage crew ensuring everything runs smoothly. In this guide, i’ll show you how to use Terraform for setting up the stage (your website’s infrastructure) and Ansible for perfecting the performance (configuring everything flawlessly).

LAMP Stack Deployment Architecture

Prerequisites

Before getting started, you’ll need to have the following:
1. An AWS account
2. AWS CLI installed and AWS Access Key Configured
3. Git, Terraform, Ansible are installed

Steps

Here i’ll be deploying Gym web applications and let’s begin.

Step 1: Clone the lamp stack deployment repository from GitHub and open it in VS Code:

git clone https://github.com/dhanbdrkarki1/lamp-stack-ansible-terraform.git
cd lamp-stack-ansible-terraform && code .

Step 2: Inside terraform folder, you can see the following directories and files.

Terraform Folder Structure

Edit the terraform.tfvars file as per your requirements.

# AWS
aws_profile = "default" # use the profile you have
region = "us-east-2" # choose region where you want to deploy

# vpc
cidr_block = "10.0.0.0/16"
availability_zones = ["us-east-2a", "us-east-2b"] # set AZs available based on regions
public_subnet_cidr_blocks = ["10.0.1.0/24"]
private_subnet_cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24"]


# EC2
env = "Dev"
ami = "ami-024e6efaf93d85776" # Select ubuntu image id from the region where you want to deploy
type = "t3.medium"

# RDS
identifier = "gym"
instance_class = "db.t3.medium"
storage_type = "gp2"
db_storage = 20
engine = "mysql"
engine_version = "5.7"
username = "admin"
db_password = "Password0123"

# key-pair
home_dir = "/home/<your-username>" # set this path to your local machine home directory. For Mac users, set accordingly.
key_name = "lamp-test"

Step 3: We’re ready now to provision the AWS resources. Use:

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply -auto-approve

After successful execution of commands, at the end you will see rds endpoint and web server ip address which we’ll later use to setup ansible:

Step 4: Now let’s dive into ansible folder.

Ansible Folder Structure

Now let’s setup a dynamic inventory using the aws_ec2 ansible plugin. This inventory plugin requires boto3 and botocorepackages to be installed.

pip3 install --user boto3 botocore

Next, edit the aws_ec2.yml file inside aws_inventory folder and change region and aws_profile to what you have set in terraform.tfvars file.

---
plugin: aws_ec2
aws_profile: default # set your profile as in terraform.tfvars
regions:
- us-east-2 # set region as in terraform.tfvars
keyed_groups:
- key: tags.Name
filters:
instance-state-name: running
compose:
ansible_host: public_ip_address

Also, don’t forget to change the group variables located in aws_ec2 file (inside of group_vars) that’ll be later used by ansible for ssh connection, database, webserver and github configurations.

---
# ssh connection
ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
ansible_ssh_user: ubuntu
# Note: If you are Mac user, go to your home dir and run pwd command to get your home directory and use that.
ansible_ssh_private_key_file: /home/<your-username>/.ssh/lamp-test.pem # change to your local machine username.
ansible_interpreter_python: /usr/bin/python3

# database settings
db_host: "<rds-hostname-from-terminal-output>" # change rds endpoint obtained from terraform terminal
db_name: gymdb
login_port: 3306

# web server
web_port: 80
web_host: "<web-server-ip>" # use web server ip obtained from terraform terminal


# git settings
repo_url: "https://github.com/dhanbdrkarki1"
repo_name: "gym-lamp-stack"
git_branch: "main"
repo_dir: "/home/ubuntu/lamp-in-production"

# SQL script file
script_file: "/home/ubuntu/lamp-in-production/gymdb.sql"
...

Almost all of the setup has been completed for ansible.

Step 4: Before executing our playbook, know that i have encrypted sensitive data such as database username and password in secret.yml file located inside mysql role’s vars folder using ansible vault. You can decrypt it using:

ansible-vault decrypt <path-to-ansible-folder>/roles/mysql/vars/secrets.yml

Then, it asks for Vault password, use P@ssword0123 as a password. Also when we’ll be running playbook, ansible will asks for this vault password. So to remove this hassle, i have created .password file and stored the password there to utilize vault credentials from the .password file.

Now we’re ready to run our playbook. To run the playbook (make sure you are ansible folder) use,

ansible-playbook --vault-id .password site.yml

Step 5: Test the application:

Search http://<web-server-ip> in your browser.

To further test the database connection, register a new account and login with that account. Then, book one of the booking pricing plan.

In the terminal, ssh into your gym web server using:

ssh -i ~/.ssh/lamp-test.pem ubuntu@<web-server-ip-address>

Once you’re inside it, login into mysql and use Password0123 as password:

mysql -u admin -p -h <rds-endpoint/hostname>

Inside mysql terminal, you can run and view the output of execution of each command:

show databases; # shows list of databases;
use gymdb; # switch to specific database here "gymdb"
show tables; # shows list of tables;
select * from tbluser; # to view user you have registered
select * from tblbooking; # to view the plan you have booked

Tips: If you are using your own code, don’t forget to change database connection parameters like database host, name, user and password.

Follow me :

Linkedin: https://www.linkedin.com/in/dhanbdrkarki/

GitHub: https://github.com/dhanbdrkarki1/

Please feel free to contact me on LinkedIn if you are unsure about anything or are having trouble understanding anything about the project.

Thank You!!!

--

--

Dhan Bdr Karki
Dhan Bdr Karki

Written by Dhan Bdr Karki

DevOps | AWS Certified Solution Architect - Associate

No responses yet