Skip to content
291 changes: 174 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,178 +1,235 @@
## Supporting Courses and Builder's Community
<!-- ```markdown -->
# Ansible - Deploy mogombo ecommerce website ..!

* If you are looking for a structured course with step by step learning enroll into [Ultimate Jenkins Bootcamp by School of Devops.](https://www.udemy.com/course/ultimate-jenkins-bootcamp-by-school-of-devops/?referralCode=BAC80386E38F767AC155).
* Join [Devops Builders Community](https://bit.ly/4fHywt0) to connect with fellow builders.
* Subscribe to [Devops.Tube](https://devops.tube/) for devops learning.
## 1. Environment Setup (Docker Compose)

## Setup Jenkins with Docker
```bash
git clone https://github.com/DinukaSanjana/bootcamp.git
cd bootcamp/setup

Here you are going learn, how to setup jenkins using docker.
# Optional cleanup
docker compose down --rmi all --volumes --remove-orphans

Ensure that you have Docker Installed on your system. Refer to [Get Docker](https://docs.docker.com/get-docker/) for instructions on setting up Docker. Start by validing your environment with,

```
docker version
docker-compose
# Start the lab
docker compose up -d
```

The first command should show you both , client and server information. The second command should return the help menu for docker compose, which validate that you have Doker installed, started and docker-compose ready to go.

## 2. Docker Compose File Overview

Now, you could launch a jenkins container on your docker host by using recommended jenkins image similar to whats recommended in the official documentation [Docker](https://www.jenkins.io/doc/book/installing/docker/) using the following sequence of commands.
**File location:** `bootcamp/setup/docker-compose.yml`

```
git clone https://github.com/udbc/bootcamp.git
cd bootcamp/jenkins
docker compose build
docker compose up -d
```
```yaml
services:
control:
image: codespaces/ansible-control:3.0.0
ports:
- "8000:8000"
hostname: control
container_name: control

[output]

```
Creating network "jenkins_custom" with driver "bridge"
Creating volume "jenkins_jenkins-docker-certs" with default driver
Creating volume "jenkins_jenkins-data" with default driver
Pulling docker (docker:dind)...
dind: Pulling from library/docker
df20fa9351a1: Pull complete
25ad7478873d: Pull complete
4684f6177b5d: Pull complete
8ba584e970af: Pull complete
3cdc74d2b06d: Pull complete
4cf5a0d07c1f: Pull complete
fca0ccc462d5: Pull complete
8a08b8f19995: Pull complete
e60a2aec8c6b: Pull complete
84edc63b9e2e: Pull complete
a8919df01d06: Pull complete
Digest: sha256:973c39d7eadb05e45923173bc484961e5b6b527d8b0693c0881e07e9d2fa8ee7
Status: Downloaded newer image for docker:dind
Pulling jenkins (jenkinsci/blueocean:)...
latest: Pulling from jenkinsci/blueocean
df20fa9351a1: Already exists
1cb481a13af0: Pull complete
f5efbd400588: Pull complete
f2d0037ca04a: Pull complete
f50c4373c0c3: Pull complete
cfa42149c07e: Pull complete
e6784003bb85: Pull complete
73a1e720e18b: Pull complete
2e41633b95a1: Pull complete
83587819eac3: Pull complete
1389b752912a: Pull complete
feb326d4942c: Pull complete
05fc0701116d: Pull complete
06a6bc155e06: Pull complete
72b0e728c908: Pull complete
53b5c96969ae: Pull complete
Digest: sha256:257958006c0fa8fe499a40b8a6ea32c145a781f2d4cfda6efe67d5a56c022c78
Status: Downloaded newer image for jenkinsci/blueocean:latest
Creating jenkins_docker_1 ... done
Creating jenkins_jenkins_1 ... done
```
frontend:
image: codespaces/ansible-node-ubuntu:18.04
hostname: frontend

catalogue:
image: codespaces/ansible-node-ubuntu:18.04
hostname: catalogue

You could validate that Jenkins is setup along with Docker using the following command
carts:
image: codespaces/ansible-node-ubuntu:18.04
hostname: carts

```
docker compose ps
# Additional nodes: user, payment, orders, etc.
```

[output]
## 3. Containers Created by Docker Compose

```
Name Command State Ports
-------------------------------------------------------------------------------------------------------------
jenkins_docker_1 dockerd-entrypoint.sh Up 2375/tcp, 0.0.0.0:2376->2376/tcp
jenkins_jenkins_1 /sbin/tini -- /usr/local/b ... Up 0.0.0.0:50000->50000/tcp, 0.0.0.0:8080->8080/tcp
```
| Container Name | Image | Role | Access Method |
|----------------|----------------------------------|--------------------------|-----------------------------------|
| control | codespaces/ansible-control:3.0.0 | Ansible Control Node + Web IDE | http://<IP>:8000 |
| frontend | codespaces/ansible-node-ubuntu:18.04 | Managed Node | ssh devops@frontend |
| catalogue | codespaces/ansible-node-ubuntu:18.04 | Managed Node | ssh devops@catalogue |
| carts | codespaces/ansible-node-ubuntu:18.04 | Managed Node | ssh devops@carts |

You could now access jenkins UI by browsing to `http://IPADDRESS:8080`
## 4. Preparing & Opening Ansible Control Node

![](jenkins2.png)
```bash
# Open in browser
http://<YOUR_SERVER_IP>:8000
# Example: http://159.65.77.142:8000
```
→ Opens Theia (VS Code-based) Web IDE → This is your Ansible Control Node

## 5. Inside Control Node - Initial Setup

To fetch the initialAdminPassword use the following command
```bash
# Clone project
git clone https://github.com/DinukaSanjana/bootcamp.git
cd bootcamp/ansible

# Verify Ansible
ansible --version
# ansible 2.9.10
```
docker compose logs jenkins
```

[sample output]
## 6. Test Connectivity

```bash
ansible all -m ping
```
→ Should return green "pong" from all nodes

2020-02-09 14:42:40.900+0000 [id=28] INFO jenkins.install.SetupWizard#init:
## 7. Inventory File & Path

*************************************************************
*************************************************************
*************************************************************
**Location:** `/root/workspace/bootcamp/ansible/ansible.cfg` (config points to default inventory)

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
**Actual inventory used:** Dynamic inventory via Docker network + `/etc/ansible/hosts` or embedded in `ansible.cfg`

4856656f53ea4c76a5cca69dfda5656f
**Sample host entry format used in lab:**
```ini
frontend ansible_host=frontend ansible_user=devops ansible_ssh_pass=codespaces
```

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
## 8. SSH to Managed Nodes

*************************************************************
*************************************************************
*************************************************************
```bash
ssh devops@frontend # Password: codespaces
ssh devops@carts
ssh devops@catalogue
```

2020-02-09 14:42:51.261+0000 [id=28] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
Check service after playbook run:
```bash
sudo systemctl status nginx
```

## 9. Ad-hoc Commands Executed

Copy the exact password that you see on your screen and paste it on the Jenkins UI to unlock.
```bash
# Check uptime on all nodes
ansible all -a "uptime"

# Check disk usage
ansible all -a "df -h"

# Reboot all nodes
ansible all -a "/sbin/reboot" --forks=10
```

In the next step , choose install suggested plugins to configure the default plugins automatically.
## 10. Run Ansible Playbooks

![](Screenshot%202019-08-07%2014.46.27.png)
```bash
cd ~/bootcamp/ansible

You can also observe the progress of plugins installation process as follows,
ansible-playbook frontend.yml
ansible-playbook catalogue.yml
ansible-playbook carts.yml
ansible-playbook mogambo.yml
```

## 11. Ansible Roles - Project Structure

![](Screenshot%202019-08-07%20at%202.49.49%20PM.png)
**Path:** `roles/`

If the plugins installation process fails, you could retry it.
```bash
roles/
├── frontend/
│ ├── tasks/
│ │ └── main.yml
│ ├── handlers/
│ │ └── main.yml
│ ├── templates/
│ ├── files/
│ ├── vars/
│ │ └── main.yml
│ └── defaults/
│ └── main.yml
├── catalogue/
├── carts/
└── common/
```

Once plugins are installed, you will create the admin user using the form presented.
## 12. Normal Playbook vs Large Project (Roles-Based)

| Type | Structure | Use Case |
|-----------------------|-------------------------------------------|--------------------------------|
| Simple Playbook | All tasks, vars, templates in one .yml | Small scripts, demos |
| Large Project (Roles) | Separated: tasks, vars, templates, handlers, files | Reusable, modular, maintainable, team-friendly |

![](Screenshot%202019-08-07%20at%202.51.05%20PM.png)
## 13. Generate New Role

```bash
ansible-galaxy init --offline roles/frontend
ansible-galaxy init --offline roles/catalogue
```

completing this process will get you to jenkins configuration page, and continuing that will take you to the main page where you could get started creating jobs from.
Creates full role directory structure automatically.

## Stopping, Starting and Resetting Jenkins
## 14. Playbook Using Roles

While you start building your Continuous Integration workflows, there would be times when you would need to stop and start this environment e.g. you shut down your laptop at the end of the day and then start if the next day, and you would want your learning lab environment to be back up and running.
```yaml
# frontend.yml
- name: Deploy Frontend Service
hosts: frontend
become: yes
roles:
- common
- nginx
- frontend
```

This can be achieved by gracefully stopping your lab environment with,
## 15. Full Playbook Structure Used

```
docker compose stop
ansible.cfg
environments/
group_vars/
hosts # inventory (if static)
roles/
└── <role_name>/
├── tasks/
├── handlers/
├── templates/
├── files/
├── vars/
└── defaults/
frontend.yml
catalogue.yml
carts.yml
mogambo.yml # Master playbook
```

and then when you start your system, by executing
## 16. Deploy mogambo.org E-commerce Website

```
docker compose up -d
```bash
ansible-playbook mogambo.yml
```

Ensure both the commands are run from the same path where `docker-compose.yaml` for this project exist e.g. `.../bootcamp/jenkins` .
After successful run → Open in browser:

**Website URL:**
`http://<YOUR_SERVER_PUBLIC_IP>:80`

If you ever need to reset this environment completely follow this process,
**Services deployed:**
- Nginx (port 80)
- Node.js apps (frontend, catalogue, carts)
- MongoDB
- Full mogambo.org e-commerce site running

```
cd bootcamp/jenkins
docker compose down
docker volume rm jenkins_jenkins-data jenkins_jenkins-docker-certs
docker compose build
docker compose up -d
```
Accessible via: `http://<VM_PUBLIC_IP>:80`

## Final Status: Completed

- Full multi-node Ansible lab running via Docker Compose
- Web-based control node at port 8000
- All nodes reachable via `ansible all -m ping`
- Roles-based, clean, reusable playbook structure
- Successfully deployed full-stack mogambo.org website
- Used ad-hoc commands, inventory, roles, handlers, templates

**Project Completed Successfully**
**Live Site:** http://<YOUR_IP>:80
**Control Panel:** http://<YOUR_IP>:8000

Do note we are deleting the volumes which are shared between docker and jenkins containers. This is been designed so that even if you restart or recreate the containers, you do not loose your jobs etc. Only when you want to reset (starting from scratch again) should you use this sequence of instructions.
Ready for production-grade Ansible automation!
Loading