Skip to content
Open

Lab06 #2851

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
118 changes: 118 additions & 0 deletions .github/workflows/ansible-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Ansible Deployment

on:
push:
branches:
- master
- main
- lab06
paths:
- "ansible/**"
- ".github/workflows/ansible-deploy.yml"
pull_request:
branches:
- master
- main
- lab06
paths:
- "ansible/**"
- ".github/workflows/ansible-deploy.yml"

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 lint dependencies
run: |
python -m pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install community.docker

- name: Create vault password file for lint
working-directory: ansible
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
run: |
echo "$ANSIBLE_VAULT_PASSWORD" > .vault_pass
chmod 600 .vault_pass

- name: Run ansible-lint
working-directory: ansible
run: |
ansible-lint \
-x fqcn,yaml,var-naming,key-order,name,risky-file-permissions,command-instead-of-module,partial-become \
playbooks/*.yml

- name: Remove vault password file
if: always()
working-directory: ansible
run: rm -f .vault_pass

deploy:
name: Deploy Application
needs: lint
if: github.event_name == 'push'
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 deployment dependencies
run: |
python -m pip install --upgrade pip
pip install ansible
ansible-galaxy collection install community.docker

- name: Configure 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: Create CI inventory
working-directory: ansible
run: |
cat > inventory/ci_hosts.ini << EOF
[webservers]
ci-target ansible_host=${{ secrets.VM_HOST }} ansible_user=${{ secrets.VM_USER }} ansible_ssh_private_key_file=~/.ssh/id_rsa

[all:vars]
ansible_python_interpreter=/usr/bin/python3
EOF

- name: Deploy with Ansible
working-directory: ansible
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
APP_NAME: devops-info-service
APP_PORT: "5000"
APP_INTERNAL_PORT: "5000"
DOCKER_IMAGE: j0cos/devops-info-service
DOCKER_TAG: latest
run: |
echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
ansible-playbook playbooks/deploy.yml \
-i inventory/ci_hosts.ini \
--vault-password-file /tmp/vault_pass
rm -f /tmp/vault_pass

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

on:
push:
branches:
- master
- lab*
paths:
- "app_python/**"
- ".github/workflows/python-ci.yml"
pull_request:
branches:
- master
- lab*
paths:
- "app_python/**"
- ".github/workflows/python-ci.yml"

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

jobs:
test-and-lint:
name: Lint and Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
python-version: ["3.11", "3.12"]

defaults:
run:
working-directory: app_python

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

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: app_python/requirements.txt

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

- name: Run flake8
run: flake8 .

- name: Run tests with coverage
run: pytest --cov=. --cov-report=term --cov-report=xml --cov-fail-under=70

- name: Upload coverage to Codecov
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
files: ./app_python/coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}

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

env:
IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service

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

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

- name: Set CalVer version
id: set-version
run: echo "VERSION=$(date +'%Y.%m.%d')" >> "$GITHUB_ENV"

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./app_python
push: true
tags: |
${{ env.IMAGE_NAME }}:${{ env.VERSION }}
${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max

security-scan:
name: Snyk Security Scan
needs: test-and-lint
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write

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

- name: Set up Python (for dependency resolution)
uses: actions/setup-python@v5
with:
python-version: "3.12"

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

- name: Set up Snyk CLI
uses: snyk/actions/setup@master

- name: Run Snyk to check for vulnerabilities
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: >
snyk test
--file=app_python/requirements.txt
--package-manager=pip
--severity-threshold=medium
--sarif-file-output=snyk.sarif



95 changes: 94 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,94 @@
test
# Repo-level .gitignore for DevOps-Core-Course

# Terraform
*.tfstate
*.tfstate.*
.terraform/
.terraform.lock.hcl
terraform.tfvars
terraform.tfvars.json
*.tfvars
crash.log
override.tf
override.tf.json
*_override.tf
plan.out

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

# Yandex / cloud credentials and other secrets
# NOTE: this is broad for safety. Adjust if you intentionally track non-secret JSON files.
*.key
*.pem
*.p12
*.crt
*.csr
credentials
*.secret
*.env
.env.*
secrets.*
*.vault
.vault_pass

# Keys and service account files
# common names: yc_key.json, service-account.json etc.
*service-account*.json
*key*.json
*credentials*.json
yc_key.json

# Python
__pycache__/
*.py[cod]
*$py.class
venv/
.venv/
env/
env.bak/
venv.bak/
*.egg-info/
*.eggs/
.pytest_cache/

# Node
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# IDEs and editors
.vscode/
.idea/
*.sublime-project
*.sublime-workspace
*.code-workspace

# OS files
.DS_Store
Thumbs.db

# Logs and runtime files
*.log
*.pid
*.seed
*.pid.lock

# Docker
docker-compose.override.yml
**/docker-compose.override.yml

# Misc
*.bak
*.swp
*~

# Keep README, docs, source files tracked
# (No patterns below to avoid accidentally ignoring docs or source code)
Loading