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

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

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 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()

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

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")
}

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 )

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{}
}

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

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'
}

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

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

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!

Software engineer, Cloud Architect, 5/5 AWS|GCP|PSM Certified, Owner of kubernetes.tn