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