Skip to content

Launching a Jenkins Master using AWS CloudFormation


Jenkins


Ampersand
CloudFormation

For more information on Jenkins, visit jenkins.io


Jenkins CFT Description


This article will walk though the contents, and usage of the included CloudFormation template that launches a master Jenkins node on a single EC2 instance. Running the CloudFormation template will yield a fully functional instance with Jenkins installed, configuredand ready for login.

The CloudFormation template that we will be using in this tutorial instantiates the following resources:

  • Jenkins EC2 Instance
  • Additional 25GB EBS volume mounted to /var/lib/jenkins on the EC2 Instance
  • Firewall configured with --add-service=ssh, --add-port=${JenkinsPort}/tcp=
  • Security Group Created and applied to allow TCP/SSH, and TCP/${JenkinsPort}, open to the IP address or IP Range specified in the SSHLOCATION parameter.


Jenkins CFT Pre-Requisites


1.    Active AWS Account:
You must have an active AWS account, with enough access to be able to create/update/delete CloudFormation stacks and EC2 instances.


Stack Deployment Setup


1.    Log into your AWS account:
Open a browser window and visit the AWS Console Page


2.    Locate and navigate to CloudFormation: From the top left side of the navigational menu bar, click on the Services menu, and then choose CloudFormation by either navigating to the Management Tools section of the listed services, or by typing the first few letters of the service name in the search box, and then choosing it from the filtered list.


CloudFormation


3.    Copy CF Template:

We will use the following CloudFormation template in order to launch off the Jenkins instance. Copy the CloudFormation template below and save it locally on your drive as jenkins_cf_deployment.yaml. If you are using a remote host to run this lab, then copy the template to your clipboard, and on the build host, again paste the template into a file using vim /media/jenkins_cf_deployment.yaml, i, paste, and save the file by typing esc, :wq!.


AWSTemplateFormatVersion: "2010-09-09"
# Description of what this CloudFormation Template is going to produce
Description: AWS CloudFormation Jenkins Template to create a Stand Alone Jenkins server stack using a single EC2 instance
# Define Parameter Variables that will be used throughout this Cloudformation template.
Parameters:
  InstanceType:
    Description: Type of EC2 instance to launch for the server. Only Compute type nodes are currently specified.
    Type: String
    Default: t2.medium
    ConstraintDescription: Must be a valid EC2 instance type
    AllowedValues: 
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
      - t2.xlarge
      - t2.2xlarge
      - m4.large
      - m4.xlarge
      - m4.2xlarge
      - m4.4xlarge
      - m4.10xlarge
      - m4.16xlarge
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5.4xlarge
      - m5.12xlarge
      - m5.24xlarge
  VpcId:
    Description: VPC ID that this stack will be launched in.
    Type: AWS::EC2::VPC::Id
    AllowedPattern: "[a-z0-9-]*"
  SubnetId:
    Description: VPC Subnet that this stack will be launched in.
    Type: AWS::EC2::Subnet::Id
    AllowedPattern: "[a-z0-9-]*"
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance(s).
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: Must be the name of an existing EC2 KeyPair
  SSHLocation:
    Description: The source IP address (/32) or source IP address range (x.x.x.x/x) that will be allowed to SSH to the EC2 instances
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
    ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x
  JenkinsPort:
    Description: The Port that will be used to access Jenkins (Must be port 1024 or above, unless changing jenkins user).
    Type: Number
    MinValue: 1024
    MaxValue: 65535
    Default: 8080
  InstanceTagName:
    Description: Instance Name tag that will be used to define the Name of the instance resource(s)
    Type: String
    Default: Jenkins

# Create an easy mapping, simply mapping the region selected to the appropriate Amazon Linux 2 AMI
# AMI ID's Updated 8/20/18
Mappings: 
  RegionMap: 
    'us-east-1': 
      AMI: 'ami-04681a1dbd79675a5'
    'us-east-2': 
      AMI: 'ami-0cf31d971a3ca20d6'
    'us-west-1': 
      AMI: 'ami-0782017a917e973e7'
    'us-west-2': 
      AMI: 'ami-6cd6f714'

# Define Resources that will be launched via this template
Resources:
  # EC2 Server Instance Definition
  JenkinsInstance:
    Description: Jenkins Standalone EC2 Instance running Java 8, and Jenkins.
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        # configSets is used when there are multiple configs that you want to run, for multiple instances. If not needed then just config (default) is adequate.
        configSets:
          default: [mountVolume, config, jenkinsConfig]
        # This configSet will define how we handle the additional EBS volume that we create with the Instance. We will mount the volume in /var/lib/Jenkins
        mountVolume:
          commands:
            01_mkdir:
              command: sudo mkdir -p /var/lib/jenkins
            02_fdisk:
              command: echo -e "o\nn\np\n1\n\n\nw" | sudo fdisk /dev/sdb
            03_wait:
              command: sleep 3
            04_mkfs:
              command: sudo mkfs.ext4 /dev/sdb1
            05_disk_label:
              command: e2label /dev/sdb1 JENKINS
            06_fstab:
              command: echo -e "LABEL=JENKINS     /var/lib/jenkins    ext4   defaults 0 0" >> /etc/fstab
            07_mount:
              command: mount -a

        # This configSet will perform the actual installation of Jenkins
        jenkinsConfig:
          packages:
            yum:
              wget: []
              java-1.8.0-openjdk: []
              java-1.8.0-openjdk-devel: []
              net-tools: []
              git: []
              jq: []
          commands:
            01_epel_repo:
              command: sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
            02_jenkins_repo:
              command: sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
            03_yum_clean:
              command: yum clean all
            04_jenkins_key:
              command: sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
            05_jenkins_dirs:
              command: sudo mkdir -p /home/jenkins /var/lib/jenkins/.ssh /var/cache/jenkins/war /var/log/jenkins
            06_jenkins_install:
              command: sudo yum install -y jenkins
            07_check_jenkins_login:
              command: usermod -s /bin/bash jenkins
            08_set_jenkins_port:
              command: !Sub |
                sudo sed -i "s/JENKINS_PORT=\"8080\"/JENKINS_PORT=\"${JenkinsPort}\"/g" /etc/sysconfig/jenkins
            09_sshconfig:
              command: sudo echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /var/lib/jenkins/.ssh/config
            10_ssh_keygen:
              command: sudo ssh-keygen -t rsa -b 2048 -C jenkins@jenkins -N "" -f /var/lib/jenkins/.ssh/id_rsa; sudo cat /var/lib/jenkins/.ssh/id_rsa.pub > /var/lib/jenkins/.ssh/authorized_keys
            11_set_permissions:
              command: sudo chown -R jenkins:jenkins /home/jenkins /var/lib/jenkins /var/cache/jenkins /var/log/jenkins; sudo chmod 0700 /var/lib/jenkins/.ssh; sudo chmod 0600 /var/lib/jenkins/.ssh/*
            12_firewall:
              command: !Sub |
                sudo firewall-cmd --permanent --add-service=ssh; sudo firewall-cmd --permanent --add-port='${JenkinsPort}'/tcp; sudo firewall-cmd --reload
          services:
            sysvinit:
              jenkins:
                enabled: true
                ensureRunning: true

        # Default Config, which handles installing the firewall, and CFN components to talk back to CloudFormation
        config:
          packages:
            yum:
              firewalld: []
          commands:
            01_update:
              command: yum -y update
          files:
            '/etc/cfn/cfn-hup.conf':
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=1
              mode: '000400'
              owner: root
              group: root
            '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.JenkinsInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init --verbose --stack=${AWS::StackName} --region=${AWS::Region} --resource=JenkinsInstance
                runas=root
          services:
            sysvinit:
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - '/etc/cfn/cfn-hup.conf'
                  - '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
              firewalld:
                enabled: true
                ensureRunning: true

    # Properties of the Instance that we are launching. Here we define things like EBS volumes, SG's, The AMI used, etc..
    Properties:
      # Create the 25GB EBS volume that we will use for /var/lib/jenkins
      BlockDeviceMappings:
        - DeviceName: /dev/sdb
          Ebs:
            DeleteOnTermination: false
            VolumeType: gp2
            VolumeSize: 25
      # Pull the Image or AMI from the RegionMap Map we defined earlier
      ImageId: !FindInMap
        - RegionMap
        - !Ref 'AWS::Region'
        - AMI
      # Pull the Intance Type, Subnet, KeyName, etc from the Parameters we defined earlier
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          DeleteOnTermination: true
          SubnetId: !Ref SubnetId
          # This defines the SG that we will place on the ENI, We will create the SG after the instance resource definition
          GroupSet: 
            - !Ref ServerSecurityGroup
      KeyName: !Ref KeyName
      Tags:
       - Key: Name
         Value: !Ref InstanceTagName
      # Use the user data to instantiate the cfn service, which will report back to CloudFormaton once the instance is set up
      UserData:
        Fn::Base64: !Sub |     # No more Fn::Join needed
          #!/bin/bash -x
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource JenkinsInstance --region ${AWS::Region}
          /opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource JenkinsInstance
    # Creation Policy will ensure that if the instance isn't complete within the specified window, that a rollback will occur
    CreationPolicy:
      ResourceSignal:
        Count: '1'
        Timeout: PT15M

  # Define the Security Group that will be appended to the ENI of the Instance we are creating.  
  ServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group that will be used for the Jenkins instance. Open ports 22, and the JenkinsPort
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
        - IpProtocol: tcp
          FromPort: !Ref JenkinsPort
          ToPort: !Ref JenkinsPort
          CidrIp: !Ref SSHLocation

# Specify any outputs for the stack.
Outputs:
  TemplateID:
    Description: 'Jenkins Single Server Template'
    Value: 'Jenkins Single Server Template'
  PublicIp:
    Description: 'The Public IP address of the EC2 Instance'
    Value: !GetAtt JenkinsInstance.PublicIp
  ServerAddress:
    Description: 'The public DNS address for this instance'
    Value: !GetAtt JenkinsInstance.PublicDnsName
  JenkinsPass:
    Description: Jenkins One Time Install Password 
    Value: !Sub "ssh ec2-user@${JenkinsInstance.PublicIp} sudo cat /var/lib/jenkins/secrets/initialAdminPassword"
  JenkinsKey:
    Description: Jenkins SSH Public Key
    Value: !Sub "ssh ec2-user@${JenkinsInstance.PublicIp} sudo cat /var/lib/jenkins/.ssh/id_rsa.pub"
  InstanceID:
    Description: 'The ID of the Jenkins instance that was launched'
    Value: !Ref JenkinsInstance


3.    Validate the Template (Optional):
Once the cloud formation template has been saved to a file on your local drive or remote instance, the template can be validated using the awscli.

aws cloudformation validate-template --template-body file://jenkins_cf_deployment.yaml


Launch Options:

The CloudFormation template above can be launched in 2 ways, via the CLI or the GUI. Both steps have been included below, but ONLY ONE of the methods needs to be performed. DO NOT LAUNCH USING BOTH METHODS to avoid duplicate stacks and/or launch errors.


Stack Deployment from the Console


From the CloudFormation console screen, click the Create Stack Button button to get started. If you don't have any existing stacks deployed, then you should have been directed to the CloudFormation dashboard, where you are presented with choice options where you can either create a new stack, or a new stackset. Click Create new stack from this screen. StackSets are a different topic and will not be covered in this tutorial. If you already have pre-existing stacks deployed, then you would have been brought to your main cloudformation stack list console. From this console click the Create Stack button from the top, next to the Actions button.


No Existing Stacks: Getting Started Launch Stack


Existing Stacks: Existing Stacks Launch Stack


1.    Launch Stack with Template Upload:
Once on the Select Template screen, click the second option Upload a template to Amazon S3 and click the Choose File button. In the selector box window, choose the CloudFormation template that you saved to your drive from the earlier step and then click the Next button.


Select CloudFormation Template


2.    Launch Stack with Template Editor (Optional Alternative):
If you don't want to save the CloudFormation template as a file, and upload it via S3, and would instead prefer to just copy and paste your template into the console to run it, then in the CloudFormation console window, you can also choose the Design template option. By selecting the Design Template, CloudFormation will open it's template editor, where you can click on the Template tab (1), where you can paste the template yaml or JSON syntax directly into the editor (2). Once complete, click the Create Stack button (3) in the editor to allow CloudFormation to upload and automatically launch the pasted template.


Select Design Template


CloudFormation Design Editor


3.    Define Stack Parameters:
In the Details window, Type a name for the stack, and then choose the appropriate values for the stack parameters and then click the Next button.

  • InstanceType - Instance family type, and size that you want to use for your Jenkins instance.
  • KeyName - The SSH Key pair that you want assigned to the Jenkins instance.
  • VpcId - The VPC that the Jenkins instance will be launched in.
  • SubnetId - The subnet(s) that the Jenkins instance will be launched in.
  • JenkinsPort - The port that Jenkins will be configured to listen no. This value defaults to the default Jenkins port of 8080.
  • SSHLocation - The source IP address or IP address range that will be configured in the security group for allowed ingress traffic to ports 22, 80 and 443.
  • InstanceTagName - The value that will be assigned to the tag "Name" key. This will effectively be what you want the instance to be named.


Specify Template Details


4.    Define Stack Options:
In the Options window, set up any key/value pairs, IAM roles or notifications that you want associated with the cluster, and then click the Next button.


CloudFormation Stack Options


5.    Review and Launch:
In the Review window, review your selected options, and once satisfied, click the I acknowledge that AWS CloudFormation might create IAM resources. check box, and click the Next button to launch the stack.


CloudFormation Parameter Review


Stack Deployment CLI


As an alternative to launching off CloudFormation stacks from the AWS console, if the desire or need to launch a stack from the CLI arises, then the following section may be used instead of the console method illustrated above.


Syntax:

aws cloudformation create-stack --stack-name {{STACK_NAME}} \
--template-body file://{{FILE_NAME}}.yaml \
--capabilities CAPABILITY_IAM \
--parameters \
ParameterKey=KeyName,ParameterValue={{KEYNAME}} \
ParameterKey=VpcId,ParameterValue={{VPCID}} \
ParameterKey=InstanceType,ParameterValue={{INSTANCE_TYPE}} \
ParameterKey=JenkinsPort,ParameterValue={{JENKINS_PORT}} \
ParameterKey=SSHLocation,ParameterValue={{SSH_LOCATION}} \
ParameterKey=InstanceTagName,ParameterValue={{INSTANCE_TAG_NAME}} \
ParameterKey=SubnetId,ParameterValue=\"{{SUBNETID_1_ID}},{{SUBNETID_2_ID}}\"


  • InstanceType - Instance family type, and size that you want to use for your Jenkins instance.
  • KeyName - The SSH Key pair that you want assigned to the Jenkins instance.
  • VpcId - The VPC that the Jenkins instance will be launched in.
  • SubnetId - The subnet(s) that the Jenkins instance will be launched in.
  • JenkinsPort - The port that Jenkins will be configured to listen no. This value defaults to the default Jenkins port of 8080.
  • SSHLocation - The source IP address or IP address range that will be configured in the security group for allowed ingress traffic to ports 22, 80 and 443.
  • InstanceTagName - The value that will be assigned to the tag "Name" key. This will effectively be what you want the instance to be named.


Example Request: (Replace KeyName, VpcId, SubnetId, JenkinsPort, SSHLocation, InstanceType and InstanceTagName Parameters With Your Values)

aws cloudformation create-stack --stack-name Jenkins \
--template-body file://jenkins_cf_deployment.yaml \
--capabilities CAPABILITY_IAM \
--parameters \
ParameterKey=KeyName,ParameterValue=My_AWS_Key \
ParameterKey=VpcId,ParameterValue=vpc-a12345bc \
ParameterKey=InstanceType,ParameterValue=t2.medium \
ParameterKey=JenkinsPort,ParameterValue=8080 \
ParameterKey=SSHLocation,ParameterValue=1.2.3.4/32 \
ParameterKey=InstanceTagName,ParameterValue=Jenkins \
ParameterKey=SubnetId,ParameterValue=\"subnet-12a3456b,subnet-23b4567c\"


Example Response:

{
    "StackId": "arn:aws:cloudformation:us-east-2:012345678910:stack/Jenkins/123a4567-8b9c-10d1-d112-13efa1bc4d1e"
}


Stack Verification


1.    Monitor the Launch:
Once the create button has been pushed, CloudFormation will begin to create the stack and all stack dependencies. You can watch the progress of the launch in the CloudFormation service console window.


CloudFormation Launch Template


2 .    Verify the Stack:
Once the stack has been successfully launched by showing the CREATE_COMPLETE status, test the deployment, by clicking on the Output tab and copying the either the PublicIP, or ServerAddress value from the outputs section of the CloudFormation launch window.


CloudFormation Stack Complete


3 .    Load Jenkins:
Once the address to Jenkins has been copied out of the CloudFormation Console Outputs section, paste the address into a browser and pressing Enter. Once pressed, your browser should load Jenkins correctly.


Jenkins Port

When pasting your Jenkins IP into your browser, don't forget to append the ${JenkinsPort} (default is 8080), to the end of the URL string. The proper address should be http://${ServerIP}:${JenkinsPort}


Gitlab Application Screen


Finalizing your Setup


Now that CloudFormation has successfully launched the Jenkins stack, we need to perform a few administrative actions on the instance in order to get Jenkins ready for usage.


1 .    Unlock Jenkins:
Once you see the Jenkins load screen, Jenkins will ask for its one time lock password. You can use the JenkinsPass URL found in the cloudformation stack outputs section, to quickly fire off a single SSH command to the new jenkins server that will return the one time password. Once you have that password, copy it into the Jenkins load screen, and click on the Continue button.


Jenkins Password Output URL

You can use the JenkinsPass Output URL to quickly fire off a command against your new Jenkins server to get the One Time Password needed to unlock your Jenkins Instance. The return value can just be copied into Jenkins to unlock the new instance


ssh ec2-user@{Instance-ServerIP} sudo cat /var/lib/jenkins/secrets/initialAdminPassword


One Time Password


Leeeerooooy Jenkins !!!!


2 .    Install Plugins:
Jenkins has thousands of plugins that you can use to perform various tasks that will further your CI/CD capabilities. When Jenkins is first installed, it needs a few of these plugins to set up its environment. After entering your unlock code, you will be presented with a screen that asks what plugins you would like to install initially. Choose the first option, Install suggested plugins. This will install the plugins that Jenkins needs, as well as a few optional plugins that most Jenkins users find beneficial. Choose this option to proceed through the installation. We can modify the list of installed plugins by removing what we don't need or adding new plugins that we do need easily, later on.


Choose Plugins


Install Plugins


Recommended Plugins:

After your installation is complete, you can go to the Manage Jenkins -> Manage Plugins section of the Jenkins console and install a wide variety of plugins to suit your needs. Here is a list of recommended plugins to get you started:


  • Green Balls - Turns success indicator from blue to green
  • Environment Injector - Allows the injection of variables into jobs
  • Version Number - Set the version number to a formated build number instead of just a build number
  • Copy Artifact - Allows you to copy artifacts produced in one build job, with other jobs
  • Build-Name-Setter - Allows you to set the build number from an upstream job to the current job
  • Checkstyle - Allows for code standard and lint checking
  • Static Analysis Collector - Analysis on coding standards from checkstyle report
  • Shelve Project - Archive a job without deleting it, but still removing it from dashboard view
  • Publish Over SSH - Automatically connect to a server via SSH to deploy artifacts and perform installations
  • Parameterized Trigger - Trigger downstream jobs, passing job variables from current job to downstream jobs
  • SCM Sync Configuration - Sync your Jenkins config with a github repository to keep your jenkins config and jobs versioned


3 .    Setup User:
Once Jenkins has completed installing the plugins, it will next, go to the user creation screen. This will allow you to register your first Jenkins user. Fill out the user details, and then click the Save and Finish button in the bottom right hand corner.


Create User


4 .    Finalize Setup:
Once the user has been created, Jenkins is finally ready for use. Click on the Start using Jenkins button to load the main Jenkins Dashboard.


Jenkins is Ready!


Jenkins Dashboard


SSH Key Management


1 .    Manage Credentials:
The last thing that we will want to do is to handle the SSH management component. On install using the cloudformation script above, Jenkins generated an SSH Key. We need to tell both Jenkins where that SSH key is, which will allow Jenkins to use that SSH Key when talking to external servers such as a Gitlab, Github, BitBucket server, etc..., and we also need to grab that SSH Key and add it as a deployment Key to our GIT SCM in order to allow Jenkins to pull code from it. In order to configure Jenkins to use the generated SSH Key, Click on Manage Jenkins from the left side dashboard menu, and click on the Configure Credentials options in the manage window.


Manage Jenkins


2 .    Navigate to Credentials Store: Next, in the credentials window, choose the Credentials link from the left side menu, this will display all available Jenkins credentials stores.


Jenkins Credentials


3 .    Choose the Credentials Store: Now that we can see all available Jenkins stores (there should only be 1 by default), click the Jenkins store to display all domains registered within that store.


Jenkins Store


4 .    Choose the Credentials Domain: Next, we should see all available Domains within the Jenkins stores (again, there should only be 1 by default), click the Global credentials domain. This will bring us to the section where we can add our ssh key credentials.


Jenkins Domain


5 .    Add SSH Credentials: Now we can finally add our SSH Keys. In the left side menu, click the link to Add Credentials, and in the Kind drop list, choose SSH Username with private key. Type jenkins as the username, and in the Private Key section, choose the option From the Jenkins master ~/.ssh. This will add the credentials for the jenkins user, using the key found in /var/lib/jenkins/.ssh/id_rsa as the SSH key to be used for that user. Once done, click on OK.


Jenkins Add SSH


Jenkins SSH Key Confirmation


Configuring Deployment Key


1 .    Grab SSH Key for SCM: Now that jenkins has been configured to use its SSH Key for the jenkins user, we need to copy that key and use our SCM's option to add that key as a Deployment Key. This will allow Jenkins to pull code from our repository in Gitlab, but not write back to that repository, ensuring that code does not get modified during the CI/CD process. In order to do this, first we must get the key from the jenkins server. This can be done by firing a single SSH command off to the jenkins server to retrieve the public key, or by logging into the jenkins server and manually typing out cat /var/lib/jenkins/.ssh/id_rsa.pub.


ssh user@jenkins.awsdocs.com sudo cat /var/lib/jenkins/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCm7NSYX9Oq9DyFrILzHMYkfEW7jwhnE27tvd5mAMBGjGt4fGmFJTnhh2Y2/sQpKSOxn4faGItefTCnZSgHup0UspGXjgCuqbrS0JPRXrOI8XWIw8rFWLDBTtkjvwmBdk05ni1lBAhmMaP5XpB3Q7AcwXru10Dygt2MBT5oatVHCwV43rUR57tb3PM00zV3tp1LeX+7LFxwj8d3mrdVn9IPcUKtFac0zKPqO92WKfBWg80Wy2NWJl1OL6Tlkk8VJ1yZP++5ud5Ji+pKOnAfSwP7VWXzW+X5CQvmJ+IHQvlBME8dqtNWh2pJURE+Rcw5lwz3IjSmxKw9h5KRvqdcgeI/ jenkins@jenkins


2 .    Gitlab Project: Once we have the public key, we need to add that key as a Deployment Key to our SCM, in this example, we will use Gitlab. First Log into Gitlab, click the project that we want to allow Jenkins to access, and in the project menu on the left side of the screen, choosing Settings --> Repository


Deploy Key Settings


3 .    Add Deploy Key: In the repository section, expand the section labeled Deploy Keys, Name the key, paste the public key into the Key input field, and click on Add Key.


Add Deployment Key


Deployment Key Confirmed


4 .    Build Your Jobs: Now that our SCM has been configured to allow access to the Jenkins deployment key, we are now ready to start building our Jenkins jobs !!


Jenkins CF Conclusion


At this point we have a fully functioning Jenkins Master, single server instance fully configured and ready for job creations. This setup is ideal for learning the Jenkins platform or testing different deployment scenarios, however for a full production configuration, Jenkins should be set up in an HA configuration consisting of the Jenkins front end being spread across more then one single AZ, A shared Jenkins directory configured on a network file system such as NFS, EFS, or GlusterFS, and Jenkins slave nodes deployed to execute various job builds/deployments.


Jenkins CF Additional Resources


Below you can find additional resources to supplement the information found in this tutorial.


Launch Jenkins Stack

Use the button below to automatically launch this cloudformation template and create your own Jenkins Single Servier instance Stack.

Launch Jenkins Stack


CloudFormation Launch

In order to use the button above you must already be logged into your AWS account. This link will launch the template the us-east-1 region. If you wish to use a different region, then copy the link and change the region=us-east-1# portion of the URL to the appropriate region.


Change Launch URL


Jenkins CloudFormation Template Download

Download the Jenkins CloudFormation Template here


Jenkins Manual Installation

In the event that you don't want to use CloudFormation in order to setup Jenkins, the following steps can be followed to install Jenkins on any Bare Metal (BM) or Virtual Machine (VM) based instance.


RHEL RHEL,   CentOS CentOS,   &   Amazon Linux Amazon Linux



1.    Install Required Packages:
Install the required packages via Yum

yum clean all
yum install -y wget java-1.8.0-openjdk java-1.8.0-openjdk-devel net-tools git


2.    Install the Jenkins Repository:

sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo


3.    Import the Jenkins PGP Signing Key:

sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key


4.    Ensure Required Directories Exist:

sudo mkdir -p /home/jenkins /var/lib/jenkins/.ssh /var/cache/jenkins/war /var/log/jenkins


5.    Install Jenkins:

sudo yum install -y jenkins


6.    Allow Jenkins to access shell:
In the event that you want to construct a job that will ssh to another server, interface directly with GIT, or to test host connections, we need to ensure that jenkins has access to a command shell.

usermod -s /bin/bash jenkins


7.    Set your SSH Config to turn off Strict Host Checking:
We want to set the SSH config to NOT perform StrictHostChecking, which can cause deployment jobs to fail, when Jenkins first tries to SSH into build slaves, or deployment targets.

sudo echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /var/lib/jenkins/.ssh/config


8.    Generate SSH Key Pair:

sudo ssh-keygen -t rsa -b 2048 -C jenkins@jenkins -N "" -f /var/lib/jenkins/.ssh/id_rsa
sudo cat /var/lib/jenkins/.ssh/id_rsa.pub > /var/lib/jenkins/.ssh/authorized_keys


9.    Set Directory Permissions:

sudo chown -R jenkins:jenkins /var/lib/jenkins /var/cache/jenkins /var/log/jenkins
sudo chmod 0700 /var/lib/jenkins/.ssh
sudo chmod 0600 /var/lib/jenkins/.ssh/*


10.    Firewall Configuration:
In the event that you are using Firewalld to further protect your Bare Metal/Instance, the following services/ports need to be open to allow ingress requests/egress responses:

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload


11.    Start Gitlab Required Services:

systemctl enable jenkins.service
systemctl start jenkins.service


Jenkins CF Site/Information References


http://www.yamllint.com/


Comments