DS‐ Automation with Ansible - 229300/SYS265-System-Admin.-Network-Services-II---Spring-2026 GitHub Wiki

My Proxmox Environment

Please Power down and say goodbye to web, nmon, and docker. These systems will be deleted later this week. You keep ad01, fw01, mgmt01 and wks01. You have new VMs, controller(ubuntu), ansible1(centos), and ansible2(rocky)

Networking

Connect all to the LAN

  • controller: 10.0.5.90
  • ansible1: 10.0.5.91
  • ansible2: 10.0.5.92

Linux Accounts

Create the following Linux accounts:

  • On controller, create a named sudo user daniel, & another sudo user named deployer
  • On ansible1 and ansible2, create a sudo user named ‘deployer’
  • All deployer passwords should be the same
Note: Creating a sudo user on Rocky Linux and CentOS is the same, as both are RHEL-based distributions, but it is different from the process on Ubuntu, which is Debian-based.
Rocky Linux and CentOS use the wheel group
Ubuntu uses the sudo group

Check the version on each VM

cat /etc/os-release

Controller:

Create a new user with my own password

  • sudo useradd -m daniel && sudo passwd daniel

Add daniel to the sudo group (Debian "admin" group)

  • sudo usermod -aG sudo daniel

Change my root account password from champlain password

  • sudo passwd root

Change the system hostname to whatever is appropriate

  • sudo hostnamectl set-hostname controller-daniel

Create a new user with my own password

  • sudo useradd -m deployer && sudo passwd deployer

Add daniel to the sudo group (Debian "admin" group)

  • sudo usermod -aG sudo deployer
  • exit

Ansible1

Create a new user with my own password

  • sudo useradd -m deployer && sudo passwd deployer

Add daniel to the wheel group (Rocky's "admin" group)

  • sudo usermod -aG wheel deployer

Change my root account password from champlain password

  • sudo passwd root

Change the system hostname to whatever is appropriate

  • sudo hostnamectl set-hostname ansible01-daniel
  • exit

Ansible2

Create a new user with my own password

  • sudo useradd -m deployer && sudo passwd deployer

Add daniel to the wheel group (Rocky's "admin" group)

  • sudo usermod -aG wheel deployer

Change my root account password from champlain password

  • sudo passwd root

Change the system hostname to whatever is appropriate

  • sudo hostnamectl set-hostname ansible02-daniel
  • exit

Controller (Ubuntu) adding to domain

  1. Check ens (network interface)
  • ls /sys/class/net
  1. Configure IP address via netplan
  • sudo nano /etc/netplan/00-installer-config.yaml
  • Looks like:
  • sudo chmod 600 /etc/netplan/00-installer-config.yaml
  • sudo netplan apply (should give no warnings)
  1. Add IP address to DNS Server / Create DNS records for controller-daniel
  • Navigate to mgmt01 VM --> Server manager --> DNS Manager --> Forward Lookup Zone
  • New 'A' Host:

Ansible1 (centos)

  1. set IP address using sudo nmtui (i set the hostname earlier but if i didn't i wiould do it here)
Remember: Always navigate to IPv4 and Change it to Manual NOT Automatic
  1. Edit a Connection
  • Looks like:
  1. Restart Network for changes to take effect
  • sudo systemctl restart NetworkManager
  • ip addr (to display new IP)
  • Looks like:
  1. Add IP address to DNS Server via mgmt01
  • Server manager --> DNS Manager --> Forward Lookup Zone
  • New 'A' Host:

Ansible2 (rocky)

  1. set IP address using sudo nmtui
  2. Edit a Connection
  • Looks like:
  1. Restart Network for changes to take effect
  • sudo systemctl restart NetworkManager
  • ip addr (to display new IP)
  • Looks like:
  1. Add IP address to DNS Server via mgmt01
  • Server manager --> DNS Manager --> Forward Lookup Zone
  • New 'A' Host:
  1. Check DNS Manager Catalog:

Disable SSH Root Login for all 3 Systems

Disabling SSH root login is a standard security best practice and is not necessary to access your systems, provided you have another user account with administrative (sudo) privileges.
Blocks Direct Root Access: It prevents anyone from logging in directly as the "root" user via SSH, even if they have the correct password or SSH key.
  1. Controller
  • sudo nano /etc/ssh/sshd_config
  • Uncomment and Change PermitRootLogin to no:
  • sudo systemctl restart ssh
  1. Ansible1
  • Install nano: sudo dnf install -y nano
  • sudo dnf upgrade -y nano
  • sudo nano /etc/ssh/sshd_config
  • Uncomment and Change PermitRootLogin to no
  • sudo systemctl restart sshd
  • sudo systemctl status sshd
  1. Ansible2
  • sudo dnf install -y nano
  • sudo dnf upgrade -y nano
  • sudo nano /etc/ssh/sshd_config
  • Uncomment and Change PermitRootLogin to no
  • sudo systemctl restart sshd
  • sudo systemctl status sshd

Check Connection/DNS via ssh, nslookup, and ping

  1. SSH from mgmt01-daniel via PuTTY to controller-daniel (login as daniel NOT deployer):
  • Type bash to begin
  1. Nslookup:
  • nslookup controller-daniel ad01-daniel
  1. Check Connection via Ping
  • ping -c1 ansible01-daniel
  • ping -c1 ansible02-daniel
  • ping -c1 champlain.edu
  • Looks like:

Testing Deployer Account

  1. Do the following commands:
  • sudo su - deployer
  • sudo -i

Installing Ansible

  • Install command: sudo apt install ansible sshpass python3-paramiko -y
  • ansible --version
  • Looks like:

Create /etc/sudoers.d/sys265 on all Linux systems

  1. On mgmt01 ssh into controller-daniel and login as deployer
  • sudo visudo -f /etc/sudoers.d/sys265
Research: Using visudo is critical because it checks your syntax for errors before saving. A single typo in a sudoers file can lock you out of administrative access.
  • Edit the file:
  1. On mgmt01 ssh into ansible01-daniel and login as deployer
  • sudo visudo -f /etc/sudoers.d/sys265
  • Edit the file:
  1. On mgmt01 ssh into ansible02-daniel and login as deployer
  • sudo visudo -f /etc/sudoers.d/sys265
  • Edit the file:

Generate RSA Key pair on Controller with a passphrase protected private key

  1. Generating the key pair
  • ssh-keygen -t rsa (creates a public and private key pair)
  • Use defualt directory to save key (by hitting enter) (saves the key to the file /home/deployer/.ssh/id_rsa)
  • input passphrase
  • Looks like:
  1. Using ssh-copy-id, add deployer@controller's public key to the deployer accounts on ansible01 and ansible02
  • ssh-copy-id deployer@ansible01-daniel
  • Looks like:
  • ssh-copy-id deployer@ansible02-daniel
  • Looks like:

Demonstrate passwordless login for Ansible boxes

  • eval $(ssh-agent)
  • ssh-add -t 14400
  1. Passwordless SSH to ansible01 and ansible02 via deployer@controller-daniel
  • ssh deployer@ansible01-daniel
  • ssh deployer@ansible02-daniel
  • Looks like:

First run

  1. Setup the following directory hierarchy and inventory file on controller-daniel. The assumption is that ansible01-daniel and ansible02-daniel resolve via DNS. Run the first ansible ping.
  • pwd
  • mkdir -p ansible/roles
  • cd ansible/
  • echo ansible01-daniel >> inventory.txt
  • echo ansible02-daniel >> inventory.txt
  • cat inventory.txt
  • ansible all -m ping -i inventory.txt
  • Looks like:

Ad-hoc commands

  1. These are one-off commands that are executed on the command of an ansible control node
  • Example:
  1. My own ad-hoc command:
  • Command: ansible all -a "df -h" -i inventory.txt (This command displays the disk space usage on all your managed nodes in a human-readable format)
  • Breakdown of Command:
  • Looks like:
  1. Update your inventory to categorize your ansible02 host by type. Then test ping against just the hosts under the [webmin] tag
  • nano inventory.txt
  • Add [webmin] in between the ansibles
  • Inside nano looks like:
  • Wanted output:

Webmin Playbook Installation

  1. Change directories to roles and create the .webmin.yml file

Note: I used .webmin.yml (with a dot). Usually, files starting with a dot are "hidden" in Linux. It's cleaner to name the new one ansible01_deploy.yml without the leading dot, but either works. If I want to view my .webmin.yml file I need to use the command: ls -a. If I want to change the file name so it's no longer hidden I do the command: mv .webmin.yml webmin.yml.
  • cd roles
  • nano .webmin.yml
  • Paste this information into .webmin.yml:
  • cd .. (leave roles and change to ansible)
  1. Execute the playbook:
  • ansible-playbook -i inventory.txt roles/.webmin.yml
  • Looks like:
  1. The reason that webmin only executes on ansible02 is because we labeled it as so in the inventory.txt file with [webmin]. I organized it so ansible02-daniel is under a group header called [webmin]. This is done by placing [webmin] above ansible02 in the inventory.txt file.

Login to webmin as root@ansible02

  1. Navigate to a browser via mgmt01-daniel and search:
  • Login Page looks like:
  • Sign in with root as username and password (i set earlier)
  • Looks like:

Install your own role with Ansible Galaxy

  1. I'm going to try installing patch management
In simple terms, patch management is the process of finding, testing, and installing updates (patches) to the software and operating system on your computers
  1. Now I Update my inventory to categorize my ansible01-daniel host by type. Then test ping against just the hosts under the [patching] tag (which is ansible01)
  2. Via deployer@controller-daniel in the ansible directory:
  • nano inventory.txt
  • Add [patching] in above ansible01
  • Inside nano looks like:
  • ansible patching -m ping -i inventory.txt
  • Looks like:
NOTE!: I realized when I did the command: ansible patching -m ping -i inventory.txt, I was prompted for my passphrase, this was not the case last time I did this ping for webmin. Then I remembered two commands from before:
  • eval $(ssh-agent)
  • ssh-add -t 14400
  • Looks like:

Patch Management Playbook Installation

  1. Install the roles
  • ansible-galaxy role install alemorvan.patchmanagement -p roles/
  • Looks like:
  1. Change directories to roles/ and create the patching.yml file
  • cd roles
  1. Create the Playbook:
  • nano patching.yml
  • Paste the playbook info into patching.yml:
  1. Breakdown of playbook:
The Header (---) YAML Start- These three dashes signify the beginning of a YAML file
name- Install Patch Management on CentOS: This is a human-readable label
hosts: patching- This tells Ansible which group of servers to target. It will look for the [patching] header I added to the inventory.txt file
become: yes- This is a security instruction. It tells Ansible to "become" the root user (using sudo) on the target machine
tasks:- This starts the list of specific actions Ansible will take on the server
name: Update all system packages- This is a label for this specific step, I will see this text right before the task runs
dnf:- This is the module Ansible uses to manage software on modern Red Hat-based systems like Rocky Linux 9 and CentOS 8/9
name: "*"- The asterisk is a wildcard. It tells the dnf module to look at every single package currently installed on the system
state: latest- This is the "goal" state. It tells Ansible: "Check the official repositories; if there is a newer version of any package available, download and install it."
  • cd .. (change directory back to ansible)
  1. Optional Ping Again
  • ansible patching -m ping -i inventory.txt
  • Should display success
  1. Execute the playbook:
  • ansible-playbook -i inventory.txt roles/patching.yml
  • Looks like:
  1. Provide a screenshot of my new service functionality from a remote client perspective (controller-daniel)
  • ansible patching -a "dnf check-update" -i inventory.txt
  • Looks Like:

This is the best "proof" because if the patching was successful, this command should return 0 or "No packages marked for update."

Windows Automation

  1. Preparing MGMT01 for Ansible
  • Open Services Applicationas an Administrator: Windows Search- Services
  • Locate and Open: Windows Update
  • Change from Manual to Automatic
  • Looks like:
  • Apply the changes
  1. Start Windows Update Service
  • Looks like:

Install OpenSSH Server via Powershell Admin Prompt

  1. On mgmt admin powershell:
  2. Check for what we have installed:
  • Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
  • Looks like:
  1. Install OpenSSH.Server:
  • Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
  • Should display:
  • Start-Service sshd (outputs warning)
  • Set-Service -Name sshd -StartupType 'Automatic'
  • Start-Service sshd (now its clean)
  1. Check for what's installed again:
  • Looks like:

Set Powershell to be the Default Shell for SSH

  • Set-ItemProperty "HKLM:\Software\Microsoft\Powershell\1\ShellIds" -Name ConsolePrompting -Value $true

This command modifies the Windows Registry to change how PowerShell asks for credentials.

  • New-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

This command sets PowerShell as the default shell for anyone connecting to that Windows machine via SSH

SSH into mgmt01

  1. Navigate to controller-daniel VM
  2. From deployer@controller-daniel ansible directory:
  1. Update Inventory file to add a new group called windows with mgmt01-yourname as the host in that group. Also include the variables associated with that group [windows:vars]
  • exit ssh
  • Should be back on deployer@controller-daniel in the ansible directory
  • nano inventory.txt
  • Add [windows] in above mgmt01-daniel
  • Add [windows:vars] above ansible_shell_type=powershell
  • Inside nano looks like:
  • cat inventory.txt (should match the teachers)
  • ansible windows -i inventory.txt -m win_ping -u [email protected] --ask-pass
  • Looks like:
  1. Updating Inventory for wks01:
  • nano inventory.txt
  • Add [windows] in above wks01-daniel
  • Inside nano looks like:
  1. Add wks01 to your inventory under the windows category. If I rerun the win_ping I will likely get the following common error:
  1. I can fix this in one of two ways. The first would be to ssh into wks1 first and accept the key. The second would be to ignore unknown hosts and you would do so by adding the following file to the directory in which you are running your ansible commands

  2. Adding ansible.cfg in "ansible" directory:

  • pwd
  • nano ansible.cfg
  • Looks like:
  • cat ansible.cfg (verify)
  1. Rerun the ping:

Didn't work for me workaround time

  1. Navigate to wks01-daniel
  2. Navigate to Services Application / Windows Search: Services
  3. Navigate to Windows Update
  4. Change Windows Update Startup Type: From Manual to Automatic
  • Apply the changes
  1. Run PowerShell as an Administrator
  2. Do these commands:
  • New-NetFirewallRule -Name sshd -DisplayName 'Allow SSH' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
  • Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
  • OpenSSH.Server is most likely NotPresent
  1. Install OpenSSH.Server
  • Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
  • Looks like:
  1. Ensure SSH is Running:
  • Start-Service sshd (outputs warning)
  • Set-Service -Name sshd -StartupType 'Automatic'
  • Start-Service sshd (now its clean)
  1. Set Powershell to be the Default Shell for SSH
  • Set-ItemProperty "HKLM:\Software\Microsoft\Powershell\1\ShellIds" -Name ConsolePrompting -Value $true
  • New-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
  1. Test Connectivity from controller-daniel to wks01-daniel
  1. Rerun win_ping
  • ansible windows -i inventory.txt -m win_ping -u [email protected] --ask-pass
  • Looks like:
Throw one of these in there if it still doesn't work but it should now. Also ensure the forward lookup and reverse lookups are pointing to the same IP address. The (I believe) Optional command: Enable-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)"

Software deployment using win_chocolatey

  1. Construct a new playbook within the roles directory called windows_software.yml. This is a simple playbook that uses built-in ansible functionality as opposed to a downloaded role. The list of tasks below will use a module called win_chocolatey which is a package manager for Windows similar to apt-get or yum that is becoming more popular in enterprises.
  2. Navigate to controller-daniel ansible/roles/ directory
  • Most likely already in ansible directory
  • cd roles
  • nano windows_software.yml
  • Looks like:

Installation

  1. cd ..
  2. cat roles/windows_software.yml
  3. Execute the playbook:
  • ansible-playbook -i inventory.txt roles/windows_software.yml -u [email protected] --ask-pass
  • Looks like:

Adding Notepad++ to wks01 and mgmt01

  1. See if you can figure out how to add the Notepad++ for windows package to wks1 and mgmt01. Rerun your playbook.
  2. Add a line in the windows_software.yml file that says notepadplusplus
  • cd roles
  • nano windows_software.yml
  • Looks like:
  • cd ..
  1. Re-run Playbook:

SSH to mgmt01 and Prove Notepad++ Installation

  1. ssh [email protected]@mgmt01-daniel
  2. Do these commands:

Link to Docs: https://docs.google.com/document/d/1L8nEN4oF1u7NbXo-N0hTY4ZKJZop3OEDSXC8rO6gbpA/edit?tab=t.0#heading=h.qt02ywaf56w2

Best Google AI Link: https://www.google.com/search?q=how+do+i+Disable+SSH+Root+Login+via+sudo+nano+%2Fetc%2Fssh%2Fsshd_config&sca_esv=80b90e68a26a4cba&sxsrf=ANbL-n48yKtgM5PHVfBgGQwIuoOkI-cbsg%3A1771970320479&source=hp&ei=EB-eaeyUEcXe2roP6IzUkQI&iflsig=AFdpzrgAAAAAaZ4tIKX5T2iC4qD_oF34Z3PaGkxHuJ5z&aep=22&ved=0ahUKEwjs3Pjrj_OSAxVFr1YBHWgGNSIQteYPCBo&oq=&gs_lp=Egdnd3Mtd2l6IgBIAFAAWABwAHgAkAEAmAEAoAEAqgEAuAEByAEAmAIAoAIAmAMAkgcAoAcAsgcAuAcAwgcAyAcAgAgA&sclient=gws-wiz&mstk=AUtExfAAJfgDoxP6vRX4anatBv83gPz6MYTiu60jF8v64FQCo6BfYuxI4DSSD9ISia7yDVreosGjnRGGPOyHin8SM0SoXyjpIeK58iNiknAn8YOg7Pp2P4c5lj_P4ejPF_WF74gFQfS8sG0c1OCIT-KYCzRtwkW2IFlEqhFzqnwB0dqZtH5mqWvNhh8Z4gMpGKVWMySdi_nXZrncuUrKKUEq9sDuEXkcGQnlNOplKNKbaBYIy3sTCwyC6vXAhw9ZZb3nffvsNPGwOOJCTC4hq2eqg2wSpofCsEhHOLc&csuir=1&lns_mode=cvst&udm=50