From 16b0ada25b760a7857c4aa78c8ba257c13e40f26 Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Sat, 13 Dec 2025 21:56:00 +0700 Subject: [PATCH 1/6] Add CI workflow --- .github/workflows/ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..facc698691 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI Pipeline + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + + - name: Install dependecies (vote app) + run: | + cd vote + pip install -r requirement.txt + + - name: Run simple test + run: | + cd vote + python -m py_compile app.py \ No newline at end of file From 45f75ceaf1999006ee864842016da2e48942d003 Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Sat, 13 Dec 2025 23:28:21 +0700 Subject: [PATCH 2/6] Fix CI trigger and workflow steps --- .github/workflows/ci.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index facc698691..2640007811 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - devops-task pull_request: branches: - main @@ -18,13 +19,15 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 + with: + python-version: '3.11' - - name: Install dependecies (vote app) + - name: Install dependencies (vote app) run: | - cd vote - pip install -r requirement.txt - + cd vote + pip install -r requirements.txt + - name: Run simple test run: | - cd vote - python -m py_compile app.py \ No newline at end of file + cd vote + python3 -m py_compile app.py From a9e3c0f42e1c32635e6b71ffbef60c04cc802ccf Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Mon, 15 Dec 2025 01:46:55 +0700 Subject: [PATCH 3/6] Add containerization explanation for task 2 --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 8516424ba1..df8156715e 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,15 @@ The voting application only accepts one vote per client browser. It does not reg This isn't an example of a properly architected perfectly designed distributed app... it's just a simple example of the various types of pieces and languages you might see (queues, persistent data, etc), and how to deal with them in Docker at a basic level. + +# For task-2 (containerization): +This application is fully containerized using Docker. Each service: vote, result, worker has its own Dockerfile. + +To ensure minimal image size and follow Docker best practices: +- Slim base images are used: node:18-slim, postgre:15-alpine +- Multi-stage build are implemented for the .NET worker service to separate build-time & runtime dependencies +- Package manager cacher are straight cleaned after installation to reduce image size +- Only required runtime files are included in the final images + +The application can be run locally using Docker Compose with a single command: +docker compose up --build From 2ac03f92ff1a4030f78b8ee3c6c6d03a6d4547e6 Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Mon, 15 Dec 2025 13:09:37 +0700 Subject: [PATCH 4/6] Add ansible playbook for infrastructure setup: Task 3 --- README.md | 6 ++++++ ansible/inventory.ini | 2 ++ ansible/playbook.yml | 28 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 ansible/inventory.ini create mode 100644 ansible/playbook.yml diff --git a/README.md b/README.md index df8156715e..863225460a 100644 --- a/README.md +++ b/README.md @@ -75,3 +75,9 @@ To ensure minimal image size and follow Docker best practices: The application can be run locally using Docker Compose with a single command: docker compose up --build + +# For task-3: Infrastructure as Code (IaC) +This project uses Ansible to demonstrate IaC principles. +A simple ansible playbook is provided to automate envrionment checks on a local machine. +- inventory.ini = to defines the target host, which in this project i only use localhost +- playbook.yml = contains automated tasks in Ansible version to verify Docker installation diff --git a/ansible/inventory.ini b/ansible/inventory.ini new file mode 100644 index 0000000000..8a4cd2230c --- /dev/null +++ b/ansible/inventory.ini @@ -0,0 +1,2 @@ +[app] +localhost ansible_connection=local \ No newline at end of file diff --git a/ansible/playbook.yml b/ansible/playbook.yml new file mode 100644 index 0000000000..37c2bbd418 --- /dev/null +++ b/ansible/playbook.yml @@ -0,0 +1,28 @@ +- name: Setup environment for Example Voting App + hosts: app + become: true + + tasks: + - name: Ensure required packages are installed + apt: + name: + - docker.io + - docker-compose + state: present + update_cache: yes + + - name: Ensure Docker service is running + service: + name: docker + state: started + enabled: true + + - name: Pull application images + command: docker compose pull + args: + chdir: /opt/example-voting-app + + - name: Run application with Docker Compose + command: docker compose up -d + args: + chdir: /opt/example-voting-app From 1bae2d6c1611177921e81e9b1e3cc16aeb7f2312 Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Mon, 15 Dec 2025 13:30:01 +0700 Subject: [PATCH 5/6] Add monitoring plan --- result/monitoring_plan.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 result/monitoring_plan.md diff --git a/result/monitoring_plan.md b/result/monitoring_plan.md new file mode 100644 index 0000000000..b85c836bdd --- /dev/null +++ b/result/monitoring_plan.md @@ -0,0 +1,29 @@ +# Monitoring Plan - for Example Voting App + +Tools +- Prometheus for collecting metrics +- Grafana for visualization and dashboards +- Alertmanager for alert notifications +- Docker metrics via cAdvisor + +Metrics to Monitor +- CPU and memory usage per container +- Container uptime and restart count +- HTTP request rate and response time +- Error rate (4xx or 5xx) +- Redis and PostgreSQL availability + +Alerting Strategy +- Alert if CPU usage > 80% for more than 5 minutes +- Alert if any container is down +- Alert if application endpoints are not reachable +- Alert if error rate exceeds defined threshold + +Example Prometheus Configuration (in Pseudocode): +- alert: HighCPUUsage + expr: cpu_usage > 80 + for: 5m + labels: + severity: warning + annotations: + description: CPU usage is above 80% \ No newline at end of file From 1e2ea2462ec99ad0e9d26fc9fb5b68c01c88465a Mon Sep 17 00:00:00 2001 From: Nur Farhayati Date: Mon, 15 Dec 2025 13:49:37 +0700 Subject: [PATCH 6/6] Update README --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 863225460a..bc4cead037 100644 --- a/README.md +++ b/README.md @@ -64,13 +64,16 @@ This isn't an example of a properly architected perfectly designed distributed a example of the various types of pieces and languages you might see (queues, persistent data, etc), and how to deal with them in Docker at a basic level. +# For task-1 (CI/CD and Version Control) +For CI/CD, i use GitHub actions because it is tightly integrated with GitHub repositories and its easy to configure. The pipeline is triggered on push and pull request events to the main branch. It will perfoms basic checks such as installing dependencies and running a simple validation that will command to ensure the application code does not contain syntax errors + # For task-2 (containerization): This application is fully containerized using Docker. Each service: vote, result, worker has its own Dockerfile. To ensure minimal image size and follow Docker best practices: -- Slim base images are used: node:18-slim, postgre:15-alpine +- Slim base images are used: node:18-slim, postgres:15-alpine - Multi-stage build are implemented for the .NET worker service to separate build-time & runtime dependencies -- Package manager cacher are straight cleaned after installation to reduce image size +- Package manager cache are straight cleaned after installation to reduce image size - Only required runtime files are included in the final images The application can be run locally using Docker Compose with a single command: @@ -81,3 +84,11 @@ This project uses Ansible to demonstrate IaC principles. A simple ansible playbook is provided to automate envrionment checks on a local machine. - inventory.ini = to defines the target host, which in this project i only use localhost - playbook.yml = contains automated tasks in Ansible version to verify Docker installation + +# For task-4: Monitoring & Logging +- i choose prometheus for metrics collection because its wide ecosystem and strong docker support, while Grafana is used for visualization and dashboards. + +# Improvements with More Time +- i will add automated test cases (unit and integration test) to the CI pipeline +- also deploy the application to a cloud environment using terraform +- also add authentication and authorization to application \ No newline at end of file