Stage 4 · Provision
Testing, AWX & CI/CD
CI Pipelines for Playbooks
GitHub Actions/GitLab CI, dry-runs, and gated applies.
Pipeline Stages
A robust Ansible CI pipeline validates code quality, tests in isolation, and gates deployments. Each stage catches different issues before they reach production.
# Stage 1: Lint
# - yamllint for YAML syntax
# - ansible-lint for Ansible best practices
# Stage 2: Test
# - Molecule tests for each role
# - Syntax check for playbooks
# Stage 3: Dry Run
# - ansible-playbook --check in staging
# - Diff mode to preview changes
# Stage 4: Deploy
# - Apply playbook to staging
# - Integration tests
# - Apply to production (manual gate)Each stage acts as a quality gate. Failing any stage prevents the next stage from running.
GitHub Actions
---
name: Ansible CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install ansible-lint yamllint
- run: yamllint -s .
- run: ansible-lint
molecule:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install molecule molecule-plugins[docker]
- run: molecule test
working-directory: roles/my-role
dry-run:
runs-on: ubuntu-latest
needs: molecule
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- run: pip install ansible
- run: ansible-playbook site.yml --check --diff
env:
ANSIBLE_INVENTORY: inventory/staging.ymlGitHub Actions runs lint, tests, and dry-runs automatically. Production deployment requires manual approval.
GitLab CI
---
stages:
- lint
- test
- deploy
lint:
stage: lint
image: python:3.11
script:
- pip install ansible-lint yamllint
- yamllint -s .
- ansible-lint
molecule:
stage: test
image: python:3.11
services:
- docker:dind
script:
- pip install molecule molecule-plugins[docker]
- molecule test
needs: [lint]
deploy-staging:
stage: deploy
image: python:3.11
script:
- pip install ansible
- ansible-playbook site.yml --check --diff -i inventory/staging.yml
needs: [molecule]
only:
- mainGitLab CI uses stages and needs to define dependencies. Deploy to staging only from main after tests pass.
Dry Runs in CI
# Check mode — preview changes without applying
ansible-playbook site.yml --check --diff -i inventory/staging.yml
# Syntax check — validate YAML and Ansible syntax
ansible-playbook site.yml --syntax-check
# Limit to specific hosts
ansible-playbook site.yml --check --limit 'web*.staging.example.com'
# Output diff for review
ansible-playbook site.yml --check --diff 2>&1 | tee dry-run.logDry runs in CI catch syntax errors, missing variables, and logic issues without touching infrastructure.
Gated Deployments
deploy-production:
runs-on: ubuntu-latest
needs: [lint, molecule, dry-run]
environment: production # Requires approval
steps:
- uses: actions/checkout@v4
- run: pip install ansible
- run: ansible-playbook site.yml -i inventory/production.yml
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}GitHub environment protection rules require manual approval before production deployments. This is your deployment gate.
Lint and test automatically on every PR. Dry-run automatically on merge to main. Deploy to staging automatically. Deploy to production only with manual approval.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.