Tools: π 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. 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 provisioningAnsible β Configuration & deploymentAWS (EC2 + RDS) β HostingPM2 + 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 appRDS (MySQL) β Stores data (private subnet)Nginx β Reverse proxyPM2 β Keeps Node.js runningβοΈ Step 1: Provision Infrastructure with Terraform First, I navigated into my Terraform directory: Then initialized Terraform: And applied the infrastructure: terraform applyβ οΈ First Major ProblemError: 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 subnetsDifferent AZsβ Output ec2_public_ip = "13.x.x.x"rds_endpoint = "epicbook-db.xxxxx.amazonaws.com:3306"π Step 2: Connect to EC2ssh -i ~/.ssh/key.pem ubuntu@βοΈ Step 3: Install Ansiblesudo apt updatesudo apt install ansible-core -y ansible --versionβ οΈ Error I Hitansible-playbook: command not found π‘ Fix: Install Ansible (itβs not pre-installed). π€ Step 4: Run Ansible Playbookcd ansibleansible-playbook -i inventory.ini site.yml Nginx setupApp deploymentDB configurationπ¦ Step 5: Application Setup git clone npm installsudo 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 #1ECONNREFUSED 127.0.0.1:3306 π‘ Cause:App was trying to connect to localhost Passed environment variables:DB_HOST β RDS endpointDB_NAME β bookstoreβοΈ Step 7: Configure App Using Ansible template: template: src: config.json.j2 dest: /var/www/epicbook/config/config.jsonβ οΈ Errorconfig.json.j2 not found π‘ Fix:Create the file here: roles/epicbook/templates/config.json.j2π Step 8: Run App with PM2npm install -g pm2pm2 start server.js --name epicbookpm2 saveβ οΈ Issuepm2 delete epicbook β not found ignore_errors: trueποΈ Step 9: Database Schema & Seeding This was the trickiest part. mysql -h -u admin -p bookstore < BuyTheBook_Schema.sql mysql -h -u admin -p bookstore < author_seed.sqlmysql -h -u admin -p bookstore < books_seed.sqlβ οΈ Issue #1Table 'books' doesn't exist π‘ Fix:Schema must run before seeding β οΈ Issue #2Unknown database 'bookstore' Standardised DB name across:TerraformAnsibleSQL filesβ οΈ Issue #3Table already exists π‘ Fix:Make tasks idempotent: ignore_errors: yesπ Final Result β And finallyβ¦π Books were displaying from the database That moment? Worth every error. π§ What This Project Taught MeTerraform is for infrastructure, not configurationAnsible eliminates manual setup (when done right) DB β Config β App β SeedDebugging is a core DevOps skillSmall misconfigurations (like DB name) can break everythingπ‘ What Iβd Improve NextUse Ansible MySQL modules instead of shellAdd Load Balancer (ALB)Implement Auto ScalingStore secrets in AWS Secrets ManagerAdd CI/CD pipelineπ Final Thoughts This wasnβt just a deployment project. It was a real-world DevOps experience: Broken configsDebugging under pressureFixing 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 Templates let you quickly answer FAQs or store snippets for re-use. as well , this person and/or