Configure managed nodes with Ansible

Post date: Jan 15, 2017 6:20:52 AM

Prerequisite

Install Ansible in CentOS 7

Log in to your Ansible control machine.

Install the EPEL repository, and install sshpass:

sudo yum install epel-release

sudo yum --enabledrepo=epel -y install sshpass

Create SSH key for current user

Use ssh-keygen to create a 2048-bit RSA key pair:

ssh-keygen -C "$USER@$HOSTNAME"

Press Enter to accept the default location.

Enter a passphrase when prompted.

Install passlib for Python

If not already loaded, start the Ansible virtualenv:

source ansible/bin/activate

cd ansible

Install the Python password library

sudo pip install passlib

A playbook for configuring ansible user

Edit a new playbook:

vi create-ansible-user.yml

Type out the playbook and save it:

---

# Create user

- hosts: all

vars:

PUBLIC_KEY_FILE: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa.pub"

vars_prompt:

- name: "ANSIBLE_USER_PASSWORD"

prompt: "Password for ansible user"

private: yes

encrypt: "sha512_crypt"

confirm: yes

no_log: true

remote_user: root

tasks:

- name: "Create ansible user"

user: name=ansible

password={{ ANSIBLE_USER_PASSWORD }}

shell=/bin/bash

groups=wheel

- name: "Add remote authorized key"

authorized_key: user=ansible key="{{ lookup('file', PUBLIC_KEY_FILE) }}"

  • hosts specifies the hosts or groups from the Ansible hosts file it will run on (i.e. all).

  • vars creates variables to reference later in the playbook.

    • "{{ lookup('env', 'HOME' }} was used to insert $HOME into the assignment

  • vars_prompt assigns user input to a variable.

    • private: yes prevents the input from being echoed in the terminal

    • encrypt: sha512_crypt converts it into a password hash.

    • no_log: true keeps the value out of ansible.log

  • remote_user specifies which credentials will be used to run the task on the remote host.

  • tasks defines the actions that will be performed on the remote host, with pre-defined Ansible functions.

    • user creates a user, if it doesn't exist already

    • authorized_key updates the authorized_key file, if needed

      • "{{ lookup('file', PUBLIC_KEY_FILE) }}" specifies the contents of PUBLIC_KEY_FILE to be used as the public key for authorized_key

Run the playbook

Run the playbook, with an option to prompt for the password of remote_user:

ansible-playbook --ask-pass create-ansible-user.yml

The ansible-playbook command will run create-ansible-user.yml, checking if tasks need to be run, and making changes if so.

You will be prompted for the password to use for the ansible user. You will need this password when running playbooks that become root.

You will also be prompted to enter the root password for the managed node; this playbook adds ansible user to the wheel group, so future playbooks only ask for the ansible user password.

Last, you will be prompted for the SSH pass-phrase. You can use ssh-agent to keep the pass-phrase in memory.

Example playbook to install Minecraft server

Edit a new playbook:

vi install-minecraft-server.yml

Type out the playbook and save it:

---

- hosts: minecraft

vars_prompt:

- name: "MINECRAFT_USER_PASSWORD"

prompt: "Password for minecraft Linux user"

private: yes

encrypt: "sha512_crypt"

confirm: yes

no_log: true

remote_user: ansible

become: yes

tasks:

- name: "Install latest OpenJDK 1.8.0"

yum:

name: java-1.8.0-openjdk-headless

state: latest

- name: "Create Linux user for minecraft"

user:

name: minecraft

password: "{{ MINECRAFT_USER_PASSWORD }}"

shell: /bin/bash

- name: "Create minecraft directory"

become_user: minecraft

file:

path: ~/minecraft

state: directory

- name: "Download Minecraft 1.11.2 Server"

become_user: minecraft

get_url:

url: https://s3.amazonaws.com/Minecraft.Download/versions/1.11.2/minecraft_server.1.11.2.jar

dest: ~/minecraft/minecraft_server.1.11.2.jar

    • remote_user: ansible tells Ansible to connect as the ansible user we created earlier

    • become: yes will try to run the tasks as root, using sudo

    • yum: installs a package. dnf could be used instead.

      • name specifies which package to install

    • become_user: minecraft tells Ansible to run the task as the minecraft user

    • file: can perform different file operations, in this case creating a directory if it doesn't exist

      • path: specifies the file name

    • get_url: downloads a file from HTTP, HTTPS, or FTP

      • url: specifies the Internet address

      • dest: specifies the downloaded file name. Subdirectories are not created automatically.

Run the playbook, prompting for the sudo password. This is the password of the remote user "ansible":

ansible-playbook --ask-become-pass install-minecraft-server.yml

What to learn next

The ansible-vault command can store passwords and other secrets, to avoid prompts.

Use roles to re-use smaller playbooks.