Chapter 13Lesson 01~165 minutes

CI/CD Components, Component Catalog, inputs, Versioned Reuse, and Organization-Wide Pipeline Building Blocks: Concepts, Architecture, and Mental Model

A CI/CD component is best understood as a versioned pipeline API rather than a convenient YAML snippet. This lesson builds the mental model from a component project and spec:inputs through version resolution, consumer arguments, compiled jobs, permissions, side effects, evidence, and compatibility promises.

CI/CD componentsspec:inputsComponent CatalogVersioned reusePipeline APIs

Learning objectives

  • Explain a CI/CD component as a versioned configuration API with a producer, consumer, inputs, generated jobs, and observable side effects.
  • Trace component project/version/ref → input interpolation → compiled configuration → jobs → runtime evidence without collapsing these states.
  • Distinguish component inputs from CI/CD variables and secret storage, including validation timing and visibility boundaries.
  • Compare commit SHA, full SemVer tag, partial SemVer selectors, branches, and ~latest by reproducibility and upgrade risk.
  • Inspect component provenance, permissions, generated job names, and compatibility assumptions before running a consumer pipeline.

1. The practical problem: shared YAML is not yet a stable API

Chapter 12 showed how includes, hidden jobs, extends, anchors, and !reference reduce duplication. Those mechanisms still expose implementation details: consumers often need to know internal job names, variables, stages, and merge behavior. At organization scale, that creates fragile coupling.

A CI/CD component adds a stronger distribution model. The maintainer publishes a named reusable unit with an explicit input contract and version identity. The consumer references that unit and supplies arguments. GitLab resolves the reference and inputs during pipeline creation, merges the resulting jobs into the consumer configuration, and only then can runners execute them.

Core invariant: a component is executable configuration from another ownership boundary. Treat its source/version, inputs, permissions, generated job names, external dependencies, and side effects as API and supply-chain state.

2. Separate the states before changing anything

State Examples Evidence
Source/revision Consumer SHA; component project; component version/ref Repository URL/path, commit SHA, release/tag identity
Compiled configuration Resolved component + interpolated inputs + caller jobs Expanded YAML / CI Lint result
Job/runner Generated job names, stage, tags, image, runner Pipeline/job IDs, runner metadata, trace
Identity/trust Project visibility, component permissions, tokens/secrets exposed to job Access decision and non-secret scope metadata
Evidence/output Artifacts/reports/logs generated by component jobs Producer job/SHA, digest, retention, report state
External side effects Registry publish, deployment, API mutation, notification Exact target identity + authorization + target verification
Governance Owner, release policy, compatibility window, deprecation path README, changelog/release notes, tests, exception record

3. Mental model: producer contract → resolved consumer jobs

The component project owns source code and a templates/ contract. A released or pinned reference identifies one revision. The consumer supplies explicit inputs. GitLab validates and interpolates those inputs while compiling the consumer pipeline. Only the generated jobs that survive compilation/rules can later enter the runner queue.

flowchart TD A[Component project + template] --> B[Version/ref identity] B --> C[Consumer include:component] C --> D[Validate + interpolate inputs] D --> E[Compiled jobs] E --> F[Rules + DAG] F --> G[Runner execution] G --> H[Artifacts/reports/side effects] H --> I[Compatibility + audit evidence]

Every arrow changes a different kind of state. A successful component lookup does not prove the inputs are valid; valid compiled jobs do not prove a runner exists; a green component job does not prove an external deployment is healthy.

4. A component project is a versioned product boundary

Current GitLab component projects store components under a top-level templates/ directory. A component can be a single templates/name.yml file or a templates/name/template.yml directory. The project should document every component in a root README and test component behavior in its own pipeline.

All components in one project share version releases. Current GitLab allows up to 100 components per component project. If one component needs an independent release cadence or radically different ownership, place it in a separate project rather than forcing unrelated APIs to version together.

5. spec:inputs is the public parameter surface

Inputs are configuration-time parameters. They are not mutable runtime variables and they are not a secret vault. Define only the choices a caller legitimately needs to make. GitLab validates required inputs and can enforce type, options, and regex before a pipeline starts.

spec:
  inputs:
    job-prefix:
      description: "Unique prefix for generated job names"
      regex: '^[a-z0-9-]{2,24}$'
    stage:
      description: "Consumer stage for the component job"
      default: test
      options: [test, verify]
    strict:
      description: "Fail when the synthetic check is not clean"
      type: boolean
      default: true
---
"$[[ inputs.job-prefix ]]-policy-check":
  stage: $[[ inputs.stage ]]
  script:
    - echo "component contract executed"
    - echo "strict=$[[ inputs.strict ]]"

A required job-prefix prevents silent name collisions. The stage is caller-controlled instead of hard-coded. The boolean remains typed. If a consumer supplies an invalid prefix or stage, configuration fails before runner execution.

6. Inputs, variables, and secrets solve different problems

Mechanism Best use Important boundary
Component input Stable caller-controlled configuration Resolved/validated at pipeline creation; treat safe values as API arguments
Predefined variable Project/pipeline/job context Provided by GitLab; phase availability matters
CI/CD variable Runtime configuration or values from settings Precedence and protection/masking rules apply
Secret provider / protected secret Sensitive credentials Authorize narrow retrieval; do not expose as ordinary component input

7. Version selectors are upgrade policy encoded in syntax

Reference Meaning Use
Full commit SHA Exact repository revision Strongest immutable evidence; ideal for high-assurance pinning/testing
1.2.3 tag Exact semantic release Human-readable governed release identity
1.2 Latest published 1.2.x catalog release Automatic patch updates within minor line; still a moving selector
1 Latest published 1.x catalog release Automatic minor/patch updates within major line
~latest Latest published catalog release Most convenient and highest drift risk; avoid for stable production without explicit policy
branch (for example main) Moving repository ref Useful during controlled development; weak production reproducibility

8. Resolution, visibility, and permission are part of the contract

include:component references a component on the same GitLab instance as the consumer. Private component projects require the consumer/user context to have sufficient access. Therefore “the URL exists” is not enough: project visibility, membership, and authorization are compilation state.

Do not solve access failures by inserting a broad personal access token into every consumer. Prefer the platform-supported authorization model and keep component projects scoped and visible according to organizational policy.

9. Read-only inspection before consumption

Before adding a third-party or organization component, inspect its source project, README, release/version, template source, dependencies, generated job names, images, scripts, token expectations, artifacts, network/API targets, and release history. Then inspect the consumer’s expanded configuration with CI Lint or the pipeline editor.

include:
  - component: $CI_SERVER_FQDN/platform/ci-components/policy-check@1.4.2
    inputs:
      job-prefix: service-a
      stage: verify
      strict: true

The consumer should be able to answer: Which component revision was compiled? Which arguments were supplied? Which jobs were added? Which permissions and side effects can those jobs exercise?

10. Component context can bind resources to the resolved component identity

Current GitLab supports component context fields such as component name, SHA, version, and original reference when declared in spec:component. This can help a component refer to a tool image released at the same version. Because this functionality arrived after component GA, verify support on older Self-Managed instances before making it mandatory.

spec:
  component: [name, sha, version, reference]
  inputs:
    stage:
      default: test
---
identity-check:
  stage: $[[ inputs.stage ]]
  script:
    - echo "component=$[[ component.name ]]"
    - echo "sha=$[[ component.sha ]]"
    - echo "version=$[[ component.version ]]"
    - echo "requested=$[[ component.reference ]]"

11. Catalog publication is distribution, not correctness proof

The CI/CD Catalog makes component projects discoverable and supports released version selection. Publishing currently requires the project to be marked as a catalog project and a SemVer release created through a GitLab release job after tests succeed. Catalog presence is useful distribution metadata, but it does not prove the component is safe for your trust model.

Consumers still audit source, version, permissions, external dependencies, secret handling, and side effects. Maintainers still test every release and publish migration guidance for breaking changes.

12. Common wrong models

  • “A component is just an include with a nicer name.” It is also a versioned interface/distribution contract with explicit inputs and catalog semantics.
  • “Inputs are secure because they are validated.” Validation is not secrecy. Do not pass credentials as ordinary component inputs.
  • “~latest is safest because it is newest.” It is deliberately moving and can cross major versions.
  • “A component can silently assume my job names or stages.” Hard-coded global assumptions make reuse brittle; expose necessary choices as inputs and use collision-resistant names.
  • “Catalog publication proves compatibility.” Only tests and a maintained compatibility policy support that claim.

Knowledge check

Why is an invalid component input not a runner problem?

Which reference gives the strongest immutable identity: main, ~latest, 1, 1.2.3, or a full commit SHA?

Why should a component expose a job-prefix input?

Should a database password be a component input?

What evidence proves which reusable configuration GitLab compiled?

Next lesson

Guided hands-on workflow and core operations

Build a tiny typed component contract, consume two simulated versions, reject invalid inputs, and inspect generated jobs.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-11. Component, input, catalog, component-context, analytics, and publication behavior is version-sensitive. Re-check the GitLab version deployed on Self-Managed or Dedicated instances before relying on newer syntax.

  • CI/CD components and CI/CD Catalog — component projects, version selectors, permissions, testing, publication, security guidance, and current project limits.
  • CI/CD inputs — spec:inputs, interpolation, types, defaults, options, regex validation, size limits, and include inputs.
  • CI/CD YAML syntax reference — include:component, include:inputs, component context, and current parsing semantics.
  • Pipeline editor — validate and inspect expanded configuration before execution.
  • CI Lint — syntax/configuration validation and pipeline simulation where available.
  • Component examples — testing components against the current SHA and coupling versioned resources to component releases.
Current behavior used by this chapter: CI/CD components and the Catalog are available on Free/Premium/Ultimate and GitLab.com/Self-Managed/Dedicated. A component project can currently contain up to 100 components. A component reference can use a commit SHA, tag, or branch; catalog-published components additionally support partial SemVer selectors such as 1/1.2 and ~latest. Catalog releases require SemVer and publication through a GitLab release job. Components can only be referenced from the same GitLab instance. Inputs are resolved at pipeline creation; missing required or invalid typed/options/regex values reject configuration before runner execution. A string inside one input must be under 1 KB, and a string containing interpolated input content must be under 1 MB. Component context fields (name, sha, version, reference) are current functionality but should be version-checked on older instances.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.