Three ways of launching Amazon Linux 2 and Ubuntu Ec2 instances and install Docker and Jenkins on them
Three Methods for Launching Amazon Linux 2 and Ubuntu EC2 Instances with Docker and Jenkins installed
๐ Overview:
This project aims to demonstrate three different approaches to launching Amazon Linux 2 and Ubuntu EC2 instances on AWS and installing Docker and Jenkins on them. The three methods include using AWS CloudFormation, Terraform, and direct Bash scripting with user data.
๐ง Problem Statement
This project demonstrates three distinct methods to deploy Amazon Linux 2 and Ubuntu EC2 instances with Docker and Jenkins installed. Each approach showcases different infrastructure-as-code and automation techniques commonly used in DevOps practices.
๐ฝ Techonology Stack
The architecture consists of the following three tiers:
VPC: AWS VPC
EC2 Instances: AWS EC2
Containerization: Docker
Cl/CD: Jenkins
Scripting: Bashscript
๐ Architecture Diagram
+-----------------------------+
| AWS Region |
| |
| +-------------------------+ |
| | VPC | |
| | | |
| | +-------------------+ | |
| | | Availability Zone | | |
| | | A | | |
| | | | | |
| | | +-------------+ | | |
| | | | Subnet A | | | |
| | | | | | | |
| | | | +--------+ | | | |
| | | | | EC2 | | | | |
| | | | | Amazon | | | | |
| | | | | Linux 2 | | | | |
| | | | +--------+ | | | |
| | | +-------------+ | | |
| | +-------------------+ | |
| | | |
| | +-------------------+ | |
| | | Availability Zone | | |
| | | B | | |
| | | | | |
| | | +-------------+ | | |
| | | | Subnet B | | | |
| | | | | | | |
| | | | +--------+ | | | |
| | | | | EC2 | | | | |
| | | | | Ubuntu | | | | |
| | | | +--------+ | | | |
| | | +-------------+ | | |
| | +-------------------+ | |
| | | |
| +-------------------------+ |
| |
+-----------------------------+
๐ Project Requirements
Before you get started, make sure you have the following prerequisites in place:
AWS account with an IAM user credentials configured in.
An Infrastructure (VPC, Subnets, route table, Security groups, NACL...) ready to be use for the lab.
An Amazon Linux 2 and Ubuntu EC2 instance running for the part for the bash scripting
To install Jenkins on a server you must have minimum hardware requirements:
256 MB of RAM 1 GB of drive space (although 10 GB is a recommended minimum if running Jenkins as a Docker container) Recommended hardware configuration for a small team: 4 GB+ of RAM 50 GB+ of drive space
To install Jenkins on a server you must have minimum hardware requirements:
OS: 64-bit version of Ubuntu RAM: At least 2 GB, but Docker recommends more for larger deployments or resource-intensive applications Disk space: 100 GB of free space CPU: Sufficient amount, depending on the applications Kernel: 64-bit kernel with support for virtualization Virtualization: Support for KVM virtualization technology QEMU: Version 5.2 or later Init system: systemd init system Desktop environment: Gnome, KDE, or MATE Firewall: Firewall rulesets created with iptables or iptables6, and added to the DOCKER-USER chai.
๐ Table of Contents
I - AWS CloudFormation Template
Step 1: Description
Step 2: Instructions of deployment
Step 3: Results
Step 4: Clean up
II - Terraform Script
Step 1: Description
Step 2: Instructions of deployment
Step 3: Results
Step 4: Clean Up
III - Bash Script
Step 1: Description
Step 2: Instructions of deployment
Step 3: Results
Step 4: Clean Up
โจAWS CLOUDFORMATION TEMPLATE
Step 1: DESCRIPTION
AWS CloudFormation allows you to define your infrastructure as code. We will create a CloudFormation template that launches Amazon Linux 2 and Ubuntu EC2 instances and uses user data scripts to install Docker and Jenkins.
Step 2: INSTRUCTIONS OF DEPLOYMENT
Create a CloudFormation template
Use your VS Code to create both files "Linux_Docker_jenkins.yml" and "ubntu-docker-jenkins.yml"
Define the resources for Amazon Linux 2 and Ubuntu EC2 instances. Here Use the
UserData
property to specify a script that installs Docker and Jenkins.Linux-Docker-Jenkins.yml
AWSTemplateFormatVersion: '2010-09-09' Metadata: License: Apache-2.0 Authors: Description: Joseph Mbatchou Description: " This template launches an amazon Linux 2 ec2 instance in a custom VPC, with an IAM assume role attached to it for SSM, then with the user data it will install Docker and Jenkins" Parameters: InstanceType: Description: EC2 instance type. Type: String AllowedValues: - t2.nano - t2.micro - t2.small - t2.medium - t2.large KeyName: Description: Name of an existing EC2 key pair for SSH access to the EC2 instance. Type: AWS::EC2::KeyPair::KeyName SSHLocation: Description: The IP address range that can be used to SSH to the EC2 instances Type: String MinLength: '9' MaxLength: '18' AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" # IP Address ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. ImageId: Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 VpcId: Type: AWS::EC2::VPC::Id Description: Select an existing VPC SubnetId: Type: AWS::EC2::Subnet::Id Description: Select an existing subnet within the selected VPC Resources: IamRole: Type: 'AWS::IAM::Role' Properties: RoleName: Ec2RoleForSSM Description: EC2 IAM role for SSM access AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' Ec2InstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: InstanceProfileName: Ec2RoleForSSM Path: / Roles: - Ref: IamRole WebServer: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref Ec2InstanceProfile ImageId: !Ref ImageId InstanceType: !Ref InstanceType KeyName: !Ref KeyName NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" GroupSet: - !Ref WebServerSecurityGroup SubnetId: !Ref SubnetId UserData: Fn::Base64: !Sub | #!/bin/bash sudo yum update -y sudo yum install python3-pip sudo amazon-linux-extras install docker sudo yum install -y docker sudo service docker start sudo systemctl enable docker sudo systemctl restart docker sudo usermod -aG docker ec2-user sudo yum update -y sudo 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-2023.key sudo yum upgrade sudo yum install java-17-amazon-corretto -y sudo yum install jenkins -y sudo systemctl start jenkins sudo systemctl enable jenkins sudo systemctl restart jenkins sudo usermod -aG jenkins ec2-user sudo reboot Tags: - Key: Name Value: Linux-Docker-Jenkins-Server WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 'Enable HTTP access via port 80 SSH access' VpcId: !Ref VpcId SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: 8080 IpProtocol: tcp ToPort: 8080 - CidrIp: !Ref SSHLocation FromPort: 22 IpProtocol: tcp ToPort: 22 - CidrIp: 0.0.0.0/0 FromPort: 80 IpProtocol: tcp ToPort: 80 Outputs: InstanceId: Description: ID of the EC2 instance Value: !Ref WebServer PublicDNS: Description: Public DNS name of the EC2 instance Value: !GetAtt WebServer.PublicDnsName PublicIP: Description: Public IP address of the EC2 instance Value: !GetAtt WebServer.PublicIp
ubuntu-docker-jenkins.yml
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
License: Apache-2.0
Authors:
Description: Joseph Mbatchou # The writer of this template
Description: " This template launches an ubuntu ec2 instance in a custom VPC, with an IAM assume role attached to it
for SSM, then with the user data it will install Docker and Jenkins"
Parameters:
InstanceType:
Description: EC2 instance type.
Type: String
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
KeyName:
Description: Name of an existing EC2 key pair for SSH access to the EC2 instance.
Type: AWS::EC2::KeyPair::KeyName
SSHLocation:
Description: Place to enter your IP address. The IP address range that can be used to SSH to the EC2 instances
Type: String
MinLength: '9'
MaxLength: '18'
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.
ImageId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: '/aws/service/canonical/ubuntu/server/jammy/stable/current/amd64/hvm/ebs-gp2/ami-id'
VpcId:
Type: AWS::EC2::VPC::Id
Description: Select an existing VPC
SubnetIds:
Type: AWS::EC2::Subnet::Id
Description: Select at least one subnet within the selected VPC
Resources:
IamRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub "${AWS::StackName}-Ec2RoleForSSM"
Description: EC2 IAM role for SSM access
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
Ec2InstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
InstanceProfileName: !Sub "${AWS::StackName}-Ec2RoleForSSM"
Path: /
Roles:
- !Ref IamRole
WebServer:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref Ec2InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
GroupSet:
- !Ref WebServerSecurityGroup
SubnetId: !Ref SubnetIds
UserData:
Fn::Base64: !Sub |
#!/bin/bash
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker.service
sudo systemctl enable docker.service
sudo usermod -aG docker ubuntu
sudo apt-get update -y
sudo apt-get install openjdk-17-jdk -y
sudo curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
sudo echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
sudo systemctl start jenkins
sudo systemctl enable jenkins
sudo usermod -aG jenkins ubuntu
sudo ufw allow 8080
sudo ufw allow OpenSSH
sudo ufw enable
Tags:
- Key: Name
Value: Ubuntu-Docker-jenkins-server
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'Enable HTTP access via port 80 SSH access'
VpcId: !Ref VpcId
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort: 8080
IpProtocol: tcp
ToPort: 8080
- CidrIp: !Ref SSHLocation
FromPort: 22
IpProtocol: tcp
ToPort: 22
- CidrIp: 0.0.0.0/0
FromPort: 80
IpProtocol: tcp
ToPort: 80
Outputs:
InstanceId:
Description: ID of the EC2 instance
Value: !Ref WebServer
PublicDNS:
Description: Public DNS name of the EC2 instance
Value: !GetAtt WebServer.PublicDnsName
PublicIP:
Description: Public IP address of the EC2 instance
Value: !GetAtt WebServer.PublicIp
- Deploy the stack using the AWS Management Console.
On the console you must open CloudFormation option then hit on "Create Stack"
Linux-stack
ubuntu stack
After launching both stacks you will get the complete stage
Step 3: RESULTS
As result you will get first both instances running in the console
After connecting to each servers via Session manager or SSH you can check status and version of each application installed.
Linux instance
ubuntu instance
Step 4: CLEAN UP
You can clean up all resources created by just delete them via the CloudFormation stack . You just need to go back in the CloudFormation window select the stack and hit delete button till you get to the message saying "Delete Complete" .
โจTERRAFORM SCRIPT
Step 1: DESCRIPTION
Terraform is an open-source infrastructure as code software tool. We will create Terraform scripts to launch Amazon Linux 2 and Ubuntu EC2 instances and use user data to install Docker and Jenkins.
Step 2: INSTRUCTIONS OF DEPLOYMENT
Create a Terraform script
Here you will have to create both (Linux-main.tf and ubuntu-main.tf) files and you will put each of them in a folder.
Define the resources for Amazon Linux 2 and Ubuntu EC2 instances. Use the
UserData
property to specify a script that installs Docker and Jenkins.Here are the contains of each files
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } } variable "aws_region" { type = string description = "region where to launch" default = "us-west-2" } variable "instance_type" { type = string description = "instance type of the instance" default = "ansible-key" } variable "key_name" { type = string description = "rkey name of the instance" default = "t2.micro" } #Configure the AWS Provider provider "aws" { region = var.aws_region }# Data source for latest Amazon Linux 2 AMI data "aws_ami" "amazon_linux_2" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } data "aws_vpc" "custom_vpc" { filter { name = "tag:Name" values = ["c@licost-vpc"] # Replace with your VPC's name tag } } data "aws_subnet" "custom_subnet" { vpc_id = data.aws_vpc.custom_vpc.id filter { name = "tag:Name" values = ["c@licost-subnet-public2-us-west-2b"] # Replace with your subnet's name tag } } # IAM Role resource "aws_iam_role" "ec2_ssm_role" { name = "Ec2RoleForSSM" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) } resource "aws_iam_role_policy_attachment" "ssm_policy_attachment" { role = aws_iam_role.ec2_ssm_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" } resource "aws_iam_instance_profile" "ec2_profile" { name = "Ec2RoleForSSM" role = aws_iam_role.ec2_ssm_role.name } # Security Group resource "aws_security_group" "web_server_sg" { name = "WebServerSecurityGroup" description = "Enable HTTP access via port 80 SSH access" vpc_id = data.aws_vpc.custom_vpc.id ingress { from_port = 8080 to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 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"] } } # EC2 Instance resource "aws_instance" "web_server" { ami = data.aws_ami.amazon_linux_2.id instance_type = var.instance_type key_name = var.key_name subnet_id = data.aws_subnet.custom_subnet.id vpc_security_group_ids = [aws_security_group.web_server_sg.id] iam_instance_profile = aws_iam_instance_profile.ec2_profile.name associate_public_ip_address = "true" user_data = base64encode(<<-EOF #!/bin/bash sudo yum update -y sudo yum install python3-pip sudo amazon-linux-extras install docker sudo yum install -y docker sudo service docker start sudo systemctl enable docker sudo systemctl restart docker sudo usermod -aG docker ec2-user sudo yum update -y sudo 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-2023.key sudo yum upgrade sudo yum install java-17-amazon-corretto -y sudo yum install jenkins -y sudo systemctl start jenkins sudo systemctl enable jenkins sudo systemctl restart jenkins sudo usermod -aG jenkins ec2-user sudo reboot EOF ) tags = { Name = "Linux-Docker-Jenkins-server" } } output "instance_id" { description = "ID of the EC2 instance" value = aws_instance.web_server.id } output "public_dns" { description = "Public DNS name of the EC2 instance" value = aws_instance.web_server.public_dns } output "public_ip" { description = "Public IP address of the EC2 instance" value = aws_instance.web_server.public_ip }
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } } #Configure the AWS Provider provider "aws" { region = var.aws_region } variable "aws_region" { type = string description = "region where to launch" default = "us-west-2" } variable "instance_type" { type = string description = "instance type of the instance" default = "ansible-key" } variable "key_name" { type = string description = "rkey name of the instance" default = "t2.micro" } #Data source for latest Amazon Linux 2 AMI data "aws_ami" "ubuntu" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] } } data "aws_vpc" "custom_vpc" { filter { name = "tag:Name" values = ["c@licost-vpc"] # Replace with your VPC's name tag } } data "aws_subnet" "custom_subnet" { vpc_id = data.aws_vpc.custom_vpc.id filter { name = "tag:Name" values = ["c@licost-subnet-public2-us-west-2b"] # Replace with your subnet's name tag } } # IAM Role resource "aws_iam_role" "ec2_ssm_role" { name = "Ec2RoleForSSM" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) } resource "aws_iam_role_policy_attachment" "ssm_policy_attachment" { role = aws_iam_role.ec2_ssm_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" } resource "aws_iam_instance_profile" "ec2_profile" { name = "Ec2RoleForSSM" role = aws_iam_role.ec2_ssm_role.name } # Security Group resource "aws_security_group" "web_server_sg" { name = "WebServerSecurityGroup" description = "Enable HTTP access via port 80 SSH access" vpc_id = data.aws_vpc.custom_vpc.id ingress { from_port = 8080 to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 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"] } } # EC2 Instance resource "aws_instance" "web_server" { ami = data.aws_ami.ubuntu.id instance_type = var.instance_type key_name = var.key_name subnet_id = data.aws_subnet.custom_subnet.id vpc_security_group_ids = [aws_security_group.web_server_sg.id] iam_instance_profile = aws_iam_instance_profile.ec2_profile.name associate_public_ip_address = "true" user_data = base64encode(<<-EOF #!/bin/bash sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl start docker.service sudo systemctl enable docker.service sudo usermod -aG docker ubuntu sudo apt-get update -y sudo apt-get install openjdk-17-jdk -y sudo curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null sudo echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt-get update sudo apt-get install jenkins -y sudo systemctl start jenkins sudo systemctl enable jenkins sudo usermod -aG jenkins ubuntu sudo ufw allow 8080 sudo ufw allow OpenSSH sudo ufw enable EOF ) tags = { Name = "Ubuntu-Docker-jenkins-server" } } output "instance_id" { description = "ID of the EC2 instance" value = aws_instance.web_server.id } output "public_dns" { description = "Public DNS name of the EC2 instance" value = aws_instance.web_server.public_dns } output "public_ip" { description = "Public IP address of the EC2 instance" value = aws_instance.web_server.public_ip }
Step 3: RESULTS
After putting each files in a folder we have to go through the process of running terraform
- Initialise the folder
terraform init
- Check the correct syntax of the file
terraform fmt
- Valid the status of the file
terraform validate
- Plan to see which resources will be create
terraform plan
- Create the resources with command
terraform apply
After all this we will get to the result images
Linux instance
In the console you have
Ubutntu
In the console
After SSM connect to each instances we have the result of different version
For Linux instance
For Ubuntu instance
Step 4: CLEAN UP
Use the command destroy to delete all the infrastructures
terraform destroy
For the Linux instance
For the ubuntu instance
โจBASH SCRIPT
Step 1: DESCRIPTION
A Bash script can be used to manually launch EC2 instances and configure them using the AWS CLI. We will write a Bash script that launches Amazon Linux 2 and Ubuntu EC2 instances and uses user data to install Docker and Jenkins.
Step 2: INSTRUCTIONS OF DEPLOYMENT
Create a Bash script (
launch-instances.sh
). This with contains the process of creating both Amazon linux and Ubuntu EC2 instances. The script included default value you can customize to your values.#!/bin/bash # Variables REGION="us-west-2" INSTANCE_TYPE="t2.micro" KEY_NAME="ansible-key" SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=DevOps-SG --query 'SecurityGroups[0].GroupId' --output text --region $REGION) # Subnet IDs - replace these with your actual subnet IDs SUBNET_ID_1="subnet-0afe31980b7b724ac" SUBNET_ID_2="subnet-099fca76d17b2fd4f" # Launch Amazon Linux 2 Instance aws ec2 run-instances \ --image-id ami-0648742c7600c103f \ --count 1 \ --instance-type $INSTANCE_TYPE \ --associate-public-ip-address \ --key-name $KEY_NAME \ --security-group-ids $SECURITY_GROUP_ID \ --subnet-id $SUBNET_ID_1 \ --region $REGION \ --user-data file:///users/josephmbatchou/amazon-linux-user-data.sh \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=AmazonLinux2-Instance},{Key=OS,Value=AmazonLinux2}]' # Launch Ubuntu Instance aws ec2 run-instances \ --image-id ami-0075013580f6322a1 \ --count 1 \ --instance-type $INSTANCE_TYPE \ --key-name $KEY_NAME \ --associate-public-ip-address \ --security-group-ids $SECURITY_GROUP_ID \ --subnet-id $SUBNET_ID_2 \ --region $REGION \ --user-data file:///users/josephmbatchou/ubuntu-user-data.sh \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=Ubuntu-Instance},{Key=OS,Value=Ubuntu}]'
Create both Bash script user data scripts to install Docker and Jenkins on the instances. Files are "amazon-linux-user-data.sh" and "ubuntu-user-data.sh"
#!/bin/bash
# install Jenkins
sudo yum update -y
sudo 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-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto -y
sudo yum install jenkins -y
sudo systemctl start jenkins
sudo systemctl enable jenkins
sudo systemctl restart jenkins
sudo usermod -aG jenkins ec2-user
#install Docker
sudo yum update -y
sudo yum install python3-pip
sudo amazon-linux-extras install docker
sudo yum install -y docker
sudo service docker start
sudo systemctl enable docker
sudo systemctl restart docker
sudo usermod -aG docker ec2-user
#!/bin/bash
#Install Jenkins
sudo apt-get update -y
sudo apt-get install openjdk-17-jdk -y
sudo curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
sudo echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
sudo systemctl start jenkins
sudo systemctl enable jenkins
sudo usermod -aG jenkins ubuntu
sudo ufw allow 8080
sudo ufw allow OpenSSH
sudo ufw enabley
#install Docker
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker.service
sudo systemctl enable docker.service
sudo usermod -aG docker ubuntu
Use the AWS CLI to launch Amazon Linux 2 and Ubuntu EC2 instances:
In order to run the script to provision the infrastructure by using CLI you must be in the prompt where your AWS CLI is configure and in the default region. Our Default region here is "us-west-2" You can verify this by using command
aws configure
Once you are set up you will have to make each script to be executable by changing modification command.
chmod +x launch-instances.sh
chmod +x amazon-linux-user-data.sh
chmod +x ubuntu-user-data.sh
As the both user data script are incorporated in the instance script you will only have to run the launch instance script with the command
./launch-instance.sh
The process of launching resources will follow and you will get results succeeded.
Linux instance
Ubuntu instance
step 3: RESULTS
You can go to the console and see that two instances were created and by connecting to them via SSH you will check for tools installed.
As you will ssh to each instances you will now check for each applications version to confirm the installation.
Linux instance
Ubuntu instance
Step 4: CLEAN UP
To delete both instances you can only check for each instances Id and use command terminate-instance to destroy them.
aws ec2 terminate-instances --instance-ids <instance-id>
By using the command with the right instances id you will terminated the both instances.
๐ Conclusion
This project showcases three different approaches to launching and configuring EC2 instances with Docker and Jenkins. Each method has its advantages and can be chosen based on specific requirements and preferences. The use of infrastructure as code tools like CloudFormation and Terraform ensures reproducibility and ease of management, while Bash scripting provides flexibility and simplicity.
๐ค Contributing
Your perspective is valuable! Whether you see potential for improvement or appreciate what's already here, your contributions are welcomed and appreciated. Thank you for considering joining us in making this project even better. Feel free to follow me for updates on this project and others, and to explore opportunities for collaboration. Together, we can create something amazing!
๐ License
This project is licensed under the Joebaho Cloud License