| Jun 22, 2021

6 MIN READ

Written by Nagarajan P
Install Jenkins on AWS

Install Jenkins on AWS EC2 Instance using Terraform!

In this article, I will walk you through the steps on how we can easily leverage Terraform to provision an EC2 instance on AWS running with Redhat and install Jenkins using remote commands.

Terraform — An IaC tool

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. It can manage existing and popular service providers as well as custom in-house solutions. Configuration files describe to Terraform the components needed to run a single application or your entire datacentre. Terraform is revolutionising DevOps by changing how infrastructure is managed, making it fast and efficient to execute DevOps projects.

Environment

Terraform v0.15.5
AWS Account —AWS Free Tier is enough to test.
AWS CLI 
Key Pair — To access the EC2 instance.

Let’s Provision our EC2 Instance!

I have created a separate working directory for my Jenkins installation. To create my main.tf file for this demo, I am going to keep all the coding in a single file. I am not using modules or other terraform futures to keep it simple.
Working Directory : D:\terraform\jenkins

Open main.tf in your favorite text editor, here I am using VS Code:

provider "aws" {
  profile = "terraform"
  region  = "us-east-1"
}

In Provider block, I am defining which provider to use and associated aws profile and the region. I have configured my local aws profile, which is “terraform” and I will keep my resources on the us-east-1 region.

To Configure AWS-cli, you can refer to the below link:
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html

Next let’s configure our Security Group…


# Security Group
variable "ingressrules" {
  type    = list(number)
  default = [8080, 22]
}
resource "aws_security_group" "web_traffic" {
  name        "Allow web traffic"
  description = "inbound ports for ssh and standard http and everything outbound"
  dynamic "ingress" {iterator = port
    for_each = var.ingressrules
    content {
      from_port   = port.value
      to_port     = port.value
      protocol    = "TCP"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     0
    protocol    "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    "Terraform" "true"
  }
}

In the Security Group block, we will configure to make our EC2 instance publicly accessible.
For the ingress rule list of ports, we are using (8080, 22). Port 22 for ssh connections and port 8080 to access Jenkins URL publicly. We will configure the egress rule to allow traffic for everything.

Next configure our data block…


# Data Block
data "aws_ami" "redhat" {
  most_recent = true
  filter {
    name   = "name"
    values = ["RHEL-7.5_HVM_GA*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["309956199498"]
}

The data block uses aws_ami data source, passes a few filter options as specified, and returns an object; this is useful to pull the latest AMI and keeps launching configuration up to date. Here we are pulling latest AMI image of Redhat 7.5.

Resource Block…!


# resource block
resource "aws_instance" "jenkins" {
  ami             = data.aws_ami.redhat.id
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.web_traffic.name]
  key_name        = "ashnikdev_key"

In the resource block, we have defined terraform to provision ec2 aws_instance, and refer to it as Jenkins inside this resource block specifying ami  by calling our data block ami image and instance_type  t2.micro and attaching the security group to aws_instance.

Also, we need to add the key pair to communicate with the server using ssh. Here I am adding my existing key pair “ key_name = “ashnikdev_key

Reference to create key pair :-
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#having-ec2-create-your-key-pair

Next, we are going to add provisioner and connection block within our resource block.

Execute Remote Commands

The remote-exec provisioner invokes a script on a remote resource after it is created. This can be used to run a configuration management tool, bootstrap into a cluster, etc. To invoke a local process, see the local-exec provisioner instead. The remote-exec provisioner supports both ssh and winrm type connections.

In the argument inline parameter, we can list all our commands strings that are executed in an order. We will install Java, Jenkins.


 provisioner "remote-exec"  {
    inline  = [
      "sudo yum install -y jenkins java-11-openjdk-devel",
      "sudo yum -y install wget",
      "sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo",
      "sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key",
      "sudo yum upgrade -y",
      "sudo yum install jenkins -y",
      "sudo systemctl start jenkins",
      ]
   }
 connection {
    type         "ssh"
    host         = self.public_ip
    user         "ec2-user"
    private_key  = file("color:#CE9178">".\ashnikdev_key.pem" )
   }

  tags  = {
    "Name"      = "Jenkins"
      }
 }

We specify the connection type, host, user, and path to our private key inside the connection block. That’s how Terraform will connect to the instance after it has been provisioned and run our commands.

Save our main.tf file and run init and validate the code.

Terraform init

The terraform init command is used to initialize a working directory containing the Terraform configuration files. This is the first command that should run after writing a new Terraform configuration or cloning an existing one. It is safe to run this command multiple times.

terraform init

Terraform validate

The terraform validate command validates the configuration files in a directory, referring only to the configuration and not accessing remote services such as remote state, provider APIs, and others.

terraform validate

Terraform plan

The terraform plan command creates an execution plan. By default, creating a plan consists of:

  • Reading the current state of any already-existing remote objects to make sure that the Terraform state is up-to-date.
  • Comparing the current configuration to the prior state and noting any differences.
  • Proposing a set of change actions should, if applied, make the remote objects match the configuration.

The plan command alone will not carry out the proposed changes, and so you can use this command to check whether the proposed changes match what you expected before you apply the changes.

terraform plan

terraform plan 2

Terraform apply

The terraform apply command executes the actions proposed in a Terraform plan:

By running terraform apply it will ask for the confirmation to perform action by entering yes :

terraform apply

terraform apply 2

terraform apply 3

Now, let’s go to our AWS console and verify the new EC2 instance.

AWS console

You should see the attached security group on the EC2 instance inside the AWS Console.

ec2 security group

We can connect to our EC2 instance over SSH via public DNS name. On the Networking tab, you can find the public DNS name address. The username is “ec2-user” by default.

SSH via public DNS

So, since all looks good now, we will access Jenkins via web browser using the public DNS name/ipaddress:8080.
Access the Jenkins Web portal
Access the URL : http://:8080

unlock jenkins

Admin password is created and stored in the log file “/var/lib/jenkins/secrets/initialAdminPassword “. Run the below command to get the password.

password setting

Copy the password and paste it in above window on “Administrator password” and click on Continue…

customize jenkins

jenkins getting started

As we can see required plugin installation is in progress for Jenkins. Once it is done with plugin installation, it will ask to create Admin User:

jenkins create user

Click on Save and Continue…

jenkins setup copleted

jenkins homepage

Summary

Using Terraform, we have created EC2 Instance on aws and using remote command future in no time. We have executed list of commands on the created resource to install Jenkins:

In this article, we touched upon the basics of Terraform’s capabilities. It has various features for building, changing, and versioning infrastructure in secure way. Terraform manages existing and popular service providers along with custom in-house solutions.

Refer to checking out the Terraform documentation to deep dive into Terraform offerings.


Go to Top