CI/CD Basics

CI/CD (Continuous Integration / Continuous Delivery) is the practice of automatically building, testing, and deploying code every time a developer pushes a change. For sysadmins, CI/CD pipelines apply the same principle to infrastructure: every change to an Ansible playbook or Terraform config triggers automated validation and (optionally) automatic deployment. This eliminates the "works on my machine" problem and creates an auditable deployment process.

CI/CD concepts

CI/CD pipeline flow:

  Developer pushes code to git
          |
          v
  CI Pipeline triggered automatically:
    1. Lint  → check syntax/style (ansible-lint, terraform validate)
    2. Test  → run tests in isolated environment
    3. Build → create artifact (Docker image, deb package)
    4. Scan  → security vulnerabilities, credentials check
          |
          v (if all stages pass)
  CD Pipeline:
    5. Deploy to staging → run tests against staging
    6. Deploy to production → (manual gate or automatic)
    7. Verify → smoke tests, rollback if tests fail

Pipeline stages

# Example: validating an Ansible playbook in CI:

# Install tools on CI runner (Ubuntu):
sudo apt install -y python3-pip
pip3 install ansible ansible-lint

# Lint the playbook (catches syntax errors and bad practices):
ansible-lint site.yml

# Run against a test inventory (localhost or a test VM):
ansible-playbook site.yml -i tests/inventory --check

# For Terraform:
terraform init
terraform validate
terraform plan -out=plan.tfplan    # Save plan to file for inspection
# Human reviews plan before:
terraform apply plan.tfplan
# Pre-commit hooks — catch issues before they reach CI:
pip3 install pre-commit
cat > .pre-commit-config.yaml << 'EOF'
repos:
  - repo: https://github.com/ansible/ansible-lint
    rev: v24.2.0
    hooks:
      - id: ansible-lint
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.83.5
    hooks:
      - id: terraform_validate
      - id: terraform_fmt
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks    # Scan for accidental secret commits
EOF
pre-commit install    # Installs hooks into .git/hooks/

Deploying with CI/CD

# Deployment strategies:
# Push-based: CI pipeline SSHes into server and runs deployment commands
# Pull-based: server periodically polls git and applies changes (GitOps)

# Push-based deployment (simpler, common for Ansible):
# CI runner SSHes to server using deploy key (dedicated SSH key for CI)
ssh-keygen -t ed25519 -C "ci-deploy" -f deploy_key -N ""
# Add public key to ~/.ssh/authorized_keys on target server
# Add private key to CI system as a secret variable

# Deployment script run by CI:
ansible-playbook site.yml   --private-key="${DEPLOY_KEY}"   -i inventory/production   --limit webservers

Conclusion

For infrastructure teams, the highest-value CI/CD pipeline is: lint (catch syntax errors) + test on staging (catch runtime errors) + manual approval gate before production. This catches 95% of mistakes without requiring complex test infrastructure. The pre-commit hook for secret scanning (gitleaks) is arguably more important than any other check — it prevents the worst possible CI/CD failure: accidentally committing credentials to git history.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Work with Muhammad Irfan Aslam