Skip to content
Open

Lab09 #3266

Show file tree
Hide file tree
Changes from all commits
Commits
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
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/**'
- '!ansible/docs/**'
- '.github/workflows/ansible-deploy.yml'
pull_request:
branches: [main, master]
paths:
- 'ansible/**'

jobs:
lint:
name: Ansible Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
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
run: |
cd ansible
ansible-lint playbooks/*.yml

deploy:
name: Deploy Application
needs: lint
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v4

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

- name: Install Ansible
run: pip install ansible

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

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

- name: Verify Deployment
run: |
sleep 10
curl -f http://${{ secrets.VM_HOST }}:5000 || exit 1
104 changes: 104 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Python app - Test & Docker Push

on:
push:
pull_request:
types: [opened]

defaults:
run:
working-directory:
./app_python

env:
DOCKER_HUB_USERNAME: ${{ vars.DOCKER_HUB_USERNAME }}
IMAGE_NAME: ${{ vars.IMAGE_NAME }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
code-quality-and-testing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.11', '3.12', '3.13' ]
fail-fast: true

steps:
- uses: actions/checkout@v4

- name: Setup Python ${{matrix.python-version}}
uses: actions/setup-python@v4
with:
python-version: ${{matrix.python-version}}
cache: 'pip'

- name: Cache virtual environment
id: cache-venv
uses: actions/cache@v4
with:
path: ./app_python/venv
key: venv-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('./app_python/requirements.txt') }}

- name: Create virtual environment and install dependencies
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
python -m venv venv
. venv/bin/activate
pip install -r requirements.txt

- name: Run flake8
run: venv/bin/flake8 ./app.py ./tests/test_app.py

- name: Run tests
run: venv/bin/pytest

- name: Install Snyk
uses: snyk/actions/setup@master

- name: Run Snyk
run: |
. venv/bin/activate
snyk test --severity-threshold=high --file=requirements.txt
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
continue-on-error: false
timeout-minutes: 2

docker-build-push:
runs-on: ubuntu-latest
needs: code-quality-and-testing
if: github.event_name == 'pull_request' && github.event.action == 'opened'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Docker tags
id: tags
uses: docker/metadata-action@v5
with:
images: ${{env.DOCKER_HUB_USERNAME}}/${{env.IMAGE_NAME}}
tags: |
type=semver,pattern={{version}}
type=raw,value=latest
- name: Log in to docker hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}

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

- name: Build and push
uses: docker/build-push-action@v5
with:
context: ./app_python
push: true
tags: ${{ steps.tags.outputs.tags }}
labels: ${{ steps.tags.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
32 changes: 31 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
test
test
.pytest_cache/

# Terraform
*.tfstate
*.tfstate.*
.terraform/
.terraform.lock.hcl
terraform.tfvars
*.tfvars
crash.log

# Pulumi
pulumi/venv/
pulumi/__pycache__/
pulumi/*.pyc
Pulumi.*.yaml

# Cloud credentials
*.pem
*.key
service-account-key.json
credentials.json

# Ansible
*.retry
.vault_pass
ansible/inventory/*.pyc
__pycache__/

.env
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Labs](https://img.shields.io/badge/Labs-18-blue)](#labs)
[![Exam](https://img.shields.io/badge/Exam-Optional-green)](#exam-alternative)
[![Duration](https://img.shields.io/badge/Duration-18%20Weeks-lightgrey)](#course-roadmap)
[![Ansible Deployment](https://github.com/AidarSarvartdinov/DevOps-Core-Course/actions/workflows/ansible-deploy.yml/badge.svg)](https://github.com/AidarSarvartdinov/DevOps-Core-Course/actions/workflows/ansible-deploy.yml)

Master **production-grade DevOps practices** through hands-on labs. Build, containerize, deploy, monitor, and scale applications using industry-standard tools.

Expand Down
24 changes: 24 additions & 0 deletions ansible/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM python:3.11-slim

RUN apt-get update && \
apt-get install -y --no-install-recommends \
openssh-client \
sshpass \
&& rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir \
ansible \
docker

RUN mkdir -p /root/.ssh

WORKDIR /ansible

# Copy ansible.cfg to a safe (non-world-writable) location
COPY ansible.cfg /etc/ansible/ansible.cfg
ENV ANSIBLE_CONFIG=/etc/ansible/ansible.cfg

# Entrypoint fixes SSH key permissions (Windows → Linux)
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
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 = /ansible/inventory/hosts.ini
roles_path = /ansible/roles
host_key_checking = False
remote_user = ubuntu
retry_files_enabled = False

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