Skip to content

CI/CD Pipelines

What You'll Learn

How to build GitLab CI/CD pipelines for common homelab automation tasks — from building Docker images to deploying infrastructure with Terraform and Ansible.

Pipeline Basics

Every pipeline starts with a .gitlab-ci.yml file in your repository root. Here's the anatomy of a well-structured pipeline:

.gitlab-ci.yml
stages:
  - validate
  - build
  - test
  - deploy

variables:
  # Define reusable variables
  APP_NAME: "myapp"

# Template for Docker jobs
.docker-job: &docker-job
  image: docker:latest
  services:
    - docker:dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  tags:
    - docker

Real-World Examples

Build & Push Docker Image

build-image:
  <<: *docker-job
  stage: build
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker build -t $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main

Terraform Pipeline

terraform-validate:
  stage: validate
  image:
    name: hashicorp/terraform:latest
    entrypoint: [""]
  script:
    - terraform init -backend=false
    - terraform validate
    - terraform fmt -check

terraform-plan:
  stage: build
  image:
    name: hashicorp/terraform:latest
    entrypoint: [""]
  script:
    - terraform init
    - terraform plan -out=tfplan
  artifacts:
    paths:
      - tfplan

terraform-apply:
  stage: deploy
  image:
    name: hashicorp/terraform:latest
    entrypoint: [""]
  script:
    - terraform init
    - terraform apply -auto-approve tfplan
  dependencies:
    - terraform-plan
  when: manual
  only:
    - main

Ansible Playbook Execution

ansible-lint:
  stage: validate
  image: cytopia/ansible-lint
  script:
    - ansible-lint playbook.yml

ansible-deploy:
  stage: deploy
  image: willhallonline/ansible:latest
  script:
    - ansible-playbook -i inventory/hosts playbook.yml
  when: manual
  only:
    - main

Tips & Patterns

Pipeline Efficiency

  • Use rules: instead of only:/except: for more flexible pipeline control
  • Cache dependencies between jobs to speed up builds
  • Use needs: for DAG-based pipelines instead of waiting for entire stages
  • Store secrets in GitLab CI/CD variables, never in the repo

More pipeline patterns will be added as I build them out.