To deploy a Jenkins cluster on AWS using Terraform and Packer, you will need to follow several steps. First, you will use Packer to create a custom Amazon Machine Image (AMI) with Jenkins pre-installed. Then, you will use Terraform to provision the necessary AWS resources, such as EC2 instances and security groups, based on the custom AMI.

Here's a step-by-step guide on how to accomplish this:

Install Packer: Download and install Packer from the official website (https://www.packer.io/downloads) and ensure it's available in your system's PATH.

Create a Packer configuration file: Create a new file named jenkins-ami.json and paste the following contents into it:

{
  "variables": {
    "aws_access_key": "",
    "aws_secret_key": "",
    "aws_region": "us-west-2",
    "instance_type": "t2.micro",
    "source_ami": "ami-0c94855ba95c71c99",
    "ssh_username": "ubuntu",
    "jenkins_version": "2.289.2"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "{{user `aws_region`}}",
      "source_ami": "{{user `source_ami`}}",
      "instance_type": "{{user `instance_type`}}",
      "ssh_username": "{{user `ssh_username`}}",
      "ami_name": "Jenkins-{{user `jenkins_version`}}-{{isotime | clean_resource_name}}",
      "ami_description": "Jenkins {{user `jenkins_version`}}",
      "ssh_timeout": "30m",
      "tags": {
        "Name": "Jenkins AMI"
      },
      "provisioners": [
        {
          "type": "shell",
          "script": "install-jenkins.sh"
        }
      ]
    }
  ]
}

In this configuration file, we define variables for AWS access key, secret key, region, instance type, source AMI, SSH username, and Jenkins version. Adjust these values according to your needs. The install-jenkins.sh script will be responsible for installing Jenkins on the EC2 instance during the image creation process.

Create a Jenkins installation script: Create a new file called install _ jenkins.sh in the same directory as the Packer configuration file. This script will install Jenkins on the EC2 instance created by Packer. Add the following content to the script:
#!/bin/bash

# Update system packages
sudo apt-get update

# Install Jenkins dependencies
sudo apt-get install -y openjdk-11-jdk

# Install Jenkins
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install -y jenkins

# Start Jenkins service
sudo systemctl start jenkins

This script updates the system packages, installs OpenJDK 11, adds the Jenkins repository, installs Jenkins, and starts the Jenkins service.

Build the custom Jenkins AMI: Open a terminal or command prompt, navigate to the directory where you saved the jenkins-ami.json file, and run the following command:
packer build jenkins-ami.json

Packer will start the build process and provision an EC2 instance based on the provided configuration. It will install Jenkins and create a new custom AMI.

Install Terraform: Download and install Terraform from the official website (https://www.terraform.io/downloads.html) and ensure it's available in your system's PATH.

Create a Terraform configuration file: Create a new file named main.tf and paste the following contents into it:
provider "aws" {
  access_key = ""
  secret_access_key = ""
  region = "us-west-2"
}

variable "ami_id" {
  description = "The ID of the custom Jenkins AMI created with Packer"
  type = string
  default = ""
}

variable "instance_type" {
  description = "The EC2 instance type for the Jenkins cluster"
  type = string
  default = "t2.micro"
}

resource "aws_security_group" "jenkins_sg" {
  name        = "jenkins_sg"
  description = "Jenkins security group"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "jenkins_instance" {
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = "your_key_pair_name"
  security_group_ids = [aws_security_group.jenkins_sg.id]

  tags = {
    Name = "Jenkins Instance"
  }
}

In this Terraform configuration file, you'll need to set your AWS access key and secret access key in the provider block, as well as specify the custom AMI ID created by Packer in the ami_id variable.

Make sure to replace "your_key_pair_name" with the name of your AWS key pair that you want to use to access the Jenkins instances.

Initialize and apply Terraform: Open a terminal or command prompt, navigate to the directory where you saved the main.tf file, and run the following commands:
terraform init
terraform apply

Terraform will initialize and download the necessary provider plugins and then provision the EC2 instance(s) based on the specified configuration.

Access the Jenkins cluster: Once the Terraform deployment is complete, you can access the Jenkins cluster by obtaining the public IP address of the provisioned EC2 instance. You can find this information in the Terraform output or the AWS Management Console. Simply open a web browser and navigate to http://:8080 to access the Jenkins web interface.

That's it! You have successfully deployed a Jenkins cluster on AWS using Terraform and Packer. Remember to destroy the infrastructure when you no longer need it by running terraform destroy.