Skip to content
Open

Lab06 #2858

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
55db2f8
Add solution to first lab
Daniil20xx Jan 28, 2026
5ce9e5f
Add solution to bonus task
Daniil20xx Jan 28, 2026
71a73e7
Add README.md
Daniil20xx Feb 3, 2026
67fd335
Add solution to task2
Daniil20xx Feb 3, 2026
9655d95
Add pytest to test code, tests for pytest and github workflow
Daniil20xx Feb 11, 2026
fdd5a79
Add pytest to test code, tests for pytest and github workflow
Daniil20xx Feb 11, 2026
43adf5f
update .gitignore
Daniil20xx Feb 11, 2026
d8b4b84
update yml
Daniil20xx Feb 11, 2026
c3473ca
Update yml; add first version of md
Daniil20xx Feb 11, 2026
a6bcd6e
Update yml; add first version of md
Daniil20xx Feb 11, 2026
b579d57
Update yml; add first version of md
Daniil20xx Feb 11, 2026
8201c26
Update yml; add first version of md
Daniil20xx Feb 11, 2026
c279429
Update yml; add first version of md
Daniil20xx Feb 11, 2026
68846d0
Update yml; add first version of md
Daniil20xx Feb 11, 2026
8bae40a
Add docker push only in main
Daniil20xx Feb 11, 2026
6f1d0b7
Add snyk test to yml
Daniil20xx Feb 11, 2026
21942db
Add snyk test to yml
Daniil20xx Feb 11, 2026
8a80aa8
bonus task
Daniil20xx Feb 11, 2026
015d3a1
bonus task
Daniil20xx Feb 11, 2026
31936e3
bonus task
Daniil20xx Feb 11, 2026
4254fe4
bonus task
Daniil20xx Feb 11, 2026
882a708
Remove bonus task
Daniil20xx Feb 11, 2026
43b143e
Add terrafrom and bonus task
Daniil20xx Feb 19, 2026
e7b11a4
update yml
Daniil20xx Feb 19, 2026
5de9128
update yml
Daniil20xx Feb 19, 2026
d06f938
update yml
Daniil20xx Feb 19, 2026
a145e61
update yml
Daniil20xx Feb 19, 2026
845b3f7
update yml
Daniil20xx Feb 19, 2026
f730455
update yml
Daniil20xx Feb 19, 2026
089ba6e
update yml
Daniil20xx Feb 19, 2026
0ae6db3
update yml
Daniil20xx Feb 19, 2026
e66cabb
update yml
Daniil20xx Feb 19, 2026
2a08d97
Add solution to lab5
Daniil20xx Feb 25, 2026
e1c2634
Add solution to lab6
Daniil20xx Mar 5, 2026
bac5682
Add solution to lab6
Daniil20xx Mar 5, 2026
338811c
Add solution to lab6
Daniil20xx Mar 5, 2026
bb24718
Add solution to lab6
Daniil20xx Mar 5, 2026
ff96221
Add solution to lab6
Daniil20xx Mar 5, 2026
465043f
Add solution to lab6
Daniil20xx Mar 5, 2026
165ca1b
Add solution to lab6
Daniil20xx Mar 5, 2026
df3a0c5
Add solution to lab6
Daniil20xx Mar 5, 2026
aca0620
Add solution to lab6
Daniil20xx Mar 5, 2026
09916ca
Add solution to lab6
Daniil20xx Mar 5, 2026
fcc889f
Add solution to lab6
Daniil20xx Mar 5, 2026
dcdbd4e
Add solution to lab6
Daniil20xx Mar 5, 2026
b139c24
Add solution to lab6
Daniil20xx Mar 5, 2026
cfb564c
Add solution to lab6
Daniil20xx Mar 5, 2026
292f866
Add solution to lab6
Daniil20xx Mar 5, 2026
ce58770
Add solution to lab6
Daniil20xx Mar 5, 2026
8f05cdc
Add solution to lab6
Daniil20xx Mar 5, 2026
1e289af
Add solution to lab6
Daniil20xx Mar 5, 2026
cae7a8c
Update LAB06.md with CI/CD section and issues
Daniil20xx Mar 5, 2026
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
Binary file added .coverage
Binary file not shown.
99 changes: 99 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Python CI

on:
push:
paths:
- 'app_python/**'
pull_request:
paths:
- 'app_python/**'

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r app_python/requirements.txt
pip install -r app_python/requirements-dev.txt

- name: Run linter
run: ruff check .

- name: Run pytest tests
run: |
pytest -v

- name: Install Snyk CLI
run: npm install -g snyk

- name: Run Snyk Test
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: snyk test app_python --severity-threshold=high

deploy:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Install Ansible
run: pip install ansible

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
aws-region: us-east-1

- name: Set up SSH key
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > key.pem
chmod 600 key.pem

- name: Prepare Password
run: |
echo "${{ secrets.ANSIBLE_PASSWORD }}" > pass.txt
chmod 600 pass.txt

- name: Create temporary inventory
env:
SERVER_IP: ${{ secrets.SERVER_IP }}
run: |
echo "[webservers]" > inventory.ini
echo "ubuntu ansible_host=$SERVER_IP ansible_user=ubuntu ansible_ssh_private_key_file=key.pem" >> inventory.ini
cat inventory.ini

- name: Ansible Run
run: |
ansible-playbook -i inventory.ini ./ansible/playbooks/deploy.yml \
--extra-vars "@ansible/group_vars/all.yml" \
--vault-password-file="pass.txt"

- name: Remove Password
run: |
rm pass.txt
rm key.pem


15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
test
# Python
__pycache__/
*.py[cod]
venv/
*.log
app_python/venv/
app_python/__pycache__/

# IDE
.vscode/
.idea/

# OS
.DS_Store
11 changes: 11 additions & 0 deletions ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[defaults]
inventory = inventory/hosts.ini
roles_path = roles
host_key_checking = False
remote_user = maior
retry_files_enabled = False

[privilege_escalation]
become = True
become_method = sudo
become_user = root
200 changes: 200 additions & 0 deletions ansible/docs/LAB05.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# Lab 5 — Ansible Fundamentals

## 1. Architecture Overview

* **Ansible version:** 2.16.14
* **Target VM OS:** Ubuntu 24.04 LTS
* **Role structure:**

```
ansible/
├── inventory/
│ └── hosts.ini # Static inventory
├── roles/
│ ├── common/ # Common system tasks
│ │ ├── tasks/
│ │ │ └── main.yml
│ │ └── defaults/
│ │ └── main.yml
│ ├── docker/ # Docker installation
│ │ ├── tasks/
│ │ │ └── main.yml
│ │ ├── handlers/
│ │ │ └── main.yml
│ │ └── defaults/
│ │ └── main.yml
│ └── app_deploy/ # Application deployment
│ ├── tasks/
│ │ └── main.yml
│ ├── handlers/
│ │ └── main.yml
│ └── defaults/
│ └── main.yml
├── playbooks/
│ ├── site.yml # Main playbook
│ ├── provision.yml # System provisioning
│ └── deploy.yml # App deployment
├── group_vars/
│ └── all.yml # Encrypted variables (Vault)
├── ansible.cfg # Ansible configuration
└── docs/
└── LAB05.md # Your documentation
```

**Why roles?**
Roles allow modular, reusable, and maintainable code. Each role encapsulates tasks, defaults, handlers, and variables, so playbooks remain clean.

# Command to run:
```bash
docker run -it --rm -v ${PWD}\app_python\ansible:/ansible -v C:\Users\maior\.ssh\vm_machine_ubuntu:/root/.ssh/vm_machine_ubuntu -w /ansible willhallonline/ansible:2.16-debian-bookworm-slim ` bash
```
---

## 2. Roles Documentation

### **2.1 Common Role**

* **Purpose:** Basic system provisioning (apt updates, packages, timezone)
* **Defaults:** `common_packages: [python3-pip, curl, git, vim, htop]`
* **Handlers:** None
* **Dependencies:** None

### **2.2 Docker Role**

* **Purpose:** Install and configure Docker engine
* **Defaults:** Docker version, user to add to `docker` group
* **Handlers:** `restart docker` — restarts Docker service if needed
* **Dependencies:** `common` role

### **2.3 App Deploy Role**

* **Purpose:** Deploy containerized Python app from previous labs
* **Defaults:**
* `app_name: devops-info-service`
* `docker_image_tag: latest`
* `app_port: 5000`
* `app_container_name: devops-info-service`
* link to image: https://hub.docker.com/r/daniil20xx/devops-info-service
* **Handlers:** `restart app container` — restarts app container if task triggers
* **Dependencies:** `docker` role

---

## 3. Idempotency Demonstration

### **3.1 Provisioning (common + docker)**

**First run:**

![playbook-1](/ansible/docs/screenshots/playbook-1.png)

* Tasks with **error** and **changes**

**Second run:**

![playbook-2](/ansible/docs/screenshots/playbook-2.png)


* Tasks with **changes**

**Third run:**

![playbook-3](/ansible/docs/screenshots/playbook-3.png)

* All tasks `ok` (green), `changed=0`
* Idempotency confirmed

### **3.2 Deployment (app_deploy)**

**First run:**

![docker-playbook-1](/ansible/docs/screenshots/docker-playbook-1.png)

* Docker container pulled and started
* `changed=3` (container creation, old container removal, docker login)
* `ignored=1`(container was not created yet)

**Second run:**

![docker-playbook-2](/ansible/docs/screenshots/docker-playhook-2.png)

* Many tasks `ok`, `changed=3`

**Third run:**

![docker-playbook-3](/ansible/docs/screenshots/docker-playhook-3.png)

* Many tasks `ok`, `changed=3`

**Analysis:**

##### changed=3 is repeated why:
- Stop existing container - the module checks if the container is running; even if the container is already running, Ansible marks the task as changed when bringing it to the desired state (e.g. restart or pull latest image).
- Remove old container - the old container is removed (if it is updated or recreated).
- Run container - a new container is created based on the latest image (if tag latest, Ansible pulls the latest image even when restarting).

---

## 4. Ansible Vault Usage

* Vault file: `group_vars/all.yml`

```yaml
dockerhub_username: daniil20xx
dockerhub_password: [HIDDEN]
app_name: devops-info-service
docker_image: "{{ dockerhub_username }}/{{ app_name }}"
docker_image_tag: latest
app_port: 5000
app_container_name: "{{ app_name }}"
```

* Vault password not committed to repo
* Deployed with:

```bash
ansible-playbook playbooks/deploy.yml --ask-vault-pass
```

* **Purpose:** Keep Docker Hub credentials secure
* **Best practice:** `no_log: true` prevents secrets from appearing in logs

---

## 5. Deployment Verification

**Check containers:**

![docker-check](/ansible/docs/screenshots/docker-check.png)

**Health check:**

![health-check](/ansible/docs/screenshots/working_url.png)

---

## 6. Key Decisions

* **Why use roles instead of plain playbooks?**
Roles separate concerns, making playbooks modular, reusable, and easier to maintain.

* **How do roles improve reusability?**
Each role encapsulates a repeatable task set, which can be reused in multiple projects.

* **What makes a task idempotent?**
Using stateful modules ensures tasks only make changes when necessary.

* **How do handlers improve efficiency?**
Handlers execute only when notified, avoiding unnecessary service restarts.

* **Why is Ansible Vault necessary?**
Vault securely stores credentials and sensitive variables, preventing secrets from leaking in version control.

---

## 7. Challenges

* Run `ansible` on Docker and move nessasary keys to it
* Connect to vm using ansible and ssh keys

---
Loading