GitLab CI Variables

A CI variable is a named value that a pipeline job can read while it runs. Variables keep passwords, server addresses, and settings out of your scripts. One change in a settings page updates every job that uses the value.

Think of a hotel key card. The room number changes for each guest, but the door reader works the same way. A variable lets the same script run with different values in different places.

Three Sources of Variables

  ┌────────────────────────┐   ┌────────────────────────┐   ┌────────────────────────┐
  │  PREDEFINED            │   │  YAML FILE             │   │  SETTINGS PAGE         │
  │  GitLab supplies them  │   │  Written in            │   │  Stored in the project │
  │  CI_COMMIT_BRANCH      │   │  .gitlab-ci.yml        │   │  or group, encrypted   │
  │  CI_PROJECT_NAME       │   │  Visible to everyone   │   │  Hidden from logs      │
  └───────────┬────────────┘   └───────────┬────────────┘   └───────────┬────────────┘
              └──────────────────┬─────────┴─────────────────────────────┘
                                 ▼
                       Job script reads $VARIABLE_NAME

Predefined Variables

GitLab creates these values for every job. No setup is needed.

VariableHoldsSample Value
CI_COMMIT_BRANCHBranch that triggered the pipelinemain
CI_COMMIT_SHAFull commit identifiera1b2c3d4...
CI_COMMIT_SHORT_SHAFirst eight characters of the commita1b2c3d4
CI_PROJECT_NAMEProject namemy-app
CI_PIPELINE_IDPipeline number1204
CI_JOB_NAMEName of the running jobrun-tests
CI_DEFAULT_BRANCHDefault branch of the projectmain
print-info:
  script:
    - echo "Building $CI_PROJECT_NAME from $CI_COMMIT_BRANCH"
    - echo "Commit $CI_COMMIT_SHORT_SHA in pipeline $CI_PIPELINE_ID"

Variables Written in the YAML File

Place variables at the top of the file for global scope or inside a job for local scope.

variables:
  APP_ENV: "staging"          # global: every job sees it

build-app:
  variables:
    BUILD_MODE: "fast"        # local: only this job sees it
  script:
    - echo "Mode is $BUILD_MODE in $APP_ENV"

Anyone with repository access reads these values. Store only harmless settings in the file.

Variables in the Settings Page

  1. Open your project and select Settings → CI/CD.
  2. Expand the Variables section.
  3. Select Add variable.
  4. Type a key such as DEPLOY_TOKEN.
  5. Paste the value.
  6. Choose the visibility and protection options.
  7. Select Add variable to save.

Option Reference

OptionEffect
Protect variableExposes the value only to protected branches and tags
Mask variableReplaces the value with asterisks in job logs
Hidden visibilityHides the value in the settings page after saving
Type: VariablePasses the value as plain text
Type: FileSaves the value in a temporary file and passes the file path
Environment scopeLimits the value to one environment such as production

A masked value needs at least eight characters on a single line. Longer secrets such as certificates fit the File type.

Scope by Environment

The same key can hold different values for different environments.

  Key: DATABASE_URL

  Scope: staging      → postgres://staging-db.example.com
  Scope: production   → postgres://prod-db.example.com

A deploy job tied to the production environment receives the production value automatically.

Variable Priority

When two sources define the same key, the higher source wins.

  1. Values typed during a manual pipeline run     (highest)
  2. Project settings variables
  3. Group settings variables
  4. Instance settings variables
  5. Job-level variables in the YAML file
  6. Global variables in the YAML file             (lowest)

Use Variables in Rules

Rules read variables to decide whether a job runs.

deploy-production:
  script:
    - ./deploy.sh
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Run a Pipeline with Custom Values

Open Build → Pipelines and select New pipeline. Add a key and value in the form. The pipeline starts with those values at the top of the priority list.

Security Habits

  • Store passwords and tokens in the settings page.
  • Mask every secret.
  • Protect production secrets so feature branches cannot read them.
  • Avoid printing variables with echo or env commands.
  • Rotate a token the moment it appears in a log.

Debug a Missing Variable

SymptomLikely Cause
Value is empty on a feature branchThe variable is protected
Value shows asterisks in the logThe mask is working as designed
Wrong value in productionAnother source with higher priority overrides it
Dollar sign inside the value disappearsVariable expansion is active; turn off expansion for that key