This is a quick setup guide for a basic ansible server configuration and setting up and adding a host to run playbooks against. This is based on Ubuntu 23.10 however it should be fairly universal other than the package manager used.
Setting up the Ansible Server
Update the system
On the server you will be running ansible from, log in and fully update the system.
sudo apt update -y && sudo apt upgrade -y
Reboot the system (probably not required).
sudo reboot now
Install Python/Ansible packages
Install pipx so that you can install ansible through python packages instead of the Ubuntu repository.
The Ubuntu Repository uses an older version of ansible.
sudo apt install pipx -y
Install ansible using pipx.pipx install --include-deps ansible
Log out and back in so that you can run the ansible binaries that were loaded.
Create a SSH key with no passphrase
Create an SSH key, name it ansible (or whatever you would like)
moving forward this guide will assume the Public and private key will be called ansible and ansible.pub.
Do not create a passphrase for the key. This will be used for automatically running ansible playbooks without confirmation.
There will be a second SSH skey with a passphrase to use later in the host setup stage of this guide.
ssh-keygen -t ed25519
When it asks to enter file in which to save the key use
/home/<your user>/.ssh/ansible
ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/<user>/.ssh/id_ed25519): /home/<user>/.ssh/ansible
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/<user>/.ssh/ansible
Your public key has been saved in /home/<user>/.ssh/ansible.pub
The key fingerprint is:
SHA256:QzQiH8Ky2SGBrUwRPNaVfuS2iGTRsCrGqTVR4A3orpE <user>@ansible
The key's randomart image is:
+--[ED25519 256]--+
|.*B=B.+ o |
|o*+*+* = . |
| =.+B+.+ . |
| o.=+.. = |
|o* = . - S |
|Eo o . . . |
|o. .. |
|. |
| |
+----[SHA256]-----+
Verify the public and private keys are created in the proper location.
Private keys have no file extension.
Public keys have the .pub extension.
<user>@ansible:~/ansible$ ls -alh ~/.ssh/
total 16K
drwx------ 2 <user><group>4.0K Jan 27 04:08 .
drwxr-x--- 7 <user><group>4.0K Jan 27 03:54 ..
-rw------- 1 <user><group>399 Jan 27 04:08 ansible
-rw-r--r-- 1 <user><group>95 Jan 27 04:08 ansible.pub
-rw------- 1 <user><group>0 Jan 27 02:05 authorized_keys
Create a SSH key WITH passphrase
To be able to initiate the first connection and run the playbook that will allow automation,
we need to add another ssh key that can be passed manually to the new hosts.
This is not fully necessary to the process; I do however like to have the separate keys.
This passkey WILL include a passphrase to make it a bit more secure.
I am calling this one “<user>” because that is my username.
The SSH key that requires a passphrase will be <user>in this document moving forward.
<user>@ansible:~/ansible$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/<user>/.ssh/id_ed25519): /home/<user>/.ssh/<user>
Enter passphrase (empty for no passphrase): <passphrase>
Enter same passphrase again: <passphrase>
Your identification has been saved in /home/<user>/.ssh/<user>
Your public key has been saved in /home/<user>/.ssh/<user>.pub
The key fingerprint is:
SHA256:MKUqVDgTVU2NBO42U+vxKUgNcYI3QD/Sl5IG156BgKk <user>@ansible
The key's randomart image is:
+--[ED25519 256]--+
| .+o=B*=++.. |
| o+.B+.o* |
| .+ *.Oo. |
| .E + =o*. |
| . . S o.. . |
| . . + o o |
| . . o |
| |
| |
+----[SHA256]-----+
Now you can verify both private and public keys exist.
<user>@ansible:~/ansible$ ls -alh ~/.ssh/
total 32K
drwx------ 2 <user><group> 4.0K Jan 27 05:32 .
drwxr-x--- 7 <user><group> 4.0K Jan 27 05:49 ..
-rw------- 1 <user><group> 399 Jan 27 04:08 ansible
-rw-r--r-- 1 <user><group> 95 Jan 27 04:08 ansible.pub
-rw------- 1 <user> <group> 0 Jan 27 02:05 authorized_keys
-rw------- 1 <user><group> 444 Jan 27 05:30 <user>
-rw-r--r-- 1 <user><group> 95 Jan 27 05:30 <user>.pub
-rw------- 1 <user><group> 2.0K Jan 27 04:39 known_hosts
Create the file structure
mkdir -p ansible/files
Move into the ansible directory.cd ansible
Create an Inventory file
The inventory file is a list of all of the hosts that the ansible playbooks will target.
Create the file named “inventory” and insert the IP of any systems you will manage.
Inventory can be split into different sections with brackets [ ] as shown. The list could be as simple as a single IP address. The example used is for a group of several servers with different roles.
vim inventory
[servers]
10.10.10.13
10.10.10.14
[workstations]
10.10.10.15
[webservers]
10.10.10.16
10.10.10.17
[database servers]
10.10.10.18
10.10.10.19
Create the ansible config file
Create an ansible.cfg file and insert the following.
This will tell ansible to use the inventory file created, the user we will create, and the ssh key we created.
We are adding the location of the “ansible” ssh key. If following this guide the location and name shown should be correct in this example. If not you will need to change the name and or location in the “private_key_file” field below.
vim ansible.cfg
[defaults]
inventory = inventory
private_key_file = ~/.ssh/ansible
remote_user = ansible
Create the sudoer_ansible file
Create a file called “sudoer_ansible” in the ./ansible/files directory.
This file will be moved to the managed hosts to allow the new user “ansible” that will be created to run with sudo privileges without a password.
vim files/sudoer_ansible
ansible ALL=(ALL) NOPASSWD: ALL
Create the bootsrap.yml file
The first playbook we will create will be bootstrap.yml.
This playbook will set new hosts up to accept playbooks without any input in the future.
Each play is described here:
1. Create a user named “ansible”.
2. Add the SSH key with no a passphrase to ansible to login without a prompt.
3. Add the sudoer_ansible file to the sudoer folder, and set the permissions.
For SSH key you will need to cat the ansible.pub ssh key and copy the key.
Save that and paste the key into the “Add ssh key for ansible user” section below.
cat ../.ssh/ansible.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NKDUBBBK43NhNAU5Q0MQ1rIy+hZTtMackJbQPXysI9d7sbhugk/H <user>@ansible
*For some reason when I created this document if I paste the text in, I had to cat the file, copy the text from the Linux host, then remove the file, and create the file again and paste from the text copied from the Linux console.
Include the first line “—” all the way to the bottom.
vim bootstrap.yml
---
- hosts: all
become: true
tasks:
- name: create ansible user
user:
name: ansible
groups: root
- name: Add ssh key for ansible user
tags: always
authorized_key:
user: ansible
key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINNhNAU5Q0MQ1rIy+hZTtMackJbQPXysI9d7molnzm/H chris@ansible"
- name: Add sudoers file for ansible user
copy:
src: sudoer_ansible
dest: /etc/sudoers.d/ansible
owner: root
group: root
mode: 0440
Create you first update.yml file
Create a file to update any Ubuntu and CentOS systems in the inventory.
*For some reason when I created this document
if I copy from here and paste the text in, I had to cat the file, copy the text from the Linux console,
Then remove the file and create the file again and paste from the text copied from the Linux console.
vim update.yml
---
- hosts: all
become: true
pre_tasks:
- name: Install updates for CentOS
dnf:
update_only: yes
update_cache: yes
when: ansible_distribution == "CentOS"
- name: Install updates for Ubuntu
apt:
upgrade: dist
update_cache: yes
when: ansible_distribution == "Ubuntu"
Setting up a new host to accept ansible connections
Add the new host(s) to the inventory.yml file
Add the new host into the inventory.yml file If you did not do this in the steps above.
If there are sections [like this] put it in the most appropriate place.
IP will work, or hostname if DNS is set up.
vim inventory
[servers]
10.10.10.13
10.10.10.14
[workstations]
10.10.10.15
[webservers]
10.10.10.16
10.10.10.17
[database servers]
10.10.10.18
10.10.10.19
SSH to the new host
SSH from the ansible server to the new host you will want to manage.
This is required so you can accept the host key initially.
you can exit right after you ssh in.
ssh [email protected]
(type yes to accept the connection)
exit the connection with the “exit” command.
exit
Copy the SSH key WITH passcode to the host
Use the ssh-copy-id command to SSH key file (that does require a passphrase) to the host to be set up.
ssh-copy-id -i ~/.ssh/<user>.pub 10.10.10.13
Run the bootstrap playbook
Now run the bootstrap.yml and target the new host.
Specify the keyfile for your key WITH passphrase that you sent to your new server.
Specify the username you can log in with on your server (one that has sudo privileges).
For this one you should get asked the user password (for root privilege) and the passphrase for your ssh key.
ansible-playbook bootstrap.yml --key-file ~/.ssh/<user> -u <user> --ask-become-pass --limit 10.10.10.13
You will be prompted first for the “BECOME password” this is the root password.BECOME password:
You will be prompted for you passphrase for the SSH key.Enter passphrase for key '/home/<user>/.ssh/<user>':
There are times that this will fail because it does not accept the passphrase the first time.
I’m not sure why this happens, but if it does fail, try a few times and hit enter a few times after entering the passphrase.
The –limit <IP/HOST> option does require that the host specified be added to the inventory file.
The –ask-become-pass option is to request to become root on the target system when the playbook is running its commands.
The –key-file option is specifying which SSH key you want to use. We used <user> here because that is the key we sent to this host in the previous stop.
Run the update playbook
To verify password less root and ssh keys were placed correctly run the update playbook without any other options.
This will run on all of the hosts in the inventory.
If you want to just run it on your new host, use the –limit flag the same as before.
ansible-playbook update.yml
Or limit the command to the specific server.
ansible-playbook update.yml --limit 10.10.10.13
If successful you should see “ok” for that server, or “changed” if an update needed to be performed.
Directory structure when complete:
ansible
├── ansible.cfg
├── bootstrap.yml
├── inventory
├── update.yml
└── files
└── sudoer_ansible