Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7464c9d
feat: implement lab01 devops info service
Jan 28, 2026
cb5bacf
feat: complete lab02 dockerization
Jan 31, 2026
31761ff
feat: implement lab03 ci/cd pipeline
Jan 31, 2026
27e307f
fix: make docker push conditional on secrets availability
Jan 31, 2026
6ef7b41
feat: add go CI/CD workflow with multi-app path filters
Jan 31, 2026
78652af
feat(lab03): implement complete CI/CD pipeline with coverage and mult…
Jan 31, 2026
bc18721
docs: add codecov coverage badge to README
Jan 31, 2026
532aa78
fix(lab03): improve CI workflows and documentation
Jan 31, 2026
26e7014
feat(lab03): add Go unit tests for complete coverage
Jan 31, 2026
a85f145
feat(lab03): add coverage threshold and improve CI
Jan 31, 2026
5dcde3e
fix(lab03): fix Python linting issues - use datetime.UTC and sort imp…
Jan 31, 2026
1faee36
feat(lab03): improve Go test coverage to 87.3%
Jan 31, 2026
c4549a9
fix(go): handle json.Encode error returns for golangci-lint
Jan 31, 2026
ca91e86
feat(lab04): add terraform and pulumi infrastructure with docs
Feb 19, 2026
a94566e
docs(lab04): make report fully English
Feb 19, 2026
9f80fdc
fix: update lab05 docs and ansible validation
Feb 26, 2026
c751267
lab06: rotate vault password and self-hosted workflows
Mar 5, 2026
7be417e
ci: add self-hosted workflows for lab06
Mar 5, 2026
af8e7e3
ci: trigger python and bonus workflows
Mar 5, 2026
410086c
ci: make ansible-lint config optional in workflows
Mar 5, 2026
a5a8ed9
lab06: add missing playbooks/roles/vars for CI
Mar 5, 2026
382c551
ci: remove setup-python from self-hosted deploy jobs
Mar 5, 2026
d2df944
ci: remove setup-python from lint jobs
Mar 5, 2026
f3465f6
ci: force fresh run on latest workflows
Mar 5, 2026
472eb99
ci: trigger workflows on latest config
Mar 5, 2026
a741966
ci: auto-cancel stale queued runs via concurrency
Mar 5, 2026
e03ec00
ci: use preinstalled ansible on self-hosted deploy jobs
Mar 5, 2026
2476150
lab06: fix local deploy reproducibility and align CI/docs
Mar 5, 2026
4420201
lab06: harden wipe and ci secret handling
Mar 5, 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
137 changes: 137 additions & 0 deletions .github/workflows/ansible-deploy-bonus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Ansible Deploy Bonus App

on:
push:
branches:
- main
- master
- lab06
paths:
- "ansible/playbooks/provision.yml"
- "ansible/playbooks/deploy.yml"
- "ansible/vars/app_bonus.yml"
- "ansible/playbooks/deploy_bonus.yml"
- "ansible/roles/common/**"
- "ansible/roles/web_app/**"
- "ansible/roles/docker/**"
- "ansible/collections/requirements.yml"
- "ansible/ansible.cfg"
- "ansible/group_vars/**"
- ".github/workflows/ansible-deploy-bonus.yml"
pull_request:
branches:
- main
- master
paths:
- "ansible/playbooks/provision.yml"
- "ansible/playbooks/deploy.yml"
- "ansible/vars/app_bonus.yml"
- "ansible/playbooks/deploy_bonus.yml"
- "ansible/roles/common/**"
- "ansible/roles/web_app/**"
- "ansible/roles/docker/**"
- "ansible/collections/requirements.yml"
- "ansible/ansible.cfg"
- "ansible/group_vars/**"
- ".github/workflows/ansible-deploy-bonus.yml"
workflow_dispatch:

concurrency:
group: ansible-deploy-bonus-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
name: Ansible Lint (Bonus app)
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Ansible tooling
run: |
python3 --version
python3 -m pip install --upgrade pip
python3 -m pip install ansible ansible-lint

- name: Install required Ansible collections
run: ansible-galaxy collection install -r ansible/collections/requirements.yml

- name: Run ansible-lint
run: |
cd ansible
LINT_TARGETS="playbooks/provision.yml playbooks/deploy.yml playbooks/deploy_bonus.yml roles/common roles/docker roles/web_app"
if [ -f .ansible-lint ]; then
ansible-lint -c .ansible-lint ${LINT_TARGETS}
else
ansible-lint ${LINT_TARGETS}
fi

deploy:
name: Deploy bonus app
runs-on: [self-hosted, macOS, ARM64]
needs: lint
if: github.event_name != 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Use preinstalled Ansible tooling
run: |
command -v ansible
command -v ansible-playbook
command -v ansible-galaxy
ansible --version

- name: Install required Ansible collections
run: ansible-galaxy collection install -r ansible/collections/requirements.yml

- name: Ensure local lab containers are running
run: |
docker rm -f lab05-registry >/dev/null 2>&1 || true
docker run -d --name lab05-registry -p 5001:5000 registry:2
docker start lab05-ubuntu2404 >/dev/null || true
test "$(docker inspect -f '{{.State.Running}}' lab05-ubuntu2404)" = "true"
test "$(docker inspect -f '{{.State.Running}}' lab05-registry)" = "true"

- name: Build and publish bonus image to local registry
env:
BONUS_APP_IMAGE_TAG: ${{ vars.BONUS_APP_IMAGE_TAG || 'latest' }}
run: |
docker build -t "localhost:5001/devops-info-service-go:${BONUS_APP_IMAGE_TAG}" app_go
docker push "localhost:5001/devops-info-service-go:${BONUS_APP_IMAGE_TAG}"

- name: Prepare vault password file
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
run: |
if [ -n "${ANSIBLE_VAULT_PASSWORD:-}" ]; then
printf '%s\n' "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
elif [ -f "$HOME/.ansible_vault_pass_lab06" ]; then
cp "$HOME/.ansible_vault_pass_lab06" /tmp/vault_pass
else
echo "Vault password missing. Set secret ANSIBLE_VAULT_PASSWORD or create $HOME/.ansible_vault_pass_lab06 on the runner host." >&2
exit 1
fi
chmod 600 /tmp/vault_pass
- name: Run deployment playbook
env:
BONUS_APP_IMAGE_TAG: ${{ vars.BONUS_APP_IMAGE_TAG || 'latest' }}
run: |
set -euo pipefail
cleanup_vault_pass() { rm -f /tmp/vault_pass; }
trap cleanup_vault_pass EXIT
cd ansible
ansible-playbook -i inventory/hosts.local-docker.ini playbooks/deploy_bonus.yml \
--vault-password-file /tmp/vault_pass \
-e @vars/local_multiapp_test.yml \
-e "docker_tag=${BONUS_APP_IMAGE_TAG}" \
-e "web_app_pull_policy=missing"

- name: Verify bonus app endpoints
env:
BONUS_APP_PORT: ${{ vars.BONUS_APP_PORT || '8001' }}
run: |
sleep 10
docker exec lab05-ubuntu2404 curl -fsS "http://127.0.0.1:${BONUS_APP_PORT}/"
docker exec lab05-ubuntu2404 curl -fsS "http://127.0.0.1:${BONUS_APP_PORT}/health"
137 changes: 137 additions & 0 deletions .github/workflows/ansible-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Ansible Deploy Python App

on:
push:
branches:
- main
- master
- lab06
paths:
- "ansible/playbooks/provision.yml"
- "ansible/playbooks/deploy.yml"
- "ansible/vars/app_python.yml"
- "ansible/playbooks/deploy_python.yml"
- "ansible/roles/common/**"
- "ansible/roles/web_app/**"
- "ansible/roles/docker/**"
- "ansible/collections/requirements.yml"
- "ansible/ansible.cfg"
- "ansible/group_vars/**"
- ".github/workflows/ansible-deploy.yml"
pull_request:
branches:
- main
- master
paths:
- "ansible/playbooks/provision.yml"
- "ansible/playbooks/deploy.yml"
- "ansible/vars/app_python.yml"
- "ansible/playbooks/deploy_python.yml"
- "ansible/roles/common/**"
- "ansible/roles/web_app/**"
- "ansible/roles/docker/**"
- "ansible/collections/requirements.yml"
- "ansible/ansible.cfg"
- "ansible/group_vars/**"
- ".github/workflows/ansible-deploy.yml"
workflow_dispatch:

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

jobs:
lint:
name: Ansible Lint (Python app)
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Ansible tooling
run: |
python3 --version
python3 -m pip install --upgrade pip
python3 -m pip install ansible ansible-lint

- name: Install required Ansible collections
run: ansible-galaxy collection install -r ansible/collections/requirements.yml

- name: Run ansible-lint
run: |
cd ansible
LINT_TARGETS="playbooks/provision.yml playbooks/deploy.yml playbooks/deploy_python.yml roles/common roles/docker roles/web_app"
if [ -f .ansible-lint ]; then
ansible-lint -c .ansible-lint ${LINT_TARGETS}
else
ansible-lint ${LINT_TARGETS}
fi

deploy:
name: Deploy Python app
runs-on: [self-hosted, macOS, ARM64]
needs: lint
if: github.event_name != 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Use preinstalled Ansible tooling
run: |
command -v ansible
command -v ansible-playbook
command -v ansible-galaxy
ansible --version

- name: Install required Ansible collections
run: ansible-galaxy collection install -r ansible/collections/requirements.yml

- name: Ensure local lab containers are running
run: |
docker rm -f lab05-registry >/dev/null 2>&1 || true
docker run -d --name lab05-registry -p 5001:5000 registry:2
docker start lab05-ubuntu2404 >/dev/null || true
test "$(docker inspect -f '{{.State.Running}}' lab05-ubuntu2404)" = "true"
test "$(docker inspect -f '{{.State.Running}}' lab05-registry)" = "true"

- name: Build and publish Python image to local registry
env:
PYTHON_APP_IMAGE_TAG: ${{ vars.PYTHON_APP_IMAGE_TAG || 'latest' }}
run: |
docker build -t "localhost:5001/devops-info-service:${PYTHON_APP_IMAGE_TAG}" app_python
docker push "localhost:5001/devops-info-service:${PYTHON_APP_IMAGE_TAG}"

- name: Prepare vault password file
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
run: |
if [ -n "${ANSIBLE_VAULT_PASSWORD:-}" ]; then
printf '%s\n' "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
elif [ -f "$HOME/.ansible_vault_pass_lab06" ]; then
cp "$HOME/.ansible_vault_pass_lab06" /tmp/vault_pass
else
echo "Vault password missing. Set secret ANSIBLE_VAULT_PASSWORD or create $HOME/.ansible_vault_pass_lab06 on the runner host." >&2
exit 1
fi
chmod 600 /tmp/vault_pass
- name: Run deployment playbook
env:
PYTHON_APP_IMAGE_TAG: ${{ vars.PYTHON_APP_IMAGE_TAG || 'latest' }}
run: |
set -euo pipefail
cleanup_vault_pass() { rm -f /tmp/vault_pass; }
trap cleanup_vault_pass EXIT
cd ansible
ansible-playbook -i inventory/hosts.local-docker.ini playbooks/deploy_python.yml \
--vault-password-file /tmp/vault_pass \
-e @vars/local_multiapp_test.yml \
-e "docker_tag=${PYTHON_APP_IMAGE_TAG}" \
-e "web_app_pull_policy=missing"

- name: Verify Python app endpoints
env:
PYTHON_APP_PORT: ${{ vars.PYTHON_APP_PORT || '8000' }}
run: |
sleep 10
docker exec lab05-ubuntu2404 curl -fsS "http://127.0.0.1:${PYTHON_APP_PORT}/"
docker exec lab05-ubuntu2404 curl -fsS "http://127.0.0.1:${PYTHON_APP_PORT}/health"
Loading
Loading