Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
81ab248
feat: implement lab01 devops info service
acecution Jan 28, 2026
d994dea
Update README.md
acecution Jan 28, 2026
926fb20
Update LAB01.md
acecution Jan 28, 2026
df68271
Update README.md
acecution Jan 28, 2026
58a30f0
Update LAB01.md
acecution Jan 28, 2026
17145cd
lab2
acecution Feb 4, 2026
a7b9b39
lab03 task1
acecution Feb 12, 2026
4a0eed9
Merge branch 'inno-devops-labs:master' into lab03
acecution Feb 12, 2026
4bfd6f7
fix build
acecution Feb 18, 2026
3004393
merge
acecution Feb 18, 2026
f9f19bf
fix build
acecution Feb 18, 2026
0de5dfd
fix build
acecution Feb 18, 2026
d4db453
fix build
acecution Feb 18, 2026
a9dd617
fix build
acecution Feb 18, 2026
227b8c1
fix build
acecution Feb 18, 2026
40e840f
fix build
acecution Feb 18, 2026
491edc1
fix build
acecution Feb 18, 2026
d9ac71d
fix build
acecution Feb 18, 2026
127ad16
update LAB03.md
acecution Feb 18, 2026
dc38cc0
lab04
acecution Feb 19, 2026
b761f81
fix LAB04.md
acecution Feb 19, 2026
3598305
lab05
acecution Feb 26, 2026
f6c86c7
fix: code style
acecution Feb 26, 2026
b623e3e
lab06
acecution Mar 5, 2026
0dd0281
add ansible workflow
acecution Mar 5, 2026
6402842
fix
acecution Mar 5, 2026
77349b3
fix
acecution Mar 5, 2026
6bd96c3
fix format
acecution Mar 5, 2026
f35d1e7
fix ansible workflow
acecution Mar 5, 2026
2cd5bc1
fix: replace vault file with new password
acecution Mar 5, 2026
251e83f
lab07
acecution Mar 12, 2026
cc7afb0
update LAB07.md
acecution Mar 12, 2026
b8c5123
update LAB07.md
acecution Mar 12, 2026
c500439
lab08
acecution Mar 19, 2026
2ee2781
lab09
acecution Mar 26, 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
13 changes: 13 additions & 0 deletions .github/cache-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"cache": {
"pip": true,
"docker": true,
"node": false,
"actions": true
},
"optimizations": {
"parallel_jobs": true,
"skip_duplicate_actions": true,
"cancel_in_progress_on_new_commit": true
}
}
74 changes: 74 additions & 0 deletions .github/workflows/ansible-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Ansible Deployment

on:
push:
branches: [ main, master ]
paths:
- 'ansible/**'
- '.github/workflows/ansible-deploy.yml'
pull_request:
branches: [ main, master ]
paths:
- 'ansible/**'

jobs:
lint:
name: Ansible Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Install dependencies
run: |
pip install ansible ansible-lint

- name: Run ansible-lint
working-directory: ansible
run: |
ansible-lint playbooks/*.yml

deploy:
name: Deploy to VM
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Install Ansible and collections
run: |
pip install ansible
ansible-galaxy collection install community.docker

- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa

- name: Deploy with Ansible
working-directory: ansible
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
run: |
echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
ansible-playbook playbooks/deploy.yml \
-i inventory/hosts.ini \
--vault-password-file /tmp/vault_pass \
--extra-vars "web_app_wipe=false"
rm /tmp/vault_pass

- name: Verify Deployment
run: |
sleep 10
curl -f http://${{ secrets.VM_HOST }}:8000/health || exit 1
curl -f http://${{ secrets.VM_HOST }}:8000/ || exit 1
196 changes: 196 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
name: Python CI/CD Pipeline

on: [push, pull_request]

env:
DOCKER_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository_owner }}/devops-info-service
PYTHON_VERSION: '3.13'
DOCKER_BUILDKIT: 1

jobs:
lint-and-test:
name: Lint and Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: 'app_python/requirements.txt'

- name: Install dependencies
working-directory: ./app_python
run: |
pip install -r requirements.txt
pip install pytest pytest-cov httpx

- name: Run unit tests with coverage
working-directory: ./app_python
run: |
echo "Running tests with coverage..."
python -m pytest tests/ -v --cov=app --cov-report=xml --cov-report=html

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./app_python/coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

- name: Upload test artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: |
app_python/coverage.xml
app_python/htmlcov/
retention-days: 7

build-and-push:
name: Build and Push Docker Image
runs-on: ubuntu-latest
needs: lint-and-test
if: github.ref == 'refs/heads/lab03'

permissions:
contents: read
packages: write
security-events: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Generate version tag
id: version
run: |
echo "version=$(date +'%Y.%m.%d')-${GITHUB_SHA::7}" >> $GITHUB_OUTPUT

- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=raw,value=${{ steps.version.outputs.version }}
labels: |
maintainer=${{ github.actor }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.created=${{ steps.meta.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./app_python
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64

- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest

- name: Scan image for vulnerabilities with Trivy
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
format: 'sarif'
output: 'trivy-results.sarif'
exit-code: '0'

- name: Check if Trivy results exist
id: check_trivy
run: |
if [ -f trivy-results.sarif ]; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Trivy results found"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "No Trivy results file found"
fi

- name: Upload Trivy scan results to GitHub Security tab
if: steps.check_trivy.outputs.exists == 'true'
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif

security-scan:
name: Security Scan (Snyk)
runs-on: ubuntu-latest
needs: lint-and-test
continue-on-error: true

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install dependencies
working-directory: ./app_python
run: |
pip install -r requirements.txt

- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/python@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high

- name: Run safety check
working-directory: ./app_python
run: |
pip install safety
safety check -r requirements.txt

notify:
name: Notify Status
runs-on: ubuntu-latest
needs: [lint-and-test, build-and-push, security-scan]
if: always()
steps:
- name: Check workflow status
run: |
echo "## Workflow Status" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Lint and Test | ${{ needs.lint-and-test.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Build and Push | ${{ needs.build-and-push.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
test
.vscode
2 changes: 2 additions & 0 deletions ansible/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vault_pass
hosts.ini
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 = ubuntu
retry_files_enabled = False

[privilege_escalation]
become = True
become_method = sudo
become_user = root
Loading