- Add a resource group
- Requirements
- Process modes
- Pipeline-level concurrency control with cross-project/parent-child pipelines
- API
- Related features
- Troubleshooting
Resource group
By default, pipelines in GitLab CI/CD run in parallel. The parallelization is an important factor to improve
the feedback loop in merge requests, however, there are some situations that
you may want to limit the concurrency on deployment
jobs to run them one by one.
Use resource groups to strategically control
the concurrency of the jobs for optimizing your continuous deployments workflow with safety.
Provided that you have the following pipeline configuration ( Every time you push a new commit to a branch, it runs a new pipeline that has
two jobs In this case, the In order to ensure that a With this configuration, the safety on the deployments is assured while you
can still run Only one resource can be attached to a resource group.
You can choose a process mode to strategically control the job concurrency for your deployment preferences.
The following modes are supported:
Oldest first: This process mode limits the concurrency of the jobs. When a resource is free,
it picks the first job from the list of upcoming jobs ( This mode is useful when you want to ensure that the jobs are executed from the oldest pipeline.
This is less efficient compared to the Newest first: This process mode limits the concurrency of the jobs. When a resource is free,
it picks the first job from the list of upcoming jobs ( This mode is useful when you want to ensure that the jobs are executed from the newest pipeline and
cancel all of the old deploy jobs with the skip outdated deployment jobs feature.
This is the most efficient option in terms of the pipeline efficiency, but you must ensure that each deployment job is idempotent.
To change the process mode of a resource group, you need to use the API and
send a request to edit an existing resource group
by specifying the Consider the following If three commits are pushed to the project in a short interval, that means that three
pipelines run almost at the same time:
Depending on the process mode of the resource group:
You can define The following example has two pipeline configurations in a project. When a pipeline starts running,
non-sensitive jobs are executed first and aren’t affected by concurrent executions in other
pipelines. However, GitLab ensures that there are no other deployment pipelines running before
triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits
until those pipelines finish before running another one.
You must define See the API documentation.
Read more how you can use GitLab for safe deployments.
Since For example, when you run a child pipeline
that requires the same resource group with the parent pipeline,
a dead lock could happen. Here is an example of a bad setup:
In a parent pipeline, it runs the However, a child pipeline also requires a resource from the In this case, you should specify the Add a resource group
.gitlab-ci.yml
file in your repository):
build:
stage: build
script: echo "Your build script"
deploy:
stage: deploy
script: echo "Your deployment script"
environment: production
build
and deploy
. But if you push multiple commits in a short interval, multiple
pipelines start running simultaneously, for example:
build
-> deploy
build
-> deploy
deploy
jobs across different pipelines could run concurrently
to the production
environment. Running multiple deployment scripts to the same
infrastructure could harm/confuse the instance and leave it in a corrupted state in the worst case.
deploy
job runs once at a time, you can specify
resource_group
keyword to the concurrency sensitive job:
deploy:
...
resource_group: production
build
jobs concurrently for maximizing the pipeline efficiency.
Requirements
Limitations
Process modes
created
, scheduled
, or waiting_for_resource
state)
that are sorted by pipeline ID in ascending order.
unordered
mode in terms of the pipeline efficiency,
but safer for continuous deployments.
created
, scheduled
or waiting_for_resource
state)
that are sorted by pipeline ID in descending order.
Change the process mode
process_mode
:
unordered
oldest_first
newest_first
An example of difference between the process modes
.gitlab-ci.yml
, where we have two jobs build
and deploy
each running in their own stage, and the deploy
job has a resource group set to
production
:
build:
stage: build
script: echo "Your build script"
deploy:
stage: deploy
script: echo "Your deployment script"
environment: production
resource_group: production
build
-> deploy
. Let’s call this deployment job deploy-1
.
build
-> deploy
. Let’s call this deployment job deploy-2
.
build
-> deploy
. Let’s call this deployment job deploy-3
.
unordered
:
deploy-1
, deploy-2
, and deploy-3
do not run in parallel.
deploy-1
could run before or after deploy-3
runs.
oldest_first
:
deploy-1
, deploy-2
, and deploy-3
do not run in parallel.
deploy-1
runs first, deploy-2
runs second, and deploy-3
runs last.
newest_first
:
deploy-1
, deploy-2
, and deploy-3
do not run in parallel.
deploy-3
runs first, deploy-2
runs second and deploy-1
runs last.
Pipeline-level concurrency control with cross-project/parent-child pipelines
resource_group
for downstream pipelines that are sensitive to concurrent
executions. The trigger
keyword can trigger downstream pipelines and the
resource_group
keyword can co-exist with it. resource_group
is useful to control the
concurrency of deployment pipelines, while other jobs can continue to run concurrently.
# .gitlab-ci.yml (parent pipeline)
build:
stage: build
script: echo "Building..."
test:
stage: test
script: echo "Testing..."
deploy:
stage: deploy
trigger:
include: deploy.gitlab-ci.yml
strategy: depend
resource_group: AWS-production
# deploy.gitlab-ci.yml (child pipeline)
stages:
- provision
- deploy
provision:
stage: provision
script: echo "Provisioning..."
deployment:
stage: deploy
script: echo "Deploying..."
strategy: depend
with the trigger
keyword. This ensures that the lock isn’t released until the downstream pipeline
finishes.
API
Related features
Troubleshooting
Avoid dead locks in pipeline configurations
oldest_first
process mode enforces the jobs to be executed in a pipeline order,
there is a case that it doesn’t work well with the other CI features.
# BAD
test:
stage: test
trigger:
include: child-pipeline-requires-production-resource-group.yml
strategy: depend
deploy:
stage: deploy
script: echo
resource_group: production
test
job that subsequently runs a child pipeline,
and the strategy: depend
option makes the test
job wait until the child pipeline has finished.
The parent pipeline runs the deploy
job in the next stage, that requires a resource from the production
resource group.
If the process mode is oldest_first
, it executes the jobs from the oldest pipelines, meaning the deploy
job is going to be executed next.
production
resource group.
Since the child pipeline is newer than the parent pipeline, the child pipeline
waits until the deploy
job is finished, something that will never happen.
resource_group
keyword in the parent pipeline configuration instead:
# GOOD
test:
stage: test
trigger:
include: child-pipeline.yml
strategy: depend
resource_group: production # Specify the resource group in the parent pipeline
deploy:
stage: deploy
script: echo
resource_group: production