This article is part of a series.
- SSH Series
- Part 1: Introduction to SSH
- Part 2: Setting Up and Using SSH
- Part 3: SSH Key Based Authentication
- Part 4: SSH Best Practices and Security Hardening
- Part 5: Advanced SSH Techniques
- Part 6: Troubleshooting Common SSH Issues
- Part 7: Automating Tasks With Automation
- Part 8: SSH Alternatives and Enhancements
- Part 9: Recap, Further Resources, and Closing Thoughts

Throughout this SSH series, I’ve explored everything from basic setups and key-based authentication to best practices and troubleshooting. Now, I’m going to show you how to automate tasks using SSH—an essential skill in modern DevOps and system administration. Whether you’re executing simple commands on multiple servers or orchestrating complex deployments, SSH can simplify and secure your workflow.
Basics of SSH Usage in Bash Scripting
Bash Scripting with SSH Commands
One of the most straightforward ways to automate tasks with SSH is by writing bash scripts. For instance, suppose I want to run a disk usage check on a remote server every day. Instead of logging in manually, I can script it:
#!/bin/bash
REMOTE_USER="myuser"
REMOTE_HOST="example.com"
REMOTE_CMD="df -h"
echo "Checking disk usage on $REMOTE_HOST..."
ssh "${REMOTE_USER}@${REMOTE_HOST}" "$REMOTE_CMD"
ssh user@host "<command>"
- Runs a single command on the remote host without opening an interactive shell.
- Advantages
- You can store these commands in scripts, schedule them with cron, or trigger them on demand.
Error Handling
If you want to detect errors (like permission issues or missing commands), you can check $?
(the exit code)
ssh "${REMOTE_USER}@${REMOTE_HOST}" "$REMOTE_CMD"
if [ $? -ne 0 ]; then
echo "Error: Could not run command on $REMOTE_HOST"
fi
Handling Non-Interactive Authentication
For automation, non-interactive logins are key. I recommend key-based authentication (as covered in Part 3 of this series). Here’s a quick recap:
-
Generate SSH Keys (on your local machine)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_automation
-
Copy the Public Key to the Server
ssh-copy-id -i ~/.ssh/id_ed25519_automation.pub user@host
-
Use the Private Key in Your Script
ssh -i ~/.ssh/id_ed25519_automation user@host "<command>"
You can store the key in a secure location and reference it from your script. This way, the script never needs to prompt for a password, which is crucial for scheduled tasks or large-scale automation.
[!Tip] To add a passphrase to your key for extra security, consider using an SSH agent or keychain to cache passphrases if the script environment allows it.
Handling Multiple Servers
Using for
Loops
If you have a small set of servers, a simple bash for loop can do the trick
#!/bin/bash
SERVERS=("server1.example.com" "server2.example.com" "server3.example.com")
CMD="uptime"
for HOST in "${SERVERS[@]}"; do
echo "----- $HOST -----"
ssh "myuser@$HOST" "$CMD"
done
This will SSH into each server and run uptime
. Of course, you can expand this with different commands, error handling, or output parsing.
Parallel SSH (pssh)
If you have dozens or hundreds of servers, waiting on them one by one can be slow. Tools like pssh (parallel SSH) let you run commands in parallel:
-
Install pssh
- Ubuntu/Debian
sudo apt-get install pssh
- Ubuntu/Debian
-
Create a Host File (
hosts.txt
)server1.example.com server2.example.com server3.example.com
-
Run a Command
pssh -h hosts.txt -l myuser -A -i "uptime"
Where
-h hosts.txt
: Reads the list of hosts.-A
: Prompts you for a password (if not using key-based auth).-i
: Prints output inline.
This way, each SSH session is executed in parallel, saving you time.
Ansible as an Alternative
For more sophisticated automation, Ansible is a popular choice. It uses SSH under the hood by default, so you don’t need extra daemons.
-
Install Ansible
sudo apt-get install ansible
-
Inventory File (
inventory.ini
)[webservers] server1.example.com server2.example.com [dbservers] server3.example.com
-
Run a Command
ansible webservers -m shell -a "uptime" -u myuser
Ansible handles parallel execution, conditional tasks, modules for different actions, and more.
Best Practices for SSH Automation
Key Management
- Separate Keys
- Use different SSH keys for automated tasks than for interactive logins. This way, if one key is compromised, you don’t lose all access.
- Rotate Keys
- Regularly: Update keys periodically to reduce the risk of old keys being abused.
- Least Privilege
- Limit each key to exactly what it needs (e.g.,
command="uptime"
inauthorized_keys
if you only want that command to run).
- Limit each key to exactly what it needs (e.g.,
Secrets Handling
- Never Store Passwords in Plain Text
- If you must use passwords, consider environment variables or secure vaults (e.g., Ansible Vault, HashiCorp Vault).
- Encrypted Filesystems
- If your automation server stores multiple private keys, keep them on an encrypted filesystem or use strong passphrases.
3.3 Minimizing Exposure
- Restrict IP Addresses
- Use firewalls to limit SSH access to known management stations.
- Logging and Monitoring
- Keep an eye on
/var/log/auth.log
or equivalent. Automated tasks can run frequently, so watch for anomalies.
- Keep an eye on
- Periodic Review
- Regularly audit which scripts and cron jobs use SSH. Remove anything unnecessary or outdated.
Example Workflow: Automated Software Update
Let me show you a quick scenario:
-
Script (
update_servers.sh
):#!/bin/bash SERVERS=("web1" "web2" "db1") CMD="sudo apt-get update && sudo apt-get upgrade -y" for HOST in "${SERVERS[@]}"; do echo "Updating $HOST..." ssh -i ~/.ssh/id_automation "myuser@$HOST" "$CMD" done
-
Set a Cron Job:
crontab -e
# Run at 2 AM every Sunday 0 2 * * 0 /home/myuser/update_servers.sh >> /var/log/update_servers.log 2>&1
-
Check Logs
- Each Sunday, the script auto-updates all listed servers. The logs can be reviewed for any errors.
[!Warning] Automatic upgrades can sometimes break services if dependencies change. Always test updates on a staging environment before rolling them out.
Conclusion
By leveraging SSH in scripts, using tools like pssh or Ansible, and adhering to best practices for key management and secrets handling, you can streamline admin tasks and reduce manual overhead. This approach is especially invaluable when managing large server fleets or complex deployments.
Key Takeaways
- Scripting SSH calls can handle repetitive tasks like collecting logs, running health checks, or deploying updates.
- Parallel tools (pssh, Ansible) greatly speed up tasks that would be tedious to run server-by-server.
- Security is paramount: treat your automation keys like the keys to your kingdom—because they are.
In our next and final posts, I’ll dive deeper into more SSH tools and alternatives. Feel free to leave a comment if you have questions or want to share your own automation tips!
Further Reading
Happy automating, and I’ll see you in the next part of this SSH series!
This article is part of a series.
- SSH Series
- Part 1: Introduction to SSH
- Part 2: Setting Up and Using SSH
- Part 3: SSH Key Based Authentication
- Part 4: SSH Best Practices and Security Hardening
- Part 5: Advanced SSH Techniques
- Part 6: Troubleshooting Common SSH Issues
- Part 7: Automating Tasks With Automation
- Part 8: SSH Alternatives and Enhancements
- Part 9: Recap, Further Resources, and Closing Thoughts
comments powered by Disqus