Deploy A Jenkins Cluster On AWS - A Cloud Guru PDF
Deploy A Jenkins Cluster On AWS - A Cloud Guru PDF
A few months ago, I gave a talk at Nexus User Conference 2018 on how
to build a fully automated CI/CD platform on AWS using Terraform,
Packer & Ansible.
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 1/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
The platform has a Jenkins cluster with a dedicated Jenkins master and
workers inside an autoscaling group. Each push event to the code
repository will trigger the Jenkins master which will schedule a new
build on one of the available slave nodes.
The slave nodes will be responsible of running the unit and pre-
integration tests, building the Docker image, storing the image to a
private registry and deploying a container based on that image to
Docker Swarm cluster.
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 2/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
On this post, I will walk through how to deploy the Jenkins cluster on
AWS using the latest automation tools.
The cluster will be deployed into a VPC with 2 public and 2 private
subnets across 2 availability zones. The stack will consists of an
autoscaling group of Jenkins workers in a private subnets and a private
instance for the Jenkins master sitting behind an elastic Load balancer.
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 3/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
To get started, we will create 2 AMIs (Amazon Machine Image) for our
instances. To do so, we will use Packer, which allows you to bake your
own image.
The first AMI will be used to create the Jenkins master instance. The
AMI uses the Amazon Linux Image as a base image and for provisioning
part it uses a simple shell script:
1 {
2 "variables" : {
3 "region" : "eu-west-3",
4 "source_ami" : "ami-0ebc281c20e89ba4b"
5 },
6 "builders" : [
7 {
8 "type" : "amazon-ebs",
9 "profile" : "default",
10 "region" : "{{user `region`}}",
11 "instance_type" : "t2.micro",
12 "source_ami" : "{{user `source_ami`}}",
13 "ssh_username" : "ec2-user",
14 "ami_name" : "jenkins-master-2.107.2",
15 "ami_description" : "Amazon Linux Image wi
16 "run_tags" : {
17 "Name" : "packer-builder-docker"
18 },
19 "tags" : {
20 "Tool" : "Packer",
21 "Author" : "mlabouardy"
22 }
23 }
24 ],
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 4/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
1 #!/bin/bash
2
3 echo "Install Jenkins stable release"
4 yum remove -y java
5 yum install -y java-1.8.0-openjdk
6 wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenki
7 rpm --import https://jenkins-ci.org/redhat/jenkins-ci.
8 yum install -y jenkins
9 chkconfig jenkins on
10
11 echo "Install Telegraf"
12 wget https://dl.influxdata.com/telegraf/releases/teleg
13 yum localinstall -y /tmp/telegraf.rpm
14 rm /tmp/telegraf.rpm
15 chkconfig telegraf on
16 mv /tmp/telegraf.conf /etc/telegraf/telegraf.conf
17 service telegraf start
18
19 echo "Install git"
20 yum install -y git
21
22 echo "Setup SSH key"
23 mkdir /var/lib/jenkins/.ssh
24 touch /var/lib/jenkins/.ssh/known_hosts
25 chown -R jenkins:jenkins /var/lib/jenkins/.ssh
26 chmod 700 /var/lib/jenkins/.ssh
27 mv /tmp/id_rsa /var/lib/jenkins/.ssh/id_rsa
28 chmod 600 /var/lib/jenkins/ ssh/id rsa
It will install the latest stable version of Jenkins and configure its
settings:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 5/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
The second AMI will be used to create the Jenkins workers, similarly to
the first AMI, it will be using the Amazon Linux Image as a base image
and a script to provision the instance:
1 #!/bin/bash
2
3 echo "Install Java JDK 8"
4 yum remove -y java
5 yum install -y java-1.8.0-openjdk
6
7 echo "Install Docker engine"
8 yum update -y
9 yum install docker -y
10 usermod -aG docker ec2-user
11 service docker start
12
13 echo "Install git"
14 yum install -y git
15
16 echo "Install Telegraf"
Now our Packer template files are defined, issue the following
commands to start baking the AMIs:
Packer will launch a temporary EC2 instance from the base image
specified in the template file and provision the instance with the given
shell script. Finally, it will create an image from the instance. The
following is an example of the output:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 6/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
Now our AMIs are ready to use, let’s deploy our Jenkins cluster to AWS.
To achieve that, we will use an infrastructure as code tool called
Terraform, it allows you to describe your entire infrastructure in
templates files.
Another template file used as a reference to each AMI built with Packer:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 7/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 8/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 9/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
1 #!/bin/bash
2
3 JENKINS_URL="${jenkins_url}"
4 JENKINS_USERNAME="${jenkins_username}"
5 JENKINS_PASSWORD="${jenkins_password}"
6 TOKEN=$(curl -u $JENKINS_USERNAME:$JENKINS_PASSWORD ''
7 INSTANCE_NAME=$(curl -s 169.254.169.254/latest/meta-da
8 INSTANCE_IP=$(curl -s 169.254.169.254/latest/meta-data
9 JENKINS_CREDENTIALS_ID="${jenkins_credentials_id}"
10
11 sleep 60
12
13 curl -v -u $JENKINS_USERNAME:$JENKINS_PASSWORD -H "$TO
14 import hudson.model.Node.Mode
15 import hudson.slaves.*
16 import jenkins.model.Jenkins
17 import hudson.plugins.sshslaves.SSHLauncher
18 DumbSlave dumb = new DumbSlave("'$INSTANCE_NAME'",
At boot time, the user-data script above will be invoked and the instance
private IP address will be retrieved from the instance meta-data and a
groovy script will be executed to make the node join the cluster:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 10/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
1 // Scale out
2 resource "aws_cloudwatch_metric_alarm" "high-cpu-jenki
3 alarm_name = "high-cpu-jenkins-slaves-alarm
4 comparison_operator = "GreaterThanOrEqualToThreshold
5 evaluation_periods = "2"
6 metric_name = "CPUUtilization"
7 namespace = "AWS/EC2"
8 period = "120"
9 statistic = "Average"
10 threshold = "80"
11
12 dimensions {
13 AutoScalingGroupName = "${aws_autoscaling_group.je
14 }
15
16 alarm_description = "This metric monitors ec2 cpu ut
17 alarm_actions = ["${aws_autoscaling_policy.scale
18 }
19
20 resource "aws_autoscaling_policy" "scale-out" {
21 name = "scale-out-jenkins-slaves"
22 scaling_adjustment = 1
23 adjustment_type = "ChangeInCapacity"
24 cooldown = 300
25 autoscaling_group_name = "${aws_autoscaling_group.je
26 }
27
28 // Scale In
29 resource "aws_cloudwatch_metric_alarm" "low-cpu-jenkin
30 alarm_name = "low-cpu-jenkins-slaves-alarm"
31 comparison_operator = "LessThanOrEqualToThreshold"
32 evaluation_periods = "2"
33 metric_name = "CPUUtilization"
34 namespace = "AWS/EC2"
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 11/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
1 region = ""
2
3 aws_profile = ""
4
5 shared_credentials_file = ""
6
7 key_name = ""
8
9 hosted_zone_id = ""
10
11 bastion_sg_id = ""
12
13 jenkins_username = ""
14
15 jenkins_password = ""
16
17 jenkins credentials id = ""
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 12/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
In the terminal session, under the Outputs section, the Jenkins URL will
be displayed:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 13/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
Point your favorite browser to the URL displayed, the Jenkins login
screen will be displayed. Sign in using the credentials provided while
baking the Jenkins master’s AMI:
The same goes for “Plugins”, a list of needed packages will be installed
also:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 14/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
Once the Autoscaling group finished creating the EC2 instances, the
instances will join the cluster automatically as you can see in the
following screenshot:
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 15/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
You can take this further and build a dynamic dashboard in your
favorite visualization tool like Grafana to monitor your cluster resource
usage based on the metrics collected by the agent installed on each EC2
instance:
https://github.com/mlabouardy/grafana-dashboards
mlabouardy/nexususerconference-
infrastructure
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 16/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 17/18
5/2/2019 Deploy a Jenkins Cluster on AWS – A Cloud Guru
https://read.acloud.guru/deploy-a-jenkins-cluster-on-aws-35dcf66a1eca 18/18