GitLab CI/CD Associate cheat sheet
GitLab CI/CD Associate · Keep the key ideas within reach.
Pipeline Configuration and CI/CD YAML Fundamentals
.gitlab-ci.yml is parsed top-down; global keywords (stages, variables, default, include, workflow) apply to all jobs unless overridden at job level.
stages defines execution order; jobs with the same stage run in parallel. If stages is omitted, the default order is build, test, deploy, and jobs without a stage keyword are assigned to test.
Job names must be unique and cannot collide with reserved keywords (image, services, stages, types, before_script, after_script, variables, cache, include, workflow).
include supports local, remote, template, and project references; use ref and file for project includes, and rules or include:rules to conditionally include configuration.
YAML anchors (&) and aliases (*) can deduplicate repeated blocks, but the merge key (<<) is not supported by GitLab; use extends for inheritance instead.
extends performs a reverse deep merge: the child job's keys override the parent, and arrays are replaced, not concatenated.
default: sets global defaults for image, services, before_script, after_script, cache, artifacts, retry, timeout, and interruptible; job-level keys override defaults.
workflow:rules controls whether a pipeline is created at all and can set workflow:name; use it to prevent duplicate pipelines for branch and MR events.
The configuration file must be valid YAML and is validated with the CI Lint tool or the /ci/lint API endpoint before merging.
Job Execution, Stages, and Pipeline Flow Control
A job runs when its rules evaluate to true and its needs dependencies are satisfied; rules are evaluated in order and the first match wins.
rules:if uses predefined CI/CD variables and supports =~ and !~ regex operators; rules:changes checks modified paths and rules:exists checks file presence in the repository.
when values: on_success (default), on_failure, always, manual, delayed, and never. allow_failure: true makes a failed job non-blocking; manual jobs are non-blocking by default.
needs creates a directed acyclic graph (DAG) that lets jobs start before their stage completes; needs: optional: true prevents the pipeline from failing when the needed job is absent.
dependencies limits which jobs' artifacts are downloaded; it must reference jobs in earlier stages unless needs is used.
interruptible: true allows a running job to be canceled when a newer pipeline for the same ref is started and auto-cancel is enabled.
retry specifies max attempts and when conditions (always, on_failure, on_script_failure, on_runner_system_failure, on_stuck_or_timeout_failure).
timeout sets a job-level limit in hours/minutes; the project-level timeout is the fallback, and a job exceeding it is marked failed.
resource_group serializes jobs that share the same resource, preventing concurrent deployments to the same environment.
Variables, Secrets, and Protected Configuration
Predefined variables (CI_COMMIT_REF_NAME, CI_PIPELINE_SOURCE, CI_MERGE_REQUEST_IID, CI_JOB_TOKEN, CI_PROJECT_DIR) are read-only and available in jobs.
Variable precedence from highest to lowest: trigger/manual pipeline variables, project/group variables, instance variables, .gitlab-ci.yml job variables, .gitlab-ci.yml global variables, deployment variables, predefined variables.
Protected variables are only exposed to pipelines running on protected branches or tags; masked variables hide values in job logs and must meet masking requirements (minimum length, allowed characters).
File-type variables write the value to a temporary file and expose the path; use them for credentials such as kubeconfig or service account keys.
Secrets from external stores (HashiCorp Vault, Azure Key Vault, Google Secret Manager, AWS Secrets Manager) are injected with the secrets keyword and id_tokens for OIDC authentication.
The CI_JOB_TOKEN is a short-lived token scoped to the job; it can authenticate to the GitLab API and package registry with limited permissions.
Variables defined in the environment scope (environment:name) are only available to jobs deploying to that environment.
Never echo secrets; use masked variables and avoid printing environment dumps. Artifacts and caches can also leak sensitive files if not excluded.
Caching and Artifacts
cache is reused between jobs and pipelines; artifacts are uploaded after a job and passed to later jobs. Cache is best-effort and not guaranteed; artifacts are stored and downloadable.
cache:key determines the cache bucket; use key:files to compute a hash from lockfiles (e.g., package-lock.json, Gemfile.lock) so the cache invalidates when dependencies change.
cache:key:prefix appends a string to the computed key; cache:key:files_commits uses commit SHAs for key computation.
cache:paths lists directories or files to cache; cache:policy pull, push, or pull-push controls download and upload behavior.
artifacts:paths lists files to archive; artifacts:exclude removes paths from the archive; artifacts:expire_in sets retention (default 30 days).
artifacts:reports supports junit, coverage_report, codequality, sast, dependency_scanning, container_scanning, and license_scanning; these are consumed by merge request widgets.
artifacts:when controls upload on_success, on_failure, or always; artifacts:access controls who can download (all or developer).
dependencies: [] prevents downloading artifacts from previous jobs; needs:artifacts: false downloads only the needed job's artifacts.
Cache and artifacts are uploaded to the GitLab server or object storage; runners may use distributed cache (S3, GCS, Azure) configured in config.toml.
Runners, Executors, and Job Scheduling
Runner types: shared (available to all projects), group, and project-specific. Runner scope and tags determine which jobs a runner can pick up.
Executors: shell, docker, docker-autoscaler, kubernetes, docker-machine (deprecated), virtualbox, parallels, ssh. The executor determines the job environment and isolation.
Tags are case-sensitive; a job with tags runs only on runners that have all listed tags. Jobs without tags can run on any runner with Run untagged jobs enabled.
Concurrent setting in config.toml limits parallel jobs per runner; limit and request_concurrency control the number of concurrent jobs and requests.
protected: true on a runner restricts it to protected branches and tags; combine with protected variables for deployment security.
The Kubernetes executor creates a pod per job; use the runner's service account and pod specifications for resource limits and node selection.
Docker executor uses the image keyword; services: starts linked containers (e.g., postgres, redis) reachable by hostname alias.
Runner authentication uses a runner authentication token (glrt- prefix) created in the UI or API; registration tokens are deprecated.
Job scheduling is first-come, first-served among matching runners; use resource_group and needs to control concurrency and ordering.
Troubleshooting Pipelines and Merge Request Pipelines
Merge request pipelines require rules with $CI_PIPELINE_SOURCE == "merge_request_event" or workflow:rules; otherwise the pipeline may run as a branch pipeline and duplicate.
workflow:rules can prevent duplicate pipelines by allowing either branch pipelines or MR pipelines, not both, for the same event.
Merge request pipeline variables: CI_MERGE_REQUEST_IID, CI_MERGE_REQUEST_SOURCE_BRANCH_NAME, CI_MERGE_REQUEST_TARGET_BRANCH_NAME, CI_MERGE_REQUEST_PROJECT_URL.
A job in an MR pipeline that needs artifacts from a branch pipeline may fail because artifacts are scoped to the pipeline; use needs with the same pipeline or dependencies carefully.
Common failure causes: YAML syntax errors, unknown keywords, missing stages, invalid rules expressions, and runner tag mismatches. Check the CI Lint and job logs.
Exit code 137 usually indicates the job was killed (OOM or timeout); exit code 1 is a script failure. Check the job log and runner system logs.
Use CI_DEBUG_TRACE: "true" or CI_DEBUG_SERVICES: "true" for verbose logs; avoid in production because secrets may be exposed.
Retry failed jobs with the retry button or API; use retry:when to automatically retry specific failure types.
The pipeline graph and job trace show stage order and dependencies; use needs to visualize the DAG and identify blocked jobs.