Jenkins has always been a bit of an elephant in the room to me. Not being a developer I have always just shrugged it off a tool used for running unit tests, however, as I moving more into orchestration and automation I am finding the need for a tool which can run both tasks and unit tests, so this weekend I decided to finally take the plunge and have a play around with it.

As always I started off with a blank CentOS 7 server hosted in Digital and ran my bootstrap script to get the basics sorted.

Once I had that in order I grabbed the repo file for the Jenkins RPM repository and installed the package along with Java and NGINX;

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm  import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install nginx httpd-tools java-1.7.0-openjdk jenkins

As there is only going to be me using this installation I decided that I would use NGINX to provide both the SSL termination and also the password protection for the installation.

I started by creating the password file for NGINX to use;

htpasswd -c /etc/nginx/.htpasswd my_username

The NGINX config file which was called /etc/nginx/conf.d/jenkins.conf looks like this;

server {
 listen 80;
 server_name jenkins.super-awesome-domain.io;
 return 301 https://$host$request_uri;
}

server {

listen 443;
 server_name jenkins.super-awesome-domain.io;

ssl_certificate /etc/letsencrypt/live/jenkins.super-awesome-domain.io/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/jenkins.super-awesome-domain.io/privkey.pem;

ssl on;
 ssl_session_cache builtin:1000 shared:SSL:10m;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
 ssl_prefer_server_ciphers on;

access_log /var/log/nginx/jenkins.access.log;

location / {

auth_basic Restricted;
 auth_basic_user_file /etc/nginx/.htpasswd;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_pass http://localhost:8080;
 proxy_read_timeout 90;
 proxy_redirect http://localhost:8080 https://jenkins.super-awesome-domain.io;
 }
 }

As you have noticed I got the certificate from the incredibly awesome LetEncrypt external link . As the domain I was using was already resolving to the server getting the certificate was a simple as running the following commands and then following the on screen prompts;

cd /root/
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt/
./letsencrypt-auto certonly

As I wasn’t going to directly expose Jenkins to the world, I configured it to listen on localhost, that way we don’t have a Java service bond directly publicly available NIC. To do this run the following command;

echo JENKINS_ARGS=  webroot=/var/cache/jenkins/war  httpListenAddress=127.0.0.1  httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT > /etc/default/jenkins

Finally, it’s time to enable the firewall, by default Firewalld has the ssh port (22) configured. As the bootstrap script installed Fail2Ban, and also password enabled login is disabled on the instance so I am happy to keep the port open. So we just need to enable ports 80 & 443;

systemctl enable firewalld && systemctl restart firewalld
firewall-cmd  zone=public  add-port=80/tcp  permanent
firewall-cmd  zone=public  add-port=443/tcp  permanent
firewall-cmd  reload

Finally, its time to enable and start the rest of the services;

systemctl enable jenkins.service && systemctl restart jenkins.service
systemctl enable nginx.service && systemctl restart nginx

If everything went as planned you should be able to access Jenkins at the domain name you configured in the NGINX configuration.

Once I had access to the GUI I configured Jenkins to deploy this blog whenever it detects a change at the repo external link . I won’t go into to the details here as there are both AWS access keys and Cloudflare API keys involved in the configuration, and knowing my luck I would end up getting hacked because I exposed them.