24.2 GitHub Actions 🐙
Βασικό workflow
# .github/workflows/ansible-ci.yml
name: Ansible CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# ── Stage 1: Lint ─────────────────────────────────
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.11"
- name: Install ansible-lint
run: pip install ansible ansible-lint
- name: Run ansible-lint
run: ansible-lint
# ── Stage 2: Molecule Test ────────────────────────
molecule:
name: Molecule (${{ matrix.role }})
runs-on: ubuntu-latest
needs: lint # ← μόνο αν lint πέρασε
strategy:
matrix:
role: [nginx, postgresql, redis, docker]
fail-fast: false # ← συνέχισε ακόμα κι αν ένα fail
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install tools
run: |
pip install ansible molecule molecule-plugins[docker] ansible-lint
- name: Run Molecule
run: molecule test
working-directory: roles/${{ matrix.role }}
env:
PY_COLORS: "1"
ANSIBLE_FORCE_COLOR: "1"
# ── Stage 3: Deploy to Staging ───────────────────
deploy-staging:
name: Deploy Staging
runs-on: ubuntu-latest
needs: molecule # ← μόνο αν tests πέρασαν
if: github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v4
- name: Set up SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H ${{ secrets.STAGING_HOST }} >> ~/.ssh/known_hosts
- name: Set up Vault password
run: echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > .vault_pass
- name: Install Ansible
run: pip install ansible
- name: Install Galaxy requirements
run: ansible-galaxy install -r requirements.yml
- name: Deploy to Staging
run: |
ansible-playbook playbooks/deploy.yml \
--limit staging \
--vault-password-file .vault_pass \
-e "app_version=${{ github.sha }}" \
-v
- name: Cleanup
if: always()
run: rm -f .vault_pass ~/.ssh/id_ed25519
# ── Stage 4: Deploy to Production ────────────────
deploy-production:
name: Deploy Production
runs-on: ubuntu-latest
needs: deploy-staging
if: github.ref == 'refs/heads/main'
environment:
name: production # ← Required approval!
steps:
- uses: actions/checkout@v4
- name: Set up SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H ${{ secrets.PRODUCTION_HOST }} >> ~/.ssh/known_hosts
- name: Set up Vault password
run: echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > .vault_pass
- name: Install Ansible
run: pip install ansible
- name: Deploy to Production
run: |
ansible-playbook playbooks/deploy.yml \
--limit production \
--vault-password-file .vault_pass \
-e "app_version=${{ github.sha }}" \
-v
- name: Slack notification
if: always()
run: |
STATUS="${{ job.status }}"
EMOJI=$([ "$STATUS" = "success" ] && echo "✅" || echo "❌")
curl -s -X POST "${{ secrets.SLACK_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d "{\"text\": \"$EMOJI Deploy $STATUS: ${{ github.sha }}\"}"
- name: Cleanup
if: always()
run: rm -f .vault_pass ~/.ssh/id_ed25519
GitHub Environments — Approval gates
Settings → Environments → production
├── Required reviewers: [sre-team]
├── Wait timer: 5 minutes
└── Deployment branches: main only
Αποτέλεσμα:
Push to main → CI passes → "Waiting for approval" email
→ SRE approves → Deploy to production
Σύνοψη 24.2
GitHub Actions Pipeline:
│
├── Triggers: push, pull_request
├── Stages: lint → molecule → staging → production
├── needs: → sequential execution
├── matrix: → parallel role testing
├── environment: → approval gate
└── Secrets: SSH key, Vault password, Slack