Quick Setup Guide: Ansible

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

Leave a Reply

Your email address will not be published. Required fields are marked *