Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Deploy Documentation

on:
push:
branches:
- main
paths:
- 'README.md'
- '.github/workflows/deploy-docs.yml'

permissions:
contents: read
pages: write
id-token: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: '.'

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Terraform
**/.terraform/*
*.tfstate
*.tfstate.*
*.tfvars
.terraform.lock.hcl

# Terraform backups
*.backup

# Sensitive files
*.pem
*.key

# Ansible
*.retry

# IDE
.vscode/
.idea/

# OS
.DS_Store
Thumbs.db
199 changes: 199 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,202 @@

# DevOps Bootcamp Project

This repository contains my DevOps bootcamp learning materials and projects.

# DevOps Bootcamp Final Project

## Project Overview
This project demonstrates a complete DevOps infrastructure deployment using industry-standard tools and practices.

**Student Name**: KHAIRUL MUJAHID
**Project Name**: Trust Me, I'm a DevOps Engineer
**Date**: January 2025

## 🌐 Live Deployments

- **Web Application**: https://web.muja-net.com
- **Monitoring Dashboard**: https://monitoring.muja-net.com
- Username: `admin`
- Password: `admin123`

## 📋 Project Architecture

### Infrastructure Components

- **Cloud Provider**: AWS (ap-southeast-1)
- **VPC CIDR**: 10.0.0.0/24
- Public Subnet: 10.0.0.0/25
- Private Subnet: 10.0.0.128/25

### Server Instances

1. **Web Server** (Public Subnet)
- Instance Type: t3.micro
- OS: Ubuntu 24.04
- Private IP: 10.0.0.5
- Public IP: 52.220.53.85
- Purpose: Hosts containerized web application

2. **Ansible Controller** (Private Subnet)
- Instance Type: t3.micro
- OS: Ubuntu 24.04
- Private IP: 10.0.0.135
- Purpose: Configuration management automation

3. **Monitoring Server** (Private Subnet)
- Instance Type: t3.micro
- OS: Ubuntu 24.04
- Private IP: 10.0.0.136
- Purpose: Hosts Prometheus and Grafana

## 🛠️ Technologies Used

### Infrastructure as Code
- **Terraform**: Provision all AWS resources
- **AWS Services**: VPC, EC2, S3, ECR, IAM, Systems Manager

### Configuration Management
- **Ansible**: Automated server configuration and application deployment

### Containerization
- **Docker**: Application containerization
- **Amazon ECR**: Container registry

### Monitoring
- **Prometheus**: Metrics collection
- **Grafana**: Metrics visualization
- **Node Exporter**: System metrics exporter

### Security & Access
- **AWS Systems Manager (SSM)**: Secure server access
- **Cloudflare**: DNS management and tunnel for secure Grafana access

## 🚀 Deployment Steps

### 1. Infrastructure Provisioning (Terraform)
```bash
cd terraform
terraform init
terraform plan
terraform apply
```

**Resources Created:**
- VPC with public and private subnets
- Internet Gateway and NAT Gateway
- Security Groups
- 3 EC2 instances (Web, Ansible Controller, Monitoring)
- ECR repository
- IAM roles for SSM access

### 2. Configuration Management (Ansible)
```bash
cd ansible
ansible-playbook -i inventory.ini playbooks/install-docker.yml
ansible-playbook -i inventory.ini playbooks/deploy-application.yml
ansible-playbook -i inventory.ini playbooks/deploy-node-exporter.yml
ansible-playbook -i inventory.ini playbooks/deploy-prometheus.yml
ansible-playbook -i inventory.ini playbooks/deploy-grafana.yml
```

### 3. Application Deployment

- Built Docker image from source code
- Pushed to Amazon ECR
- Deployed on web server using Ansible
- Accessible via https://web.yourdomain.com

### 4. Monitoring Setup

- **Prometheus**: Scrapes metrics from Node Exporter on web server
- **Grafana**: Visualizes CPU, Memory, and Disk usage
- **Access**: Secured via Cloudflare Tunnel (no public exposure)

## 📊 Monitoring Metrics

The following metrics are collected and visualized:

- **CPU Usage**: Real-time processor utilization
- **Memory Usage**: RAM consumption and availability
- **Disk Usage**: Storage utilization of root filesystem
- **Network I/O**: Network traffic statistics

## 🔐 Security Implementation

1. **Network Segmentation**:
- Web server in public subnet (internet-facing)
- Ansible and monitoring servers in private subnet (no direct internet access)

2. **Security Groups**:
- Web server: Allows HTTP (80) from anywhere, SSH from VPC only
- Private servers: SSH from VPC only

3. **Access Control**:
- AWS SSM for secure server access (no SSH keys exposed)
- Cloudflare Tunnel for secure Grafana access
- IAM roles for ECR access

4. **SSL/TLS**:
- Cloudflare provides SSL certificates
- HTTPS enforced for all web traffic

## 📁 Repository Structure
```
devops-bootcamp-project/
├── terraform/
│ ├── main.tf # Main infrastructure configuration
│ ├── variables.tf # Variable definitions
│ ├── outputs.tf # Output values
│ ├── provider.tf # Provider configuration
│ └── backend.tf # S3 backend configuration
├── ansible/
│ ├── inventory.ini # Ansible inventory
│ ├── playbooks/
│ │ ├── install-docker.yml
│ │ ├── deploy-application.yml
│ │ ├── deploy-node-exporter.yml
│ │ ├── deploy-prometheus.yml
│ │ └── deploy-grafana.yml
│ ├── group_vars/
│ │ └── web_servers.yml
│ └── prometheus.yml # Prometheus configuration
├── .gitignore
└── README.md # This file
```

## 🔄 CI/CD Pipeline

GitHub Actions workflow automatically updates this documentation on GitHub Pages when changes are pushed to the main branch.

## 📝 Lessons Learned

1. Infrastructure as Code enables reproducible deployments
2. Ansible simplifies configuration management across multiple servers
3. Container orchestration improves application portability
4. Proper monitoring is essential for production systems
5. Security should be implemented at every layer

## 🎯 Project Completion Checklist

- ✅ Infrastructure provisioned with Terraform
- ✅ Servers configured with Ansible
- ✅ Docker installed on all servers
- ✅ Application containerized and deployed
- ✅ ECR repository created and image pushed
- ✅ Prometheus collecting metrics
- ✅ Grafana dashboards configured
- ✅ Node Exporter monitoring web server
- ✅ Cloudflare DNS configured
- ✅ Cloudflare Tunnel securing Grafana access
- ✅ Documentation published on GitHub Pages
- ✅ SSM access enabled on all servers

## 📧 Contact

**Name**: MUHAMMAD KHAIRUL MUJAHID BIN ZAKARIA
**Email**: khairulmujahid92@gmail.com
**GitHub**: https://github.com/muzadp

---

*This project was completed as part of the DevOps Bootcamp Final Project - January 2025*
6 changes: 6 additions & 0 deletions ansible/group_vars/web_servers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
ecr_repository_url: "175558635506.dkr.ecr.ap-southeast-1.amazonaws.com/devops-bootcamp/final-project-mujadp"
aws_region: "ap-southeast-1"
aws_account_id: "175558635506"
app_name: "my-devops-app"
app_port: 80
11 changes: 11 additions & 0 deletions ansible/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[web_servers]
web-server ansible_host=10.0.0.5

[monitoring_servers]
monitoring-server ansible_host=10.0.0.136

[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/ansible_key
ansible_python_interpreter=/usr/bin/python3
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
101 changes: 101 additions & 0 deletions ansible/playbooks/deploy-application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
- name: Deploy application on web server
hosts: web_servers
become: yes
vars_files:
- ../group_vars/web_servers.yml
tasks:
- name: Install prerequisites for AWS CLI
apt:
name:
- unzip
- curl
state: present
update_cache: yes

- name: Check if AWS CLI v2 is installed
command: aws --version
register: aws_cli_check
ignore_errors: yes
changed_when: false

- name: Download AWS CLI v2
get_url:
url: https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip
dest: /tmp/awscliv2.zip
mode: '0644'
when: aws_cli_check.rc != 0

- name: Unzip AWS CLI v2
unarchive:
src: /tmp/awscliv2.zip
dest: /tmp/
remote_src: yes
when: aws_cli_check.rc != 0

- name: Install AWS CLI v2
command: /tmp/aws/install
args:
creates: /usr/local/bin/aws
when: aws_cli_check.rc != 0

- name: Clean up AWS CLI installation files
file:
path: "{{ item }}"
state: absent
loop:
- /tmp/awscliv2.zip
- /tmp/aws
when: aws_cli_check.rc != 0

- name: Create AWS credentials directory for root user
file:
path: /root/.aws
state: directory
owner: root
group: root
mode: '0755'

- name: Copy AWS credentials to root
copy:
src: ~/.aws/credentials
dest: /root/.aws/credentials
owner: root
group: root
mode: '0600'

- name: Copy AWS config to root
copy:
src: ~/.aws/config
dest: /root/.aws/config
owner: root
group: root
mode: '0600'

- name: Login to ECR
shell: |
aws ecr get-login-password --region {{ aws_region }} | docker login --username AWS --password-stdin {{ aws_account_id }}.dkr.ecr.{{ aws_region }}.amazonaws.com

- name: Pull Docker image from ECR
docker_image:
name: "{{ ecr_repository_url }}"
tag: latest
source: pull
force_source: yes

- name: Stop and remove existing container
docker_container:
name: "{{ app_name }}"
state: absent
ignore_errors: yes

- name: Run application container
docker_container:
name: "{{ app_name }}"
image: "{{ ecr_repository_url }}:latest"
state: started
restart_policy: always
ports:
- "{{ app_port }}:80"
env:
NODE_ENV: production
Loading