Skip to content

Instantly share code, notes, and snippets.

@Kambaa
Last active January 28, 2025 21:16
Show Gist options
  • Save Kambaa/009549bd3c34715833e37677ffec4463 to your computer and use it in GitHub Desktop.
Save Kambaa/009549bd3c34715833e37677ffec4463 to your computer and use it in GitHub Desktop.
add-passwordless-sudo-user

Add passworddless sudo user via ansible for Ubuntu 22.04 VM's(for personal uses/learning purposes only)

For my learning environment, i needed to quickly and correctly add a passwordless sudo user(for Ubuntu 22.04 VM), since i'm learning ansible, i decided to write the necessary inventory and playbook file, after that i decided to make it customizable via a bash script. User can enter the new user details(name and password) and machine ssh connection information (ip, username and password). And this script first tests the connection via ansible's ping module, after successful operation, asks user to run the generated playbook(or exit and show the command to run the playbook)

These bash scripts:

  • install python3,pip and sshpass(for ansible), and install ansible via pip
  • asks user to enter the new user details (username and password) to generate the ansible playbook
  • asks user to enter the remote machine information to generate the ansible inventory
  • pings the inventory machines
  • requests permission to run the generated playbook for the machines given in the inventory

To run these scripts simply run:

# Download Step 1
curl -O https://gist.githubusercontent.com/Kambaa/009549bd3c34715833e37677ffec4463/raw/8de3e11108a701b2d339c4a359b3b82c7a3cef2e/1-initial-operations-install-dependencies.sh

# Download Step 2
curl -O https://gist.githubusercontent.com/Kambaa/009549bd3c34715833e37677ffec4463/raw/4d96d70c421172ac46b391e1fbd2bbc554b5e71a/2-generate-and-run-ansible-playbook.sh

# Make the files executable
chmod +x 1-initial-operations-install-dependencies.sh
chmod +x 2-generate-and-run-ansible-playbook.sh

# Run the steps(in order)
./1-initial-operations-install-dependencies.sh
./2-generate-and-run-ansible-playbook.sh
# Update package index
echo "Updating package index..."
sudo apt update -y && sudo apt upgrade -y
# Install Python3 and pip if not already installed
echo "Installing Python3 and pip..."
sudo apt install -y python3 python3-pip sshpass
echo "Install complete! Checking Python and pip versions..."
pip --version
python3 --version
# Update package index
echo "Installing ansible via pip..."
pip install ansible passlib
echo "Install complete! Restart terminal session to see the effect!(run 'ansible --version')"
#!/bin/bash
# Set up the output file
INVENTORY_FILE="$PWD/inventory"
PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE="$PWD/1.add-passwordless-sudo-user.yaml"
# Function to ask for confirmation
confirm() {
if [ -e "$INVENTORY_FILE" ] && [ -e "$PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE" ]; then
while true; do
read -p "Use the previous configuration (y/n): " choice
case "$choice" in
y|Y ) return 1 ;; # Confirmed, return success
n|N ) return 0 ;; # Not confirmed, return failure
* ) echo "Invalid input. Please enter 'y' or 'n'." ;;
esac
done
else
return 0 # If files do not exist, return failure immediately
fi
}
if confirm; then
echo "You chose NO, proceeding with new configuration.."
echo "Running the task..."
# Ask for the new user infos:
read -p "Enter new machine user's name: " new_ssh_user
read -sp "Enter new user's password: " new_ssh_pass
echo "" > $PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE # Clear any previous content in the file
# Generate inventory dynamically
cat <<EOF > $PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE
---
- name: Add user and configure passwordless sudo
hosts: all
become: yes # Ensure tasks are executed with root privileges
tasks:
- name: Ensure user '$new_ssh_user' exists
user:
name: $new_ssh_user
password: "{{ '$new_ssh_pass' | password_hash('sha512') }}"
state: present
shell: /bin/bash
- name: Add '$new_ssh_user' to sudoers with passwordless sudo
lineinfile:
path: /etc/sudoers
regexp: '^$new_ssh_user'
line: '$new_ssh_user ALL=(ALL) NOPASSWD:ALL'
validate: '/usr/sbin/visudo -cf %s'
- name: Enable ssh authentication with passowrd - Remove ``KbdInteractiveAuthentication no`` config(for EC2 Ubuntu 22.04)
# This task removes 'KbdInteractiveAuthentication no' from the sshd_config to avoid issues.
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^KbdInteractiveAuthentication no'
state: absent
when: ec2ssh is defined
- name: Enable ssh authentication with password(for EC2 Ubuntu 22.04)
# This task adds 'KbdInteractiveAuthentication yes' and 'PasswordAuthentication yes' to enable password auth.
blockinfile:
path: /etc/ssh/sshd_config
marker: "# {mark} ANSIBLE MANAGED BLOCK"
block: |
KbdInteractiveAuthentication yes
PasswordAuthentication yes
insertbefore: EOF
create: yes
when: ec2ssh is defined
- name: Restart sshd service to apply changes
systemd:
name: sshd
state: restarted
enabled: yes
when: ec2ssh is defined
EOF
echo
echo "Playbook generation complete. File saved at $PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE"
echo
echo
echo
echo "Prompting inventory machine infos..."
echo "" > $INVENTORY_FILE # Clear any previous content in the file
# Loop to collect IPs, usernames, and passwords
while true; do
# Prompt for IP address
read -p "Enter IP address (or type 'done' to finish): " ip_address
if [[ "$ip_address" == "done" ]]; then
break
fi
if [[ -z "$ip_address" ]];then
continue
fi
# Prompt for username
read -p "Enter SSH username for \`$ip_address\`(or type 'done' to finish): " ssh_user
if [[ "$ssh_user" == "done" ]]; then
break
fi
ansibe_ssh_user_part=""
if [[ -n "$ip_address" ]]; then
ansibe_ssh_user_part="ansible_ssh_user=$ssh_user"
fi
# Prompt for password
read -sp "Enter SSH password for \`$ip_address\`(or type 'done' to finish): " ssh_pass
echo # Print a new line for better readability after password input
if [[ "$ssh_pass" == "done" ]]; then
break
fi
ansibe_ssh_pass_part=""
if [[ -n "$ssh_pass" ]]; then
ansibe_ssh_pass_part="ansible_ssh_pass=$ssh_pass"
fi
# Prompt for become password (sudo password)
read -sp "Enter become password (sudo password) for \`$ip_address\`: " become_pass
echo # Print a new line for better readability after password input
ansibe_ssh_become_pass_part=""
if [[ -n "$become_pass" ]]; then
ansibe_ssh_become_pass_part="ansible_become_password=$become_pass"
fi
# Prompt for key file
read -p "Enter key file path for \`$ip_address\`: " keyfile
echo # Print a new line for better readability after password input
keyfile=$(echo "$keyfile" | sed 's|^~|'$HOME'|')
ansibe_ssh_keyfile_part=""
if [[ -n "$keyfile" ]]; then
# Loop to ensure the file exists
while [[ ! -f "$keyfile" ]]; do
echo "The provided SSH key file does not exist: $keyfile"
read -p "Enter a valid key file path for $ip_address: " keyfile
keyfile=$(echo "$keyfile" | sed 's|^~|'$HOME'|')
done
ansibe_ssh_keyfile_part="ansible_ssh_private_key_file=$keyfile"
fi
echo
# Write the gathered information into the inventory file
echo "$ip_address $ansibe_ssh_user_part $ansibe_ssh_pass_part $ansibe_ssh_become_pass_part $ansibe_ssh_keyfile_part" >> $INVENTORY_FILE
echo "Added $ip_address to inventory."
read -p "Add another machine to ansible inventory? (y/n): " inventory_ending_choice
inventory_ending_choice=$(echo "$inventory_ending_choice" | tr '[:upper:]' '[:lower:]')
if [[ "$inventory_ending_choice" == "n" ]]; then
break
fi
done
echo "Inventory generation complete. File saved at $INVENTORY_FILE."
fi
# Check if ansible and passlib are installed using pip list
check_package_installed() {
package=$1
# Check if the package is installed using pip show
pip show "$package" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "$package is installed."
else
echo "$package is NOT installed."
echo "install $package with this command: 'pip install ansible passlib'"
exit 1
fi
}
# Check if ansible and passlib are installed
check_package_installed "ansible"
check_package_installed "passlib"
echo
echo
echo
echo "RUN ANSIBLE COMMAND: pinging machine written in inventory file"
ANSIBLE_HOST_KEY_CHECKING=False ansible -i inventory all -m ping
# Check the exit code of the Ansible command
if [ $? -ne 0 ]; then
echo "Ansible ping failed. See the command output above for details."
exit 1
else
echo "Ansible ping succeeded."
fi
read -p "Continue running the ansible playbook? (y/n): " choice
# Convert input to lowercase for consistency
choice=$(echo "$choice" | tr '[:upper:]' '[:lower:]')
# Check if the user responded with 'y'
if [[ "$choice" == "y" ]]; then
echo "You chose Yes, running the command..."
read -p "[ONLY FOR EC2 Ubuntu] Enable password login for ssh (y/n): " choice2
# Convert input to lowercase for consistency
choice=$(echo "$choice2" | tr '[:upper:]' '[:lower:]')
[ "$choice" == "y" ] && ec2sshansiblevar="-e ec2ssh=y" || ec2sshansiblevar=""
ansible-playbook -i $INVENTORY_FILE $PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE $ec2sshansiblevar
else
echo "You did not press 'Y', exiting..."
echo "You can manually run via this command: 'ansible-playbook -i $INVENTORY_FILE $PASSWORDLESS_SUDO_USER_ADDING_PLAYBOOK_FILE -vvvv'"
exit 1
fi

Comments are disabled for this gist.