Skip to content
Open

Lab7 #2913

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

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

jobs:
lint:
name: Ansible Lint
runs-on: ubuntu-latest
defaults:
run:
working-directory: ansible

steps:
- name: Checkout
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-lint
ansible-galaxy collection install community.docker community.general

- name: Run ansible-lint
run: ansible-lint playbooks/*.yml
continue-on-error: true

deploy:
name: Deploy Application
needs: lint
runs-on: ubuntu-latest
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/lab06')
defaults:
run:
working-directory: ansible

steps:
- name: Checkout
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 community.general

- 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 2>/dev/null || true

- name: Create CI inventory
run: |
cat > inventory/hosts.ci.ini << EOF
[webservers]
deploy-target ansible_host=${{ secrets.VM_HOST }} ansible_user=${{ secrets.VM_USER }} ansible_python_interpreter=/usr/bin/python3
EOF

- name: Deploy with 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.ci.ini --vault-password-file /tmp/vault_pass
rm -f /tmp/vault_pass

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

on:
push:
branches: [master, lab02, lab03]
paths:
- 'app_go/**'
- '.github/workflows/go-ci.yml'
pull_request:
branches: [master, lab02, lab03]
paths:
- 'app_go/**'
- '.github/workflows/go-ci.yml'

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

env:
DOCKER_IMAGE: jambulancia/devops-info-service-go
GO_VERSION: '1.24'

jobs:
test:
name: Lint & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: app_go

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

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: app_go/go.mod

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
working-directory: app_go

- name: Run tests
run: go test -v ./...

docker:
name: Build & Push Docker
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/lab02' || github.ref == 'refs/heads/lab03')

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

- 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
id: meta
run: echo "version=$(date +%Y.%m.%d)" >> $GITHUB_OUTPUT

- name: Build and push
uses: docker/build-push-action@v6
with:
context: ./app_go
push: true
tags: |
${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
${{ env.DOCKER_IMAGE }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
95 changes: 95 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Python CI

on:
push:
branches: [master, lab02, lab03]
paths:
- 'app_python/**'
- '.github/workflows/python-ci.yml'
pull_request:
branches: [master, lab02, lab03]
paths:
- 'app_python/**'
- '.github/workflows/python-ci.yml'

# Cancel outdated runs
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
DOCKER_IMAGE: jambulancia/devops-info-service
PYTHON_VERSION: '3.13'

jobs:
test:
name: Lint & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: app_python

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

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.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 -r requirements-dev.txt

- name: Run ruff linter
run: ruff check app.py tests/

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

- name: Snyk security scan
uses: snyk/actions/python@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
command: test
args: --severity-threshold=high

docker:
name: Build & Push Docker
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/lab02' || github.ref == 'refs/heads/lab03')

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

- 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
id: meta
run: echo "version=$(date +%Y.%m.%d)" >> $GITHUB_OUTPUT

- name: Build and push
uses: docker/build-push-action@v6
with:
context: ./app_python
push: true
tags: |
${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
${{ env.DOCKER_IMAGE }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
57 changes: 57 additions & 0 deletions .github/workflows/terraform-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Terraform CI

on:
push:
branches: [master, lab04]
paths:
- 'terraform/**'
- '.github/workflows/terraform-ci.yml'
pull_request:
branches: [master, lab04]
paths:
- 'terraform/**'
- '.github/workflows/terraform-ci.yml'

jobs:
validate:
name: Validate Terraform
runs-on: ubuntu-latest
defaults:
run:
working-directory: terraform

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

- name: Create dummy SSH public key for validation
run: |
mkdir -p ~/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDummyKeyForCIValidationOnly" > ~/.ssh/id_rsa.pub

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.0"
terraform_wrapper: false

- name: Terraform Format Check
run: terraform fmt -check -recursive -diff

- name: Terraform Init
run: terraform init -backend=false

- name: Terraform Validate
run: terraform validate

- name: Setup TFLint
uses: terraform-linters/setup-tflint@v4
with:
tflint_version: latest

- name: TFLint Init
run: tflint --init

- name: TFLint
run: tflint --format compact
continue-on-error: true
27 changes: 26 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
test
test

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

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

# Credentials & secrets
.env
*.pem
*.key
credentials

# Ansible
*.retry
.vault_pass
ansible/inventory/*.pyc
__pycache__/
34 changes: 34 additions & 0 deletions ansible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Ansible — Configuration Management

[![Ansible Deployment](https://github.com/abdughafforzoda/DevOps-Core-Course/actions/workflows/ansible-deploy.yml/badge.svg)](https://github.com/abdughafforzoda/DevOps-Core-Course/actions/workflows/ansible-deploy.yml)

Role-based Ansible automation for Lab 5–6: system provisioning (common, docker) and application deployment (web_app) via Docker Compose.

## Quick start

```bash
# Edit inventory with your VM
vim inventory/hosts.ini

# Create vault (one-time)
ansible-vault create group_vars/all.yml # use structure from group_vars/all.yml.example

# Provision
ansible-playbook playbooks/provision.yml

# Deploy app
ansible-playbook playbooks/deploy.yml --ask-vault-pass
```

## Tags (Lab 6)

```bash
ansible-playbook playbooks/provision.yml --tags "docker"
ansible-playbook playbooks/provision.yml --skip-tags "common"
ansible-playbook playbooks/deploy.yml -e "web_app_wipe=true" --tags web_app_wipe # wipe only
ansible-playbook playbooks/deploy.yml -e "web_app_wipe=true" # clean reinstall
```

## CI/CD

Secrets required: `ANSIBLE_VAULT_PASSWORD`, `SSH_PRIVATE_KEY`, `VM_HOST`, `VM_USER`. See `.github/workflows/ansible-deploy.yml`.
Loading