• Gavin In The Cloud
  • Posts
  • Deploying a Jenkins Server on Google Compute Engine (GCE) Using Terraform and GitHub Actions

Deploying a Jenkins Server on Google Compute Engine (GCE) Using Terraform and GitHub Actions

Efficient Cloud Engineering with Infrastructure as Code and CI/CD Automation

Deploying a Jenkins Server on Google Compute Engine (GCE) Using Terraform and GitHub Actions

Introduction:

As a cloud engineer proficient in implementing solutions on various cloud platforms, including GCE, you understand the importance of infrastructure automation. In this blog post, we will guide you through the process of deploying a Jenkins server on Google Compute Engine (GCE) using Terraform and automating the deployment process with GitHub Actions. By following this approach, you can efficiently provision and manage Jenkins servers, ensuring consistency and reducing manual configuration efforts.

Prerequisites:

Before diving into the technical details, make sure you have the following prerequisites in place:

  1. An active Google Cloud Platform (GCP) account with appropriate permissions to create GCE instances.

  2. A GitHub account with a repository set up to manage your Terraform code.

Repository Structure:

To maintain a structured project, follow a specific directory structure within your GitHub repository: GitHub Repository

You can clone my public repository for reference: GitHub Repository

Terraform Configuration:

Now, let's explore the key Terraform configurations for deploying the Jenkins server on GCE:

  • /src: This directory contains the main Terraform configuration files and the startup script for the Jenkins server.

main.tf: This file defines the infrastructure you want to create using Terraform. In this case, it specifies the configuration for the GCE instance where Jenkins will be deployed and the firewall rules to allow necessary ports.

resource "google_compute_instance" "jenkins_server" {
  name         = "jenkins-server"
  machine_type = "e2-medium"

  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-2004-lts"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Optional. External IP address configuration.
    }
  }

  metadata_startup_script = file("startup-script.sh")
  tags                    = ["deploy-jenkins", "http-server", "jenkins-server-firewall"]
}

resource "google_compute_firewall" "jenkins_server_firewall" {
  name    = "jenkins-server-firewall"
  network = "default"
  allow {
    protocol = "tcp"
    ports    = ["8000-9000", "22", "3389"]
  }
  source_ranges = ["0.0.0.0/0"]
  target_tags = ["deploy-jenkins"]
}

output "instance_external_ip" {
  value = google_compute_instance.jenkins_server.network_interface[0].access_config[0].nat_ip
}

provider.tf: The provider.tf configures the Terraform provider for Google Cloud, specifying the required provider version and setting project, region, and zone parameters to define the target Google Cloud environment for resource provisioning.

 terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.58.0"
    }
  }
backend "gcs" {
    bucket  = "my-jenkins-server-backend"
    prefix  = "terraform-jenkins-backend"
  }
}

provider "google" {
  project     = "your-project-id"
  region      = "us-central1"
  zone        = "us-central1-c"
}

startup-script.sh: The startup-script.sh is a Bash script used during the provisioning of the Jenkins server on Google Compute Engine. It updates the package repositories, installs OpenJDK 17 (Java Runtime Environment), and then installs Jenkins. After installation, it enables and starts the Jenkins daemon, ensuring that Jenkins is up and running on the GCE instance.

#!/bin/bash -x
# Startup script to install Java 
sudo apt update
sudo apt install -y openjdk-17-jre
# Verify Java installation
java -version
# Startup script to install Jenkins
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
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 -y jenkins
# Startup script to enable & start Jenkins daemon
sudo systemctl enable jenkins
sudo systemctl start jenkins
sudo systemctl status jenkins
echo "Jenkins installation completed"

.github/workflows/terraform.yml: The .github/workflows/terraform.yml file defines a GitHub Actions workflow for Terraform automation. It specifies that the workflow should trigger on pushes to the main branch. The workflow runs Terraform commands like init, plan, apply, and destroy in a defined sequence, utilizing the Terraform version 1.0.1 without a Terraform wrapper.

name: "Deploy Jenkins Server"

on:
  push:
    branches:
      - main

jobs:
  terraform:
    name: "Terraform"
    runs-on: ubuntu-latest
    env:
      GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
    defaults:
      run:
        working-directory: ./src
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1
        with:
          terraform_version: 1.0.1
          terraform_wrapper: false

      - name: Terraform Init
        id: init
        run: terraform init

      - name: Terraform Format
        id: fmt
        run: terraform fmt 
        
      - name: Terraform Plan
        id: plan
        run: terraform plan 

      - name: Terraform Apply
        id: apply
        run: terraform apply -auto-approve
    
      #- name: Terraform Destroy
        #id: destroy
        #run: terraform destroy -auto-approve

Implementation Steps:

With the configurations in place, here are the steps to implement this automated deployment:

  1. Set Up GitHub Repository: Create a new GitHub repository or use an existing one to host your Terraform code. You can clone this repository as a reference: GitHub Repository

  2. Configure GCP Provider: In the provider.tf file within the /src directory, configure the GCP provider with your project details, such as project ID, region, and zone.

  3. Set Secrets in GitHub: In your GitHub repository, navigate to Settings > Secrets > New repository secret. Add a new secret named "GOOGLE_CREDENTIALS" and paste the contents of your Google Cloud service account key file into the value field. This securely provides the necessary credentials for Terraform to authenticate with GCP.

Note: Ensure that there are no whitespace characters in your token content before pasting it.

  1. Automate with GitHub Actions: Commit and push your Terraform code to the GitHub repository. The GitHub Actions workflow will automatically trigger, executing the defined stages and jobs to deploy your Jenkins server on GCE.

  2. Verify Jenkins Installation: Once the deployment is complete, you can access Jenkins on the GCE instance to confirm a successful installation and configuration.

Logging into the Jenkins Server:

After successfully deploying the Jenkins server, you can access its web interface to start managing your Jenkins pipelines and jobs. Here's how to log in:

  1. Get the External IP: To access Jenkins, you'll need the external IP address of your GCE instance. You can find it in the Terraform output or the Google Cloud Console.

  2. Access Jenkins Web Interface:

    • Open a web browser.

    • Enter the external IP address of your GCE instance followed by port 8080 (e.g., http://:8080).

  3. Unlock Jenkins: The first time you access Jenkins, you'll be prompted to unlock it. To retrieve the initial administrator password:

    • SSH into the GCE instance where Jenkins is deployed.

    • Use this command to display the password: sudo cat /var/lib/jenkins/secrets/initialAdminPassword.

    • Copy the password and paste it into the Jenkins web interface to unlock.

  4. Set Up Jenkins: Follow the on-screen instructions to complete the initial setup, including installing plugins and creating an administrator user.

Example: Using Terraform to Create Resources:

Now that your Jenkins server is up and running, let's provide an example of how to use the Terraform code located in /terraform to create resources:

Create a JenkinsFile: In your Jenkins project, create a JenkinsFile. This file defines the automation steps to be executed by Jenkins.

pipeline {
    agent any
    tools {
         terraform 'Terraform'
    }
    stages{
        stage('Git Checkout'){
            steps{
                checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[url: 'https://github.com/Gavin-GCP/tf-gcp.git']])
            }
        }
        stage('Terraform Init'){
            steps{
                sh 'terraform init'
            }
        }
        stage('Terraform Plan'){
            steps{
                sh 'terraform plan'
            }
        }
        stage('Terraform Apply'){
            steps{
                sh 'terraform apply -auto-approve'
            }
        }
        #stage('Terraform Destroy'){
            #steps{
                #sh 'terraform destroy -auto-approve'
            #}
        #}
    }
}
  1. Configure Jenkins Project:

  • In your Jenkins project, navigate to the project configuration.

  • In the "Pipeline" section, select "Pipeline script from SCM."

  • Specify the repository URL and JenkinsFile location within your repository.

  1. Save and Build: Save the project configuration, and Jenkins will automatically trigger builds based on your JenkinsFile.

  2. Automate Terraform:

  • When Jenkins runs the pipeline, it will execute the Terraform commands defined in your JenkinsFile, such as terraform init, terraform plan, and terraform apply.

  • These commands will apply the Terraform configurations within the /terraform directory to provision and manage resources as specified. You can refer the code within /terraform in this repo: GitHub Repository


    5. Verify Resources: After running the Jenkins pipeline, you can verify the provisioned resources by checking the Google Cloud Console or using relevant CLI commands. This step ensures that the resources specified in your Terraform configurations, located in the /terraform directory, have been successfully created and configured.

Conclusion:

In conclusion, this blog has demonstrated how to seamlessly automate the deployment of a Jenkins server on Google Compute Engine (GCE) using Terraform and streamline resource provisioning with Jenkins pipelines. By following these steps, you can efficiently manage your cloud infrastructure, enhance your continuous integration and continuous delivery (CI/CD) workflows, and achieve greater consistency and efficiency in your cloud engineering endeavors. Happy automating!

References: