Configure managed nodes with Ansible
Post date: Jan 15, 2017 6:20:52 AM
Prerequisite
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.