Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 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
93b90a8
Add solution to lab07
Daniil20xx Mar 12, 2026
94dfb1d
Add solution to lab8
Daniil20xx Mar 19, 2026
7b2eda0
Add solution to lab 9
Daniil20xx Mar 26, 2026
d8f0a1c
Add solution to lab10
Daniil20xx Apr 2, 2026
7e1cb40
Add solution to lab 12
Daniil20xx Apr 16, 2026
b2229bb
Add solution to lab 12
Daniil20xx Apr 16, 2026
68573e8
Add solution to lab 12
Daniil20xx Apr 16, 2026
92c37cf
Add solution to lab 12
Daniil20xx Apr 16, 2026
2364cc9
Add solution to lab 12
Daniil20xx Apr 16, 2026
94b92b9
Add solution to lab 12
Daniil20xx Apr 16, 2026
607a064
Change image to nginx for testing self-healing
Daniil20xx Apr 23, 2026
a1149ae
Add solution
Daniil20xx Apr 23, 2026
83eba46
fix bugs
Daniil20xx Apr 23, 2026
f9fd35b
Fix bugs
Daniil20xx Apr 23, 2026
46dcd22
fix
Daniil20xx Apr 23, 2026
c068b12
Fix bugs
Daniil20xx Apr 24, 2026
a1e9eb5
Chage replicaCount from 2 to 1
Daniil20xx Apr 24, 2026
83466fa
Add solution to lab
Daniil20xx Apr 24, 2026
d7c0fc4
Add solution to lab 14
Daniil20xx May 1, 2026
d007c9f
Add solution to lab15
Daniil20xx May 6, 2026
a4fa86c
Add solution to lab 16
Daniil20xx May 12, 2026
07ef3c2
Add solution to lab 16
Daniil20xx May 12, 2026
d5d5081
Add solution to lab17
Daniil20xx May 13, 2026
8ca4961
Add solution to lab17
Daniil20xx May 13, 2026
099f656
Add solution to lab18
Daniil20xx May 14, 2026
1a37edd
Update submission18.md
Daniil20xx May 14, 2026
6c93bd6
Remove bonus task from submission structure
Daniil20xx May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
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


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

# IDE
.vscode/
.idea/

# OS
.DS_Store

# Env
.env
venv/
.venv/
app_python/**/venv/

# Other
*.log
*.zip
labs/lab18/app_python/result
1 change: 1 addition & 0 deletions .pytest_cache/v/cache/nodeids
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions .pytest_cache/v/cache/stepwise
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
197 changes: 197 additions & 0 deletions ARGOCD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Lab 13 — GitOps with ArgoCD

## Task 1 — ArgoCD Installation & Setup

### 1.1 Install ArgoCD via Helm

1. Add the ArgoCD Helm repository:
![Screenshot: Add Helm repo](/docs_lab13/screenshots/helm_repo_add_argo.png)

2. Create dedicated namespace and install ArgoCD:
![Screenshot: Create namespace](/docs_lab13/screenshots/kubectl_create_namespace_argocd.png)

3. Verify all pods are ready:
All components should show `Running` status.

### 1.2 Access ArgoCD UI

1. Set up port forwarding to access the web interface:
![Screenshot: Port forwarding](/docs_lab13/screenshots/task2_port_forward_1.png)

2. Retrieve the initial admin password:
![Screenshot: Get password](/docs_lab13/screenshots/task2_get_pswrd.png)

3. Access ArgoCD at `https://localhost:8080` in your browser:
![Screenshot: UI login page](/docs_lab13/screenshots/task2_app_test_ui.png)

4. Log in with credentials:
- Username: `admin`
- Password: `pfZ3jJ3qkuw5l5qo`
![Screenshot: After login](/docs_lab13/screenshots/task2_after_login.png)

### 1.3 Install ArgoCD CLI

1. Download the CLI for your platform (Windows):
```PowerShell
Invoke-WebRequest -Uri "https://github.com/argoproj/argo-cd/releases/latest/download/argocd-windows-amd64.exe" -OutFile "argocd.exe"
```

2. Log in via CLI:
![0](/docs_lab13/screenshots/login_via_cl.png)

3. Verify CLI connection:
![1](/docs_lab13/screenshots/agrocd_version.png)
![2](/docs_lab13/screenshots/agrocd_user.png)


## Task 2 — Application Deployment

### 2.1 ArgoCD Application Manifests

All application manifests are stored in `k8s/argocd/`:

- **`application.yaml`** - Basic application in default namespace (for testing)
- **`application-dev.yaml`** - Dev environment with auto-sync enabled
- **`application-prod.yaml`** - Prod environment with manual sync only
- **`applicationset.yaml`** - ApplicationSet for automated generation of dev/prod apps (bonus)

### 2.2 Application Manifest Example

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: python-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/Daniil20xx/DevOps-Core-Course.git
targetRevision: lab12
path: k8s/mychart
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
syncOptions:
- CreateNamespace=true
```

### 2.3 Deploy the Application

Apply the application manifest:
![1](/docs_lab13/screenshots/task2_k8s_apply.png)

Monitor the deployment:
![2](/docs_lab13/screenshots/task2_lifecheck.png)

### 2.5 Perform Initial Sync

Trigger manual sync via CLI:
![sync_after_change_2](/docs_lab13/screenshots/to_1-sync_after_change_2.png)

Verify resources are created:
![task2_heakth_check](/docs_lab13/screenshots/task2_heakth_check.png)

Verify that 1 replica:
![after_change_2_to_1](/docs_lab13/screenshots/after_change_2_to_1.png)


## Task 3 — Multi-environment deployment (dev/prod)

### 3.1 Create namespaces

![apply_namespace](/docs_lab13/screenshots/apply_namespace.png)

### 3.2 Create ArgoCD Applications for dev/prod

```bash
kubectl apply -f k8s/argocd/applicationset.yaml
```

App list:
![app_list](/docs_lab13/screenshots/app_list.png)

Sync prod:
```bash
argocd app sync devops-info-service-prod
```

![task3_verify_deplay](/docs_lab13/screenshots/task3_verify_deplay.png)
![task3_verify_prod](/docs_lab13/screenshots/task3_verify_prod.png)

*If apps show `OutOfSync` + `Missing`, it only means resources are not created yet.*

### 3.3 Dev vs Prod differences
### 3.4 Why prod stays manual

## Task 4 — Self-healing & drift tests (dev)

### 4.1 Self-healing test: manual scale

![task4_scale_deployment](/docs_lab13/screenshots/task4_scale_deployment.png)
![task4_diff](/docs_lab13/screenshots/task4_diff.png)

- Manually scaled deployment to new count of replicas.
- ArgoCD detected configuration drift

### 4.2 Pod deletion test (Kubernetes behavior)
![task4_diff](/docs_lab13/screenshots/task4_diff.png)
![task4_pod_deletion](/docs_lab13/screenshots/task4_pod_deletion.png)

- I manually deleted the pod using `kubectl delete pod`
- Kubernetes automatically recreated the pod via the ReplicaSet
- This is Kubernetes built-in self-healing capability, not ArgoCD


### 4.3 Configuration drift test (ArgoCD behavior)

```bash
kubectl annotate deploy -n dev python-app-dev-mychart drift-ts="$(date +%s)" --overwrite
# deployment.apps/python-app-dev-mychart annotated

# Observation: in this cluster/ArgoCD setup, changing top-level Deployment metadata annotations
# did not immediately flip the app to OutOfSync (depends on tracking method), and behavior may vary:

kubectl get deploy -n dev python-app-dev-mychart \
-o jsonpath='{.metadata.annotations.drift-ts}{"\n"}'
# 1777066438

argocd app get python-app-dev --refresh | grep -E "Sync Status|Health Status" || true
# Sync Status: Synced ...
# Health Status: Healthy

sleep 8

kubectl get deploy -n dev python-app-dev-mychart \
-o jsonpath='{.metadata.annotations.drift-ts}{"\n"}' || true
# 1777066438


# Reliable drift for evidence (replicas change):
kubectl patch deployment python-app-dev-mychart -n dev \
--type merge -p '{"spec":{"replicas":5}}'

# Immediately after patch (before self-heal):
kubectl get deploy -n dev python-app-dev-mychart \
-o jsonpath='{.spec.replicas}{"\n"}'
# 5

# ArgoCD detects drift and (with self-heal enabled OR during next reconciliation loop) reverts it:
argocd app diff python-app-dev || true

sleep 10

argocd app get python-app-dev --refresh | grep -E "Sync Status|Health Status" || true
# Sync Status: Synced ...
# Health Status: Healthy

kubectl get deploy -n dev python-app-dev-mychart \
-o jsonpath='{.spec.replicas}{"\n"}'
# 1
```

### 4.4 When does ArgoCD sync and how often it checks Git?
Loading
Loading