Abdennour Toumi

Jul 18, 2021

3 min read

Practical Comparison — From Jenkins to Drone CI

I am currently migrating from Jenkins to Drone CI after more than 3 years serving Jenkins as a pipeline service for a large organizations. While i am migrating, i found it’s useful to share my observations instantly. That’s why, this article will be continuously updated based on my knowledge expansion on Drone CI.

1. Pipeline Configuration as Code

  • Jenkins

it’s a file called by default “Jenkinsfile” to be added in your app git repo. It should be implemented with Groovy programming language

  • Drone CI

it’s a file called by default “.drone.yml” to be added in your app git repo. It should be implemented with YAML programming language.

2. Standarization Layer

  • Jenkins

Jenkins provides the concept of library which can be configured in 3 steps :

a. a library is a git repository (.ie. https://git.example/jenkins-lib.git )with at least a subdirectory called “vars” and one step i.e. “vars/my_step.groovy”

b. Then, you can configure your jenkins instance with this library under Configure > Global Pipelines section

Or using config-as-code

unclassified:
globalLibraries:
libraries:
- name: "my-lib"
retriever:
modernSCM:
scm:
git:
remote: "https://git.example/jenkins-lib.git

c. You use it in your Jenkinsfile as following

// import library as per its name in the admin configuration 
@Library('my-lib') _
.....
...
// reuse step
my_step()
  • Drone CI

a. So you define a template

and this is an example of jsonnet template (https://docs.drone.io/template/jsonnet/)

b. then you persist this template using drone CLI:

# drone template add [namespace] [name] [data]

this is a live demo as well https://harness.io/blog/continuous-integration/drone-configuration-templates/

3. In-pipeline Reusability

  • Jenkins

Just define your reusable block as a groovy function at the top or at the bottom, then call that function

pipeline {    deploy('dev')
...
deploy('prod')
}def deploy(env) {
vault_pull('terraform/state');
sh("TERRAFORM_ENV=${env} terraform apply -auto-approve")
}
  • Drone CI

Use the built-in feature of YAML of reusing blocks of yaml. Make sure that your YAML template (block) is prefixed by “x-”

x-deploy: &x-deploy
image: terraform
commands:
- terraform apply -auto-approve
steps:
- name: deploy-to-dev
<<: *x-deploy
environment:
TERRAFORM_ENV: dev
- name: deploy-to-prod
<<: *x-deploy
environment:
TERRAFORM_ENV: prod

4. Parallelism (Steps Execution )

  • Jenkins

Can be done thru parallel {} step.

example before parallelism

 step_build_x{}
step_build_y{}

example refactor for parallelism

parallel {
step_build_x{}
step_build_y{}
}
  • Drone CI

By default, steps run sequentially. As soon, as you start using “depends_on” key word, you break this sequence run, and parallelism can be enabled implicitly.

example before parallelism

steps:
- name: init
image: ...
- name: build-x
image: ...
- name: build-y
image: ....

example refactored for parallelism ( build-x and build-y to run in parallel)

steps:
- name: init
image: ...
- name: build-x
image: ...
depends_on:
- init
- name: build-y
image: ...
depends_on:
- init

5. Global secrets

  • Jenkins

You can define them in your admin dashboard Configure > Credentials

OR using config-as-code

credentials:
system:
domainCredentials:
- credentials:
- string:
scope: GLOBAL
id: "aws-secret"
secret: "MySuperSecret"
description: "AWS Secret Key"

Then, in your pipeline, you can use it as following:

string(credentialsId: 'aws-secret', variable: 'AWS_SECRET_ACCESS_KEY') {
// it's now available as env var env.AWS_SECRET_ACCESS_KEY
sh 'aws cloudformation update-template'
}
  • Drone CI:

Define your secret at organization leve using drone CLI

export DRONE_SERVER=http://drone.company.local DRONE_TOKEN=<admin-user-token>drone orgsecret add <myorg> aws-secret MySuperSecret

then use it in pipeline as following:

steps:
- image: amazon/aws-cli
command: aws cloudformation update-template ...
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws-secret

6. External Secrets — Kubernetes Secrets

  • Jenkins

it requires to install kubernetes plugin,configure a cloud ( kubernetes cluster where agents will be provisioned) then you can define your Pod template.

In the pod template, you can attach whatever k8s secret as env variables

  • Drone CI

It requires to run Drone CI in kubernetes with pipeline of type: kubernetes

it requires to install kubernetes runner : drone-runner-kube

It requires to install the extension: drone-kubernetes-secrets

Then you can use it as following : https://docs.drone.io/secret/external/kubernetes/

7. Trigger for specific files/folders updates

Jenkins: Built-in by using when { changeset "my-dir/*"} keyword

Drone CI: check extensions mentioned here https://discourse.drone.io/t/can-builds-be-triggered-only-when-specific-files-folders-are-updated/9064

Bonus

My course about cloudnative with docker and docker compose https://www.udemy.com/course/cloud-native-docker/?couponCode=FIRSTCOHORT

Comparison between Jenkins and Drone CI Will be continuous updated

Stay tuned!