- GitLab CI/CD Primer
- Key similarities and differences
Migrating from Bamboo
This migration guide looks at how you can migrate from Atlassian Bamboo to GitLab CI/CD. The focus is on Bamboo Specs YAML exported from the Bamboo UI or stored in Spec repositories.
GitLab CI/CD Primer
If you are new to GitLab CI/CD, use the Getting started guide to learn
the basic concepts and how to create your first .gitlab-ci.yml
file.
If you already have some experience using GitLab CI/CD, you can review keywords reference documentation
to see the full list of available keywords.
You can also take a look at Auto DevOps, which automatically builds, tests, and deploys your application using a collection of pre-configured features and integrations.
Key similarities and differences
Offerings
Atlassian offers Bamboo in its Cloud (SaaS) or Data center (Self-managed) options. A third Server option is scheduled for EOL on February 15, 2024.
These options are similar to GitLab SaaS and Self-Managed. GitLab also offers GitLab Dedicated, a fully isolated single-tenant SaaS service.
Agents vs Runners
Bamboo uses agents to run builds and deployments. Agents can be local agents running on the Bamboo server or remote agents running external to the server.
GitLab uses a similar concept to agents called runners which use executors to run builds.
Examples of executors are shell, Docker, or Kubernetes. You can choose to use GitLab SaaS runners or deploy your own self-managed runners.
Workflow
Bamboo workflow is organized into projects. Projects are used to organize Plans, along with variables, shared credentials, and permissions needed by multiple plans. A plan groups jobs into stages and links to code repositories where applications to be built are hosted. Repositories could be in Bitbucket, GitLab, or other services.
A job is a series of tasks that are executed sequentially on the same Bamboo agent. CI and deployments are treated separately in Bamboo. Deployment project workflow is different from the build plans workflow. Learn more about Bamboo workflow.
GitLab CI/CD uses a similar workflow. Jobs are organized into stages,
and projects have individual .gitlab-ci.yml
configuration files or include existing templates.
Templating & Configuration as Code
Bamboo Specs
Bamboo plans can be configured in either the Web UI or with Bamboo Specs. Bamboo Specs is configuration as code, which can be written in Java or YAML. YAML Specs is the easiest to use but lacks in Bamboo feature coverage. Java Specs has complete Bamboo feature coverage and can be written in any JVM language like Groovy, Scala, or Kotlin. If you configured your plans using the Web UI, you can export your Bamboo configuration into Bamboo Specs.
Bamboo Specs can also be repository-stored.
.gitlab-ci.yml
configuration file
GitLab, by default, uses a .gitlab-ci.yml
file for CI/CD configuration.
Alternatively, Auto DevOps can automatically build,
test, and deploy your application without a manually configured .gitlab-ci.yml
file.
GitLab CI/CD configuration can be organized into templates that are reusable across projects. GitLab also provides pre-built templates that help you get started quickly and avoid re-inventing the wheel.
Configuration
Bamboo YAML Spec syntax
This Bamboo Spec was exported from a Bamboo Server instance, which creates quite verbose output:
version: 2
plan:
project-key: AB
key: TP
name: test plan
stages:
- Default Stage:
manual: false
final: false
jobs:
- Default Job
Default Job:
key: JOB1
tasks:
- checkout:
force-clean-build: false
description: Checkout Default Repository
- script:
interpreter: SHELL
scripts:
- |-
ruby -v # Print out ruby version for debugging
bundle config set --local deployment true # Install dependencies into ./vendor/ruby
bundle install -j $(nproc)
rubocop
rspec spec
description: run bundler
artifact-subscriptions: []
repositories:
- Demo Project:
scope: global
triggers:
- polling:
period: '180'
branches:
create: manually
delete: never
link-to-jira: true
notifications: []
labels: []
dependencies:
require-all-stages-passing: false
enabled-for-branches: true
block-strategy: none
plans: []
other:
concurrent-build-plugin: system-default
---
version: 2
plan:
key: AB-TP
plan-permissions:
- users:
- root
permissions:
- view
- edit
- build
- clone
- admin
- view-configuration
- roles:
- logged-in
- anonymous
permissions:
- view
...
A GitLab CI/CD .gitlab-ci.yml
configuration with similar behavior would be:
default:
image: ruby:latest
stages:
- default-stage
job1:
stage: default-stage
script:
- ruby -v # Print out ruby version for debugging
- bundle config set --local deployment true # Install dependencies into ./vendor/ruby
- bundle install -j $(nproc)
- rubocop
- rspec spec
Common Configurations
This section reviews some common Bamboo configurations and the GitLab CI/CD equivalents.
Workflow
Bamboo is structured differently compared to GitLab CI/CD. With GitLab, CI/CD can be enabled
in a project in a number of ways: by adding a .gitlab-ci.yml
file to the project,
the existence of a Compliance pipeline in the group the project belongs to, or enabling AutoDevOps.
Pipelines are then triggered automatically, depending on rules or context, where AutoDevOps is used.
Bamboo is structured differently, repositories need to be added to a Bamboo project, with authentication provided and triggers are set. Repositories added to projects are available to all plans in the project. Plans used for testing and building applications are called Build plans.
Build Plans
Build Plans in Bamboo are composed of Stages that run sequentially to build an application and generate artifacts where relevant. Build Plans require a default repository attached to it or inherit linked repositories from its parent project. Variables, triggers, and relationships between different plans can be defined at the plan level.
An example of a Bamboo build plan:
version: 2
plan:
project-key: SAMPLE
name: Build Ruby App
key: BUILD-APP
stages:
- Test App:
jobs:
- Test Application
- Perform Security checks
- Build App:
jobs:
- Build Application
Test Application:
tasks:
- script:
- # Run tests
Perform Security checks:
tasks:
- script:
- # Run Security Checks
Build Application:
tasks:
- script:
- # Run buils
In this example:
- Plan Specs include a YAML Spec version. Version 2 is the latest.
- The
project-key
links the plan to its parent project. The key is specified when creating the project. - Plan
key
uniquely identifies the plan.
In GitLab CI/CD, a Bamboo Build plan is similar to the .gitlab-ci.yml
file in a project,
which can include CI/CD scripts from other projects or templates.
The equivalent GitLab CI/CD .gitlab-ci.yml
file would be:
default:
image: alpine:latest
stages:
- test
- build
test-application:
stage: test
script:
- # Run tests
security-checks:
stage: test
script:
- # Run Security Checks
build-application:
stage: build
script:
- # Run builds
Container Images
Builds and deployments are run by default on the Bamboo agent’s native operating system,
but can be configured to run in containers. To make jobs run in a container, Bamboo uses
the docker
keyword at the plan or job level.
For example, in a Bamboo build plan:
version: 2
plan:
project-key: SAMPLE
name: Build Ruby App
key: BUILD-APP
docker: alpine:latest
stages:
- Build App:
jobs:
- Build Application
Build Application:
tasks:
- script:
- # Run builds
docker:
image: alpine:edge
In GitLab CI/CD, you only need the image
keyword.
The equivalent GitLab CI/CD .gitlab-ci.yml
file would be:
default:
image: alpine:latest
stages:
- build
build-application:
stage: build
script:
- # Run builds
image:
name: alpine:edge
Variables
Bamboo has the following types of variables based on scope:
- Build-specific variables which are evaluated at build time. For example
${bamboo.planKey}
. - System variables inherited from the Bamboo instance or system environment.
- Global variables defined at the instance level and accessible to every plan.
- Project variables defined at the project level and accessible by plans in the same project.
- Plan variables specific to a plan.
You can access variables in Bamboo using the format ${system.variableName}
for System variables
and ${bamboo.variableName}
for other types of variables. When using a variable in a script task,
the full stops, are converted to underscores, ${bamboo.variableName}
becomes $bamboo_variableName
.
In GitLab, CI/CD variables can be defined at these levels:
- Instance.
- Group.
- Project.
- At the global level in the CI/CD configuration.
- At the job level in the CI/CD configuration.
Like Bamboo’s System and Global variables, GitLab has predefined CI/CD variables that are available to every job.
Defining variables in CI/CD scripts is similar in both Bamboo and GitLab.
For example, in a Bamboo build plan:
version: 2
# ...
variables:
username: admin
releaseType: milestone
Default job:
tasks:
- script: echo '$bamboo_username is the DRI for $bamboo_releaseType'
The equivalent GitLab CI/CD .gitlab-ci.yml
file would be:
variables:
GLOBAL_VAR: "A global variable"
job1:
variables:
JOB_VAR: "A job variable"
script:
- echo "Variables are '$GLOBAL_VAR' and '$JOB_VAR'"
In GitLab CI/CD, variables are accessed like regular Shell script variables. For example, $VARIABLE_NAME
.
Jobs & Tasks
In both GitLab and Bamboo, jobs in the same stage run in parallel, except where there is a dependency that needs to be met before a job runs.
The number of jobs that can run in Bamboo depends on availability of Bamboo agents and Bamboo license Size. With GitLab CI/CD, the number of parallel jobs depends on the number of runners integrated with the GitLab instance and the concurrency set in the runners.
In Bamboo, Jobs are composed of Tasks, which can be:
- A set of commands run as a script
- Predefined tasks like source code checkout, artifact download, and other tasks available in the Atlassian tasks marketplace.
For example, in a Bamboo build plan:
version: 2
#...
Default Job:
key: JOB1
tasks:
- checkout:
force-clean-build: false
description: Checkout Default Repository
- script:
interpreter: SHELL
scripts:
- |-
ruby -v
bundle config set --local deployment true
bundle install -j $(nproc)
description: run bundler
other:
concurrent-build-plugin: system-default
The equivalent of Tasks in GitLab is the script
, which specifies the commands
for the runner to execute.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
job1:
script: "bundle exec rspec"
job2:
script:
- ruby -v
- bundle config set --local deployment true
- bundle install -j $(nproc)
With GitLab, you can use CI/CD templates and CI/CD components to compose your pipelines without the need to write everything yourself.
Conditionals
In Bamboo, every task can have conditions that determine if a task runs.
For example, in a Bamboo build plan:
version: 2
# ...
tasks:
- script:
interpreter: SHELL
scripts:
- echo "Hello"
conditions:
- variable:
equals:
planRepository.branch: development
With GitLab, this can be done with the rules
keyword to control when jobs run in GitLab CI/CD.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
job:
script: echo "Hello, Rules!"
rules:
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME = development
Triggers
Bamboo has a number of options for triggering builds, which can be based on code changes, a schedule, the outcomes of other plans, or on demand. A plan can be configured to periodically poll a project for new changes, as shown below.
For example, in a Bamboo build plan:
version: 2
#...
triggers:
- polling:
period: '180'
GitLab CI/CD pipelines can be triggered based on code change, on schedule, or triggered by other jobs or API calls. GitLab CI/CD pipelines do not need to use polling, but can be triggered on schedule as well.
You can configure when pipelines themselves run with the workflow
keyword,
and rules
.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
workflow:
rules:
- changes:
- .gitlab/**/**.md
when: never
Artifacts
You can define Job artifacts using the artifacts
keyword in both GitLab and Bamboo.
For example, in a Bamboo build plan:
version: 2
# ...
artifacts:
-
name: Test Reports
location: target/reports
pattern: '*.xml'
required: false
shared: false
-
name: Special Reports
location: target/reports
pattern: 'special/*.xml'
shared: true
In this example, artifacts are defined with a name, location, pattern, and the optional ability to share the artifacts with other jobs or plans. You canalso define jobs that subscribe to the artifact.
artifact-subscriptions
is used to access artifacts from another job in the same plan,
for example:
Test app:
artifact-subscriptions:
-
artifact: Test Reports
destination: deploy
artifact-download
is used to access artifacts from jobs in a different plan, for example:
version: 2
# ...
tasks:
- artifact-download:
source-plan: PROJECTKEY-PLANKEY
You need to provide the key of the plan you are downloading artifacts from in the source-plan
keyword.
In GitLab, all artifacts from completed jobs in earlier stages are downloaded by default.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
stages:
- build
pdf:
stage: build
script: #generate XML reports
artifacts:
name: "test-report-files"
untracked: true
paths:
- target/reports
In this example:
- The name of the artifact is specific explicitly, but you can make it dynamic by using a CI/CD variable.
- The
untracked
keyword sets the artifact to also include Git untracked files, along with those specified explictly withpaths
.
Caching
In Bamboo, Git caches can be used to speed up builds. Git caches are configured in Bamboo administration settings and are stored either on the Bamboo server or remote agents.
GitLab supports both Git Caches and Job cache. Caches are defined per job
using the cache
keyword.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
test-job:
stage: build
cache:
- key:
files:
- Gemfile.lock
paths:
- vendor/ruby
- key:
files:
- yarn.lock
paths:
- .yarn-cache/
script:
- bundle config set --local path 'vendor/ruby'
- bundle install
- yarn install --cache-folder .yarn-cache
- echo Run tests...
Deployment Projects
Bamboo has Deployments project, which link to Build plans to track, fetch, and deploy artifacts to deployment environments.
When creating a project you link it to a build plan, specify the deployment environment and the tasks to perform the deployments. A deployment task can either be a script or a Bamboo task from the Atlassian marketplace.
For example in a Deployment project Spec:
version: 2
deployment:
name: Deploy ruby app
source-plan: build-app
release-naming: release-1.0
environments:
- Production
Production:
tasks:
- # scripts to deploy app to production
- ./.ci/deploy_prod.sh
In GitLab CI/CD, You can create a deployment job that deploys to an environment or creates a release.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
deploy-to-production:
stage: deploy
script:
- # Run Deployment script
- ./.ci/deploy_prod.sh
environment:
name: production
To create release instead, use the release
keyword with the release-cli
tool to create releases for Git tags.
For example, in a GitLab CI/CD .gitlab-ci.yml
file:
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: $CI_COMMIT_TAG # Run this job when a tag is created manually
script:
- echo "Building release version"
release:
tag_name: $CI_COMMIT_TAG
name: 'Release $CI_COMMIT_TAG'
description: 'Release created using the release-cli.'
Security Scanning features
Bamboo relies on third-party tasks provided in the Atlassian Marketplace to run security scans.
GitLab provides security scanners out-of-the-box to detect
vulnerabilities in all parts of the SDLC. You can add these plugins in GitLab using templates, for example to add
SAST scanning to your pipeline, add the following to your .gitlab-ci.yml
:
include:
- template: Security/SAST.gitlab-ci.yml
You can customize the behavior of security scanners by using CI/CD variables, for example with the SAST scanners.
Secrets Management
Privileged information, often referred to as “secrets”, is sensitive information or credentials you need in your CI/CD workflow. You might use secrets to unlock protected resources or sensitive information in tools, applications, containers, and cloud-native environments.
Secrets management in Bamboo is usually handled using Shared credentials, or via third-party applications from the Atlassian market place.
For secrets management in GitLab, you can use one of the supported integrations for an external service. These services securely store secrets outside of your GitLab project, though you must have a subscription for the service:
GitLab also supports OIDC authentication for other third party services that support OIDC.
Additionally, you can make credentials available to jobs by storing them in CI/CD variables, though secrets stored in plain text are susceptible to accidental exposure, the same as in Bamboo. You should always store sensitive information in masked and protected variables, which mitigates some of the risk.
Also, never store secrets as variables in your .gitlab-ci.yml
file, which is public to all
users with access to the project. Storing sensitive information in variables should
only be done in the project, group, or instance settings.
Review the security guidelines to improve the safety of your CI/CD variables.
Migration Plan
The following list of recommended steps was created after observing organizations that were able to quickly complete this migration.
Create a Migration Plan
Before starting a migration you should create a migration plan to make preparations for the migration. For a migration from Bamboo, ask yourself the following questions in preparation:
- What Bamboo Tasks are used by jobs in Bamboo today?
- Do you know what these Tasks do exactly?
- Do any Task wrap a common build tool? For example, Maven, Gradle, or NPM?
- What is installed on the Bamboo agents?
- Are there any shared libraries in use?
- How are you authenticating from Bamboo? Are you using SSH keys, API tokens, or other secrets?
- Are there other projects that you need to access from your pipeline?
- Are there credentials in Bamboo to access outside services? For example Ansible Tower, Artifactory, or other Cloud Providers or deployment targets?
Prerequisites
Before doing any migration work, you should first:
- Get familiar with GitLab.
- Read about the key GitLab CI/CD features.
- Follow tutorials to create your first GitLab pipeline and more complex pipelines that build, test, and deploy a static site.
- Review the
.gitlab-ci.yml
keyword reference.
- Set up and configure GitLab.
- Test your GitLab instance.
- Ensure runners are available, either by using shared GitLab.com runners or installing new runners.
Migration Steps
- Migrate projects from your SCM solution to GitLab.
- (Recommended) You can use the available importers to automate mass imports from external SCM providers.
- You can import repositories by URL.
- Create a
.gitlab-ci.yml
file in each project. - Export your Bamboo Projects/Plans as YAML Spec
- Migrate Bamboo YAML Spec configuration to GitLab CI/CD jobs and configure them to show results directly in merge requests.
- Migrate deployment jobs by using cloud deployment templates, environments, and the GitLab agent for Kubernetes.
- Check if any CI/CD configuration can be reused across different projects, then create and share CI/CD templates.
- Check the pipeline efficiency documentation to learn how to make your GitLab CI/CD pipelines faster and more efficient.
If you have questions that are not answered here, the GitLab community forum can be a great resource.