Save 37% off PRO during our Black Friday Sale! »

Bootstrapping Jenkins

Bootstrapping Jenkins

Today, "infrastructure as code" has become normality for many of us. We provision our systems with the push of a button or via CI jobs, Jenkins probably being the most popular CI server to host these jobs. But how do we manage our Jenkins server? Quite frequently, it is manually installed. Security, credentials, plugins, jobs have to be configured. But what do we do if the server crashes? The more we move towards continuous delivery/deployment, the more important the permanent availability of the CI server is. In case of problems, we must be able to recreate it from scratch any time. This talk shows how we can spin up an instance with Terraform and provision a fully configured Jenkins master/slave setup based on Docker Compose with Ansible including Træfik as reverse proxy and TLS certificates from Let's Encrypt. The main focus will be on demonstrating how we can completely configure Jenkins via init scripts in Groovy.

5627a6711888317828bc84670537816f?s=128

Reinhard Nägele

October 25, 2017
Tweet

Transcript

  1. Bootstrapping Jenkins Reinhard Nägele 1 @unguiculus

  2. 2 Reinhard Nägele •Senior IT Consultant at codecentric AG •Kubernetes

    Helm Charts Maintainer •@unguiculus
  3. What? 3

  4. What? Google Cloud VM Instance Docker Network Træfik Jenkins Master

    Jenkins Agent https 4
  5. 5 Infrastructure as Code Reduce cost Be fast Reduce risk

    Reproducible from scratch any time
  6. Terraform 6 Create infrastructure on Google Cloud Platform VM Instance

    Domain/DNS
  7. Ansible 7 Configure instance and start up services Install Docker

    and Docker Compose Create user Checkout Git repo Copy bootstrap config files for Jenkins Pull and build Docker images Start services with Docker Compose
  8. Docker 8 Master/agent setup Træfik as reverse proxy, terminates TLS

    Let’s Encrypt Two Docker Compose projects One Docker network
  9. Show me some code! 9

  10. Jenkins Init Scripts •Written in Groovy •Must be in $JENKINS_HOME/init.groovy.d

    •Run during (every!) startup •Full access to Jenkins API 10
  11. Jenkins Init Scripts 11 def instance = Jenkins.getInstance() instance.setNumExecutors(0) instance.setNoUsageStatistics(true)

    instance.save()
  12. Jenkins Init Scripts •Make sure they are idempotent •Do I

    need to run them on every startup? •What about updates or reconfiguring Jenkins? 12
  13. Jenkins Init Scripts 13 CredentialsStore store = SystemCredentialsProvider.getInstance().getStore() def cred

    = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, 'my-cred-id', 'My User', 'admin', 'secret') def creds = CredentialsProvider.lookupCredentials(cred.class, Jenkins.getInstance(), ACL.SYSTEM, []) def oldCred = creds.findResult { it.id == cred.id ? it : null } if (oldCred) { store.updateCredentials(Domain.global(), oldCred, cred) } else { store.addCredentials(Domain.global(), cred) } store.save()
  14. Advanced Init Scripting •init.groovy.d: One trivial init script that runs

    on every startup •init.lib: Additional scripts that run only when configuration is in place •/etc/jenkins_bootstrap: Config files, copied by Ansible •Once run, configuration is deleted 14
  15. Advanced Init Scripting 15

  16. IDE Setup •Gradle project •Add Jenkins Maven repo: http://repo.jenkins-ci.org/releases/ •Add

    folders with init scripts to Groovy source paths •Add dependencies for plugins you need to configure 16
  17. Job DSL •Use job DSL to generate all jobs •Gradle

    setup •Job DSL can be tested using Jenkins Test Harness •Use multi-branch pipeline job for seed job •Sample project: https://github.com/unguiculus/job-dsl-sample 17
  18. Show me some more code! 18

  19. Check it out! •All sources available on Github
 https://github.com/unguiculus/docker-jenkins-bootstrap •Feedback

    and PRs welcome 19
  20. 20 Thank you Reinhard Nägele https://github.com/unguiculus @unguiculus