PROBLEM
To run Ansible playbook in multiple hosts via SSH.
SOLUTION
Configuring SSH environment
Ensure SSH keypair exists on the current machine (ex: ~/.ssh/id_rsa for private key and ~/.ssh/id_rsa.pub for public key). If you do not have one, create one:
ssh-keygen
Copy the public key (ex: ~/.ssh/id_rsa.pub) to each remote host’s ~/.ssh/authorized_keys. If this file doesn’t exist, create it.
Ensure the current machine’s .ssh/ directory and file have correct permission.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
In the current machine’s /etc/hosts, add all remote hosts.
127.0.0.1 localhost # current machine
192.168.1.100 donkeykong # remote host 1
192.168.1.200 supermario # remote host 2
In each remote host, enable the remote login and grant yourself the access to this service.
Test SSH connection to remote host to ensure they work first before working on Ansible playbook.
ssh user@donkeykong
ssh user@supermario
Creating Ansible Playbook
Create ansible.cfg and define the location of inventory file.
[defaults]
inventory = inventory.yml
Create inventory.yml and define both localhost and remote hosts.
all:
hosts:
localhost:
ansible_connection: local
donkeykong:
ansible_user: user
ansible_ssh_private_key_file: ~/.ssh/id_rsa
supermario:
ansible_user: user
ansible_ssh_private_key_file: ~/.ssh/id_rsa
Run a test to ensure the connection to remote hosts are successful.
ansible all -i inventory.yml -m ping
If successful, the output looks something like this:
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
donkeykong | SUCCESS => {
"changed": false,
"ping": "pong"
}
supermario | SUCCESS => {
"changed": false,
"ping": "pong"
}
Create main.yml with a very simple task.
- name: all-hosts
hosts: all
tasks:
- name: Capture current dir
shell: pwd
register: output
- name: Display output
debug: msg='{{ output.stdout }}'
Run the playbook.
ansible-playbook main.yml
If successful, the output looks something like this:
PLAY [all-hosts] *******************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]
ok: [donkeykong]
ok: [supermario]
TASK [Capture current dir] *********************************************************************************************
changed: [localhost]
changed: [donkeykong]
changed: [supermario]
TASK [Display output] **************************************************************************************************
ok: [localhost] => {
"msg": "/Users/user/myshittycode"
}
ok: [donkeykong] => {
"msg": "/Users/user"
}
ok: [supermario] => {
"msg": "/Users/user"
}
PLAY RECAP *************************************************************************************************************
donkeykong : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
supermario : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Controlling the Hosts
Sometimes, you want finer controls on what tasks to be ran in certain hosts.
To run in just one host (ex: donkeykong):
- name: one-host
hosts: donkeykong
tasks:
- ...
To run in all remote hosts except localhost:
- name: all-hosts-except-localhost
hosts: all:!localhost
tasks:
- ...
Leave a Reply