Reusable GitLab CI Components: Stop Copy-Pasting Your Pipelines
Every team copy-pastes the same CI jobs until they drift. Here's how I use GitLab's CI/CD Components and Catalog to ship versioned, reusable pipeline building blocks.
- #gitlab
- #cicd
- #components
- #catalog
- #templates
- #platform-engineering
Walk into any company with more than ten repositories and you’ll find the same thing: the same Docker-build job, copy-pasted into thirty .gitlab-ci.yml files, each one slightly different, each one drifting further from the others. When a security fix needs to land in all thirty, someone spends a miserable afternoon doing it by hand and missing two.
I’ve lived that afternoon. GitLab’s CI/CD Components and the CI/CD Catalog are the cure: versioned, reusable pipeline building blocks you publish once and consume everywhere. Here’s how I use them to turn copy-paste sprawl into a real internal platform.
What a CI/CD Component is
A component is a parameterized, reusable chunk of pipeline — think of it like a function for CI. It lives in a project, declares its inputs, and other pipelines include it with arguments. Unlike old-style include: template, components have a proper interface and proper versioning.
A component is defined in templates/ within a component project:
# templates/docker-build.yml
spec:
inputs:
image_name:
description: "Name of the image to build"
dockerfile:
default: "Dockerfile"
push:
type: boolean
default: false
---
build-$[[ inputs.image_name ]]:
stage: build
script:
- docker build -f $[[ inputs.dockerfile ]] -t $[[ inputs.image_name ]] .
- if [ "$[[ inputs.push ]]" = "true" ]; then docker push $[[ inputs.image_name ]]; fi
The spec.inputs block is the contract. Consumers see exactly what they can configure, with defaults and descriptions, instead of guessing at undocumented variables.
Consuming a component
Using it is clean. Reference the component by its catalog path and version, and pass inputs:
include:
- component: gitlab.example.com/platform/ci-components/docker-build@1.4.0
inputs:
image_name: my-app
push: true
That’s it. The job appears in your pipeline. When the platform team ships a fix, you bump @1.4.0 to @1.5.0 and you’ve got it — no copy-paste, no drift.
Version it like real software
The single most important practice: pin versions and use semantic versioning. Components are published as releases on Git tags, and you should consume a specific tag, never a moving target.
- Pin to a version (
@1.4.0) for stability. - Bump deliberately when you want the new behavior.
- Treat breaking changes as major-version bumps, exactly like any library.
The whole disaster components prevent — a shared change silently breaking everyone — only comes back if you consume @main. Pin your versions and the component is a dependency you control, not a surprise.
Publish to the CI/CD Catalog
A component project becomes discoverable when you mark it as a catalog resource and publish releases. The Catalog is a searchable index of all your components, with READMEs, inputs, and versions — so teams find the official “deploy to Kubernetes” component instead of inventing their own for the fortieth time.
To publish, you add a release job that creates a tagged release:
create-release:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: '$CI_COMMIT_TAG'
script: echo "Releasing $CI_COMMIT_TAG"
release:
tag_name: $CI_COMMIT_TAG
description: "Component release $CI_COMMIT_TAG"
Now the component shows up in the Catalog for every team in your org.
Design components people will actually use
A good component is like a good API: small, well-documented, and hard to misuse.
- Sensible defaults. The simplest case should need almost no inputs.
- Clear input descriptions. Every input gets a description and, where possible, a default.
- Do one thing. A component that builds and tests and deploys is hard to reuse. Compose small components instead.
- Validate inputs. Use input
typeandoptionsso bad values fail fast with a clear message.
I’ve seen components fail not because they were broken but because nobody understood how to call them. The interface is the product.
Test your components
Components are code, so test them. Keep example pipelines in the component repo that exercise each input combination, and run them in the component project’s own CI. A component that breaks its consumers on a release is worse than copy-paste, because now everyone’s broken at once. Your component’s pipeline should prove it works before you tag a release.
Where AI helps
Designing a clean component interface is genuinely hard — naming inputs, choosing defaults, deciding what to expose. I describe the job I’m trying to generalize to a model and ask: “What should the inputs be, what are sensible defaults, and what’s the smallest interface that covers the real use cases?” It’s good at spotting the input I forgot and the default that should be safer. I keep GitLab CI prompts for component design, and run new components through our Code Review tool before publishing them to the Catalog.
From sprawl to platform
CI/CD Components are how a CI setup graduates from “thirty drifting copies” to “a versioned internal platform.” A platform team maintains the building blocks; product teams compose them. A security fix lands in one place and rolls out through version bumps instead of thirty manual edits.
If you’re still copy-pasting jobs between repos, this is the highest-leverage change you can make to your GitLab CI. Publish the common jobs once, version them properly, put them in the Catalog, and never have that miserable thirty-repo afternoon again.
AI suggestions for component design are assistive, not authoritative. Always test a component against real consumer pipelines before tagging a release.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.