The only Jenkins Plugins you need
Tags: jenkins, devops
Published: 2022-07-29 15:03:00

Tired of the plugin headaches maintaining a Jenkins Controller? Get rid of them.

Jenkins has a wealth of plugins available that cover almost everything you could want to in a Jenkins “native” way. While this may make certain activities easier it can lead to and administration nightmare, especially if the Jenkins Controller is used by more than one team.

## What administration problems?
### Different features
Plugins are often versioned and only single versions of each plugin is allowed to be installed. This can be problematic when one team wants to use up-to-date features e.g. in the Groovy language plugin, while another team is relying on features that have been deprecated and removed in the latest plugin versions

### Pinning
Pinning to a specific version of a plugin is good practice as it stops unexpected changes in behaviour however this means that someone needs to be manually on top of the plugins, checking for new versions ensuring the new versions are compatible with your workflows, communicating breaking changes to the users base etc, and obviously the more plugins you have installed the more manual effort is required.

The alternative is to run plugins unpinned on the latest versions which works for many, but does run the risk of a plugin API changing or a relied on feature being deprecated/removed and breaking a whole host of jobs which no one wants to be dealing with on a Monday morning, or worse being called out on a Saturday afternoon.

Note: I don’t see leaving plugin pinned and not checking on them as an options as you will very quickly have a Jenkins controller full of security holes and on a Jenkins version that cannot be upgraded.

### Plugin Support
Most plugins are not maintained by the Core Jenkins team or Cloudbees, but are community maintained or have maintainers with other jobs and interests. Therefore it is not uncommon for plugins to be abandoned and left with no maintainer. Again it is up to the Jenkins operators to lookout for these plugins and then find alternatives, or end up with security holes through unpatched plugins.

## So what do I do without plugins?
### Docker
Jenkins allows you to run stages in Docker containers which means you can have any tools that you require in a container rather than as a plugin or installed and managed on every agent. Need to run some Terraform? Use the Docker container. Need to build a Maven project? Use the Docker container.

For more information on how to use Docker agents see https://www.jenkins.io/doc/book/pipeline/docker/

```
stage("Terraform Testing") {
  agent {
    docker {
      image "hashicorp/terraform"
      reuseNode true
      args "-v /etc/passwd:/etc/passwd:rw,z -v ${env.WORKSPACE}@tmp:${env.AGENT_HOME}:rw,z -v /etc/group:/etc/group:rw,z"
    }
  }
  stages {
    stage("Terraform Format") {
      steps {
        dir("${working_directory}") {
          sh("terraform fmt -check")
        }
      }
    }
  }
}
```

Not only does Docker allow you to use whatever tooling suits you without managing plugins and potentially multiple installations of the same tool, it allows you to run different versions of the tools at different times.
e.g. In production you might want to run the current stable version of a tool, but in dev you might want to test upgrading the tool version to ensure you pipelines are working.

You could also create a custom Docker container that includes all the tooling you need for building and releasing which can be tested versioned and released like any other project. This allows all teams to work in lockstep with each other on supported tooling.

Using a private container registry also means no nasty surprises from things changing when you are not expecting it e.g. a plugin being removed from the update centre.

```
stage("Terraform Testing") {
  agent {
    docker {
      image "hashicorp/terraform"
      registryUrl 'https://my-registry.com'
      registryCredentialsId 'registry-jenkins-credential'
      reuseNode true
      args "-v /etc/passwd:/etc/passwd:rw,z -v ${env.WORKSPACE}@tmp:${env.AGENT_HOME}:rw,z -v /etc/group:/etc/group:rw,z"
    }
  }
  stages { ...
```

### Shared Libraries
Jenkins Shared Libraries extend the core Jenkins functionality by allowing you to create functions that can be called like Jenkins steps. This allows you to perform actions that you need to do regularly (or share between teams), but don’t want to use Docker for and want to avoid a plugin e.g. calling a third party API, shifting some artifacts to S3 or transforming some data.

## So what plugins do I need?
Of course there will be some plugins that are required, but try to stick to Jenkins, Cloudbees or major providers (Amazon, Google etc) as these are less likely to be dropped and more likely to be released and patched on regular cadence.
I have broken these out into four sections of plugin, all of which I use on a daily basis and are the only ones installed on my controllers.
Firstly the essential plugins that are so mega useful on every modern Jenkins Controller. Then Security as enhancing the security posture of a Jenkins (especially if shared) is essential, and, Cloud Provider (or VMWare etc). I use AWS so have noted the plugins I use for this provider, however I suspect the other main players have similar plugins I just cannot vouch for them without using them in anger. Then finally utility for those plugins that I use to integrate with third party tooling.

Most of the plugins will be already familiar if not the docs generally explain their usage well.

### The Essentials
- Ansicolor https://plugins.jenkins.io/ansicolor/
- blueocean https://plugins.jenkins.io/blueocean/
- configuration-as-code https://plugins.jenkins.io/configuration-as-code/
- copyartifact https://plugins.jenkins.io/copyartifact/
- docker-workflow https://plugins.jenkins.io/docker-workflow/
- git https://plugins.jenkins.io/git/
- job-dsl https://plugins.jenkins.io/job-dsl/
- lockable-resources https://plugins.jenkins.io/lockable-resources/
- mask-passwords https://plugins.jenkins.io/mask-passwords/
- pipeline-model-definition https://plugins.jenkins.io/pipeline-model-definition/
- pipeline-utility-steps https://plugins.jenkins.io/pipeline-utility-steps/
- timestamper https://plugins.jenkins.io/timestamper/
- ws-cleanup https://plugins.jenkins.io/ws-cleanup/

### Jenkins Security (examples)
- ldap https://plugins.jenkins.io/ldap/
- role-strategy https://plugins.jenkins.io/role-strategy/
- github-oauth https://plugins.jenkins.io/github-oauth/

### Cloud Provider (I use AWS)
- ec2 https://plugins.jenkins.io/ec2/
- configuration-as-code-secret-ssm https://plugins.jenkins.io/configuration-as-code-secret-ssm/
- pipeline-aws https://plugins.jenkins.io/pipeline-aws/
- aws-parameter-store https://plugins.jenkins.io/aws-parameter-store/

### Utility
- artifactory https://plugins.jenkins.io/artifactory/
- github https://plugins.jenkins.io/github/
- slack https://plugins.jenkins.io/slack/

So thats it. They are the only plugins on my Jenkins Controller. Everything else for running jobs building various jobs in various language (python, lambdas, maven, ansible, kubernetes, packer, terraform etc) is all done through Docker containers and share libs.

## General Advice
- Use lots of smaller Jenkins Controllers rather than big shared ones
- Invest the time to automate rebuilds using Jenkins Config as Code and job-dsl to re-generate jobs
- Have test Jenkins that are rebuilt with the latest plugins and a representative set of test pipelines
- Store the Jenkins Home directory on a separate drive to the rest of the controller
- Run Jenkins in Docker to make upgrades super easy. This means using external build agents to run builds without having proxied Docker sockets and horrible hacks. I would do this anyway to keep the Controller free.