As a DevOps and cloud enthusiast, I wanted to go beyond theoretical knowledge and create something real. In this post, Iβll walk through how I provisioned infrastructure on AWS using Terraform and deployed a Dockerized app using GitHub Actions CI/CD. This project helped me apply core DevOps practices and build a production-ready pipeline from scratch.
π οΈ Stack Overview
- Terraform for infrastructure provisioning
- EC2 for hosting the app
- Docker to containerize the application
- GitHub Actions for CI/CD
- SCP + SSH for deployment automation
1οΈβ£ Infrastructure as Code with Terraform
I started by defining all infrastructure in Terraform to make deployments consistent and version-controlled. The configuration included:
- An EC2 instance with a public IP
- A security group allowing SSH (22), HTTP (80), and app port (4000)
- Optional Elastic Load Balancer for scalability
With reusable modules, I was able to spin up the entire environment with:
terraform init
terraform apply
2οΈβ£ Dockerizing the App
I deployed a simple Node.js app and containerized it using the following Dockerfile
:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 4000
CMD ["node", "app.js"]
Containerization ensured consistent behavior across dev and prod.
3οΈβ£ CI/CD with GitHub Actions
To automate deployment, I set up a GitHub Actions pipeline triggered on every push to main
. It:
- SSHs into the EC2 instance
- Sends code using
scp
- Builds and runs a Docker container remotely
Hereβs a simplified snippet of the deploy.yml
workflow:
name: Deploy to EC2
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up SSH
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > key.pem
chmod 600 key.pem
- name: Deploy App
run: |
scp -i key.pem -r . ubuntu@${{ secrets.EC2_HOST }}:/home/ubuntu/app
ssh -i key.pem ubuntu@${{ secrets.EC2_HOST }} '
cd app &&
docker build -t myapp . &&
docker stop myapp || true &&
docker rm myapp || true &&
docker run -d -p 4000:4000 --name myapp myapp
All secrets like the SSH key and host IP are stored securely in GitHub.
β Results
Once deployed, the app was accessible at:
http://<EC2_PUBLIC_IP>:4000
Each push to GitHub automatically redeploys the latest code, saving time and ensuring consistency.
π‘ Lessons Learned
- Terraform makes infra reproducible and scalable
- Docker simplifies app deployment
- GitHub Actions is powerful and integrates directly with your codebase
- Keeping sensitive values in
.env
and.env.example
is best practice
π What's Next?
Iβm planning to explore:
- Monitoring with CloudWatch
- Auto-scaling groups
- Using ECS or Fargate for container orchestration
π Resources
- GitHub Repo: ci-cd-pipeline-aws
- Live Demo:
http://<your-ec2-ip>:4000
βοΈ Let's Connect
If you're a solo dev or early-stage founder looking to deploy to AWS with CI/CD and infrastructure automation, I can help.
- Email: [email protected]
- LinkedIn: https://www.linkedin.com/in/kaustav-dey-107593244
- Portfolio Website: Kaustav Dey DevOps & Cloud Specialist | AWS β’ Docker β’ Terraform β’ CI/CDm
Top comments (1)
If you're a solo dev or early-stage founder looking to deploy to AWS with CI/CD and infrastructure automation be sure to reach out