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!