Skip to content

Instantly share code, notes, and snippets.

@sony-level
Created April 24, 2026 16:42
Show Gist options
  • Select an option

  • Save sony-level/6031748be8a2830fc9ef9823540d6113 to your computer and use it in GitHub Desktop.

Select an option

Save sony-level/6031748be8a2830fc9ef9823540d6113 to your computer and use it in GitHub Desktop.
Creation of a user dedicated to the ci/cd task via jenkins
#!/usr/bin/env bash
set -euo pipefail
# ============================================================
# Script Name: setup_jenkins_agent.sh
# Purpose:
# Create and configure a dedicated Jenkins SSH agent user
# on a host, prepare its SSH authorized_keys file, install
# Java if needed, and optionally add the user to the Docker
# group. The controller public key is mandatory, and up to
# 3 additional public keys can also be added.
#
# Author:
# Level Sony
# ============================================================
JENKINS_USER="jenkins"
JENKINS_HOME="/home/${JENKINS_USER}"
AGENT_DIR="${JENKINS_HOME}/agent"
SSH_DIR="${JENKINS_HOME}/.ssh"
AUTHORIZED_KEYS="${SSH_DIR}/authorized_keys"
MAX_EXTRA_KEYS=3
log() {
echo "[INFO] $1"
}
warn() {
echo "[WARN] $1"
}
err() {
echo "[ERROR] $1" >&2
}
require_root() {
if [ "$(id -u)" -ne 0 ]; then
err "This script must be run as root."
err "Example: sudo bash setup_jenkins_agent.sh"
exit 1
fi
}
create_user_if_needed() {
if id "${JENKINS_USER}" >/dev/null 2>&1; then
log "User '${JENKINS_USER}' already exists."
else
log "Creating user '${JENKINS_USER}'..."
adduser --disabled-password --gecos "" "${JENKINS_USER}"
fi
}
prepare_directories() {
log "Preparing directories..."
mkdir -p "${AGENT_DIR}"
mkdir -p "${SSH_DIR}"
touch "${AUTHORIZED_KEYS}"
chown -R "${JENKINS_USER}:${JENKINS_USER}" "${JENKINS_HOME}"
chmod 700 "${SSH_DIR}"
chmod 600 "${AUTHORIZED_KEYS}"
}
is_valid_ssh_key() {
local key="$1"
case "${key}" in
ssh-ed25519\ *|ssh-rsa\ *|ecdsa-sha2-nistp256\ *|ecdsa-sha2-nistp384\ *|ecdsa-sha2-nistp521\ *)
return 0
;;
*)
return 1
;;
esac
}
append_key_if_missing() {
local key_name="$1"
local public_key="$2"
if grep -Fxq "${public_key}" "${AUTHORIZED_KEYS}"; then
warn "Key '${key_name}' is already present. Skipping."
else
echo "${public_key}" >> "${AUTHORIZED_KEYS}"
log "Added key '${key_name}'."
fi
}
prompt_non_empty() {
local prompt_message="$1"
local value=""
while true; do
read -r -p "${prompt_message}" value
if [ -n "${value}" ]; then
printf '%s\n' "${value}"
return 0
fi
warn "This field is required."
done
}
prompt_public_key() {
local prompt_message="$1"
local public_key=""
while true; do
read -r -p "${prompt_message}" public_key
if [ -z "${public_key}" ]; then
warn "This field is required."
continue
fi
if is_valid_ssh_key "${public_key}"; then
printf '%s\n' "${public_key}"
return 0
fi
warn "Invalid SSH public key format. Expected formats include ssh-ed25519, ssh-rsa, or ecdsa."
done
}
collect_and_add_keys() {
local controller_key_name=""
local controller_public_key=""
local add_more=""
local extra_key_name=""
local extra_public_key=""
local i=1
echo
echo "=================================================="
echo "SSH PUBLIC KEYS CONFIGURATION"
echo "The controller public key is required."
echo "You can also add up to ${MAX_EXTRA_KEYS} additional public keys."
echo "=================================================="
echo
controller_key_name="$(prompt_non_empty "Enter the controller key name (required): ")"
controller_public_key="$(prompt_public_key "Enter the controller public key (required): ")"
append_key_if_missing "${controller_key_name}" "${controller_public_key}"
while [ "${i}" -le "${MAX_EXTRA_KEYS}" ]; do
echo
read -r -p "Do you want to add extra key #${i}? [y/N]: " add_more
add_more="${add_more:-N}"
case "${add_more}" in
y|Y|yes|YES)
extra_key_name="$(prompt_non_empty "Enter name for extra key #${i}: ")"
extra_public_key="$(prompt_public_key "Enter public key for '${extra_key_name}': ")"
append_key_if_missing "${extra_key_name}" "${extra_public_key}"
;;
*)
break
;;
esac
i=$((i + 1))
done
chown "${JENKINS_USER}:${JENKINS_USER}" "${AUTHORIZED_KEYS}"
chmod 600 "${AUTHORIZED_KEYS}"
}
install_java_if_needed() {
if command -v java >/dev/null 2>&1; then
log "Java is already installed."
java -version || true
else
log "Java is not installed. Installing default-jdk..."
apt update
apt install -y default-jdk
log "Java installed successfully."
java -version || true
fi
}
add_to_docker_group_if_present() {
if getent group docker >/dev/null 2>&1; then
log "Adding '${JENKINS_USER}' to the docker group..."
usermod -aG docker "${JENKINS_USER}"
else
warn "Docker group does not exist. Skipping this step."
fi
}
lock_password() {
log "Locking password for '${JENKINS_USER}'..."
passwd -l "${JENKINS_USER}" >/dev/null 2>&1 || true
}
show_summary() {
echo
echo "Configuration completed."
echo "User : ${JENKINS_USER}"
echo "Home : ${JENKINS_HOME}"
echo "Agent directory : ${AGENT_DIR}"
echo "Authorized keys file : ${AUTHORIZED_KEYS}"
echo
echo "Jenkins node settings:"
echo " Username : ${JENKINS_USER}"
echo " Remote root directory: ${AGENT_DIR}"
echo " Launch method : Launch agents via SSH"
echo
echo "Test SSH:"
echo " ssh -i ~/.ssh/jenkins_agent ${JENKINS_USER}@your-host"
echo
echo "Current authorized keys:"
nl -ba "${AUTHORIZED_KEYS}" || true
}
main() {
require_root
create_user_if_needed
prepare_directories
collect_and_add_keys
install_java_if_needed
add_to_docker_group_if_present
lock_password
show_summary
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment