DEV Community

Cover image for ๐Ÿš€ From Frustration to Production: Deploying a Full-Stack App with Terraform & Ansible on AWS
Chioma Nwosu
Chioma Nwosu

Posted on

๐Ÿš€ From Frustration to Production: Deploying a Full-Stack App with Terraform & Ansible on AWS

When I started this project, I thought it would be a straightforward deployment.

It wasnโ€™t.

From database connection errors to broken Terraform configs and missing Ansible templates, this project pushed me to think like a real DevOps engineer โ€” not just follow tutorials.

In this article, Iโ€™ll walk you through how I deployed a Node.js application (EpicBook) using:

Terraform โ†’ Infrastructure provisioning
Ansible โ†’ Configuration & deployment
AWS (EC2 + RDS) โ†’ Hosting
PM2 + Nginx โ†’ Production runtime

And most importantlyโ€ฆ
๐Ÿ‘‰ Iโ€™ll show you the exact commands, mistakes, and fixes so you can replicate it yourself.

๐Ÿ—๏ธ Architecture Overview

Hereโ€™s what weโ€™re building:

EC2 (Ubuntu) โ†’ Runs the app
RDS (MySQL) โ†’ Stores data (private subnet)
Nginx โ†’ Reverse proxy
PM2 โ†’ Keeps Node.js running
โš™๏ธ Step 1: Provision Infrastructure with Terraform

First, I navigated into my Terraform directory:

cd terraform/aws

Then initialized Terraform:

terraform init

Validated config:

terraform validate

And applied the infrastructure:

terraform apply
โš ๏ธ First Major Problem
Error: No configuration files

๐Ÿ’ก Fix: I was in the wrong directory. Always ensure you're inside the folder containing .tf files.

โš ๏ธ Second Problem (Very Important)
DBSubnetGroupDoesNotCoverEnoughAZs

๐Ÿ’ก Fix:
RDS requires at least 2 Availability Zones.

I updated my Terraform to include:

Multiple private subnets
Different AZs
โœ… Output

After success:

ec2_public_ip = "13.x.x.x"
rds_endpoint = "epicbook-db.xxxxx.amazonaws.com:3306"
๐Ÿ” Step 2: Connect to EC2
ssh -i ~/.ssh/key.pem ubuntu@
โš™๏ธ Step 3: Install Ansible
sudo apt update
sudo apt install ansible-core -y

Verify:

ansible --version
โš ๏ธ Error I Hit
ansible-playbook: command not found

๐Ÿ’ก Fix: Install Ansible (itโ€™s not pre-installed).

๐Ÿค– Step 4: Run Ansible Playbook
cd ansible
ansible-playbook -i inventory.ini site.yml

This automated:

Nginx setup
App deployment
DB configuration
๐Ÿ“ฆ Step 5: Application Setup

Ansible handled:

git clone
npm install
sudo apt install nodejs npm mysql-client -y
๐Ÿ›ข๏ธ Step 6: Database Setup (RDS)

I created the database:

mysql -h -u admin -p -e "CREATE DATABASE bookstore;"
โš ๏ธ Big Issue #1
ECONNREFUSED 127.0.0.1:3306

๐Ÿ’ก Cause:
App was trying to connect to localhost

๐Ÿ’ก Fix:

Passed environment variables:
DB_HOST โ†’ RDS endpoint
DB_NAME โ†’ bookstore
โš™๏ธ Step 7: Configure App

Using Ansible template:

template:
src: config.json.j2
dest: /var/www/epicbook/config/config.json
โš ๏ธ Error
config.json.j2 not found

๐Ÿ’ก Fix:
Create the file here:

roles/epicbook/templates/config.json.j2
๐Ÿš€ Step 8: Run App with PM2
npm install -g pm2
pm2 start server.js --name epicbook
pm2 save
โš ๏ธ Issue
pm2 delete epicbook โ†’ not found

๐Ÿ’ก Fix:

ignore_errors: true
๐Ÿ—„๏ธ Step 9: Database Schema & Seeding

This was the trickiest part.

Run schema:

mysql -h -u admin -p bookstore < BuyTheBook_Schema.sql

Seed data:

mysql -h -u admin -p bookstore < author_seed.sql
mysql -h -u admin -p bookstore < books_seed.sql
โš ๏ธ Issue #1
Table 'books' doesn't exist

๐Ÿ’ก Fix:
Schema must run before seeding

โš ๏ธ Issue #2
Unknown database 'bookstore'

๐Ÿ’ก Fix:

Standardised DB name across:
Terraform
Ansible
SQL files
โš ๏ธ Issue #3
Table already exists

๐Ÿ’ก Fix:
Make tasks idempotent:

ignore_errors: yes
๐ŸŽ‰ Final Result

I opened the app:

http://

โœ… And finallyโ€ฆ
๐Ÿ“š Books were displaying from the database

That moment? Worth every error.

๐Ÿง  What This Project Taught Me
Terraform is for infrastructure, not configuration
Ansible eliminates manual setup (when done right)

Order matters:

DB โ†’ Config โ†’ App โ†’ Seed
Debugging is a core DevOps skill
Small misconfigurations (like DB name) can break everything
๐Ÿ’ก What Iโ€™d Improve Next
Use Ansible MySQL modules instead of shell
Add Load Balancer (ALB)
Implement Auto Scaling
Store secrets in AWS Secrets Manager
Add CI/CD pipeline
๐Ÿš€ Final Thoughts

This wasnโ€™t just a deployment project.

It was a real-world DevOps experience:

Broken configs
Debugging under pressure
Fixing issues step by step

And in the endโ€ฆ building something that actually works in production.

๐Ÿ”— If you're learning DevOps

Donโ€™t just follow tutorials.

๐Ÿ‘‰ Break things
๐Ÿ‘‰ Fix them
๐Ÿ‘‰ Understand why

Thatโ€™s how you grow.

Top comments (0)