Ansible is an automation engine that allows for agentless system config and deployment. Ansible operates over SSH and runs Ansible modules on remote systems to complete tasks.
- Ansible setup
- Ansible configuration
- Understanding ansible ad hoc
- File manipulation with ansible
- Configuring system users and groups
- Installing software and daemon management
- Advanced features
- Conclusion
- Examples
sudo yum install epel-release
sudo yum update && sudo yum install ansible
# Add devices you'll access to /etc/ansible/hosts
sudo vim /etc/ansible/hosts
# Best practice is to create an ansible user in every host in
# the environment so you can authenticate with the same user
# from src to destination.
# CentOs
sudo useradd ansible && sudo passwd ansible
su - ansible
# Ubuntu (prompts for pw)
adduser ansible
su - ansible
# The command below tests connectivity with the ping module (-m)
# and prompts for password (-k)
ansible localhost -m ping -k
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
- Goal is to have a single common user across all hosts.
It's strongly recommended that you set up login via SSH keys so you don't have to type passwords.
ssh-keygen
ssh-copy-id centos2.jm
Give ansible sudo access
sudo visudo
# Once in the file, search for "without a password"
# And add the ansible line below the wheel line
# Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
ansible ALL=(ALL) NOPASSWD: ALL
sudo vim /etc/ansible/ansible.cfg
- There's a section called "some basic default values," which you won't likely change starting out.
- The
ansible-config
command takes some arguments that allow you to display the running config, all configs, etc. Check outman ansible-config
. This utility is avaiable as of ansible 2.4 - The config properties may be overridden using local files. The first configuration file is used and other files are ignored. Order:
- ANSIBLE_CONFIG env variable if set
- ansible.cfg in working directory
- ~/ansible.cfg
- /etc/ansible/ansible.cfg
-
The inventory is a list of hosts that ansible manages.
-
The default location is /etc/ansible/hosts
- You can specify the inventory via
ansible -i $file_name
E.g.,ansible -i inventory localhost -m ping
- You can also set the inventory in ansible.cfg
- You can specify the inventory via
-
The default file has a lot of examples of what you can do.
-
You can create groups of hosts and specify hosts by name or IP address.
-
You can use a pattern such as
www[01:06].example.com
for ansible to expand out# Example groups [ny] ny-rt1.example.com ny-rt2.example.com ny-sw1.example.com ny-sw2.example.com [routers] ny-rt1.example.com ny-rt2.example.com
-
-
You can then execute the command by referencing a host or a group:
ansible routers -m ping
- Ansible ad hoc commands are comparable to bash commands.
- Playbooks are comparable to bash scripts
- Syntax for ad hoc command:
ansible [-i $inventory] $host [-b] -m $module -a $arg1 [$arg2...] -f $num_forks
-b
= become, which by default becomes root- Example to install software:
ansible centos2.jm -b -m yum -a "name=elinks state=installed"
- Example to remove software:
ansible centos2.jm -b -m yum -a "name=elinks state=absent"
- Modules are discrete units of code that can be used from the CLI or in a playbook task.
- Most modules take key=value arguments delimited by whitespace (there are exceptions).
- Example modules include: ping, setup, yum, service, and copy
- You can visitdocs.ansible.com and use
ctrl
+F
to search for keywords such as "Cisco IOS." - You can also use the
ansible-doc
command. E.g.,ansible-doc ping
- The shell and command modules allow you to run raw commands on a target host.
- The command module is the default with ansible ad-hoc when no module is specified. It's best practice to use this module unless you require shell features.
- The shell command is almost identical, except the commands are run in a shell environment.
- The shell module might be preferred for input/output redirection, env variables, and other shell features not supported by the command module.
- It's best to use modules that do what you need so you don't need to define success criteria for raw commands.
- The script module allows you to run entire shell scripts rather than single commands.
# Example command
ansible localhost -a "touch /tmp/test1"
# Same command, but skips if file exists
ansible localhost -a "touch /tmp/test1 creates=/tmp/test1"
# Delete the file
ansible localhost -a "rm -f /tmp/test1 removes=/tmp/test1"
# Shell module for env variable and output redirection
ansible localhost -m shell -a "echo $PATH > /tmp/file1"
- Ansible facts are properties and info about remote systems.
- The setup module can retrieve facts.
- Facts may be filtered using the setup module ad-hoc by passing a value for the
filter
param. - Examples:
ansible centos2.jm -m setup | less -MN
- Filtered:
ansible centos2.jm -m setup -a "filter=*dist*" | less -MN
- Create a JSON file per host in "facts" folder:
ansible centos -m setup --tree facts
- The file module can be used to create, delete, and modify file properties.
- Check out
ansible-doc file
for parameters you can set, including permissions, owner, mod time, etc.
- Check out
- The copy module can be used to copy files from the control to the target node or from the file system on the target node.
src
= location on control noderemote_src
= location on destination node
Examples
# Create a file. Default location will be home
ansible centos -m file -a "name=testfile state=touch"
# Become root to create a file in a protected location
ansible centos -b -m file -a "name=/root/testfile state=touch"
# Delete the file
ansible centos -b -m file -a "name=/root/testfile state=absent"
# File copy example
ansible centos -m copy -a "src=testile dest=newfile"
- The lineinfile module allows us to insert a line of text into a file. It can also remove lines of text.
- The default is to add the line to the end of the file, but you can place it before or after matched text.
- If the module detects the line in the file already, it will not add it again.
- Some arguments
create=yes
: Create if !existsinsertafter
: Insert after last match specifiedinsertbefore
: Insert before last match specifiedregexp
: Replace the matched expression with the line. Cannot be used withinsertafter
norinsertbefore
- NOTE: There is a replace module that can make more granular changes using regex, replacing all occurences of a file.
Examples
# If you run the insert commands twice in a row, the second time will report
# SUCCESS and changed: false
ansible centos -m lineinfile -a "path=/home/ansible/testfile line='I am the walrus.' state=present create=yes"
ansible centos -m lineinfile -a "line='I am before the walrus' path=/home/ansible/testfile insertbefore='walrus'"
- The get_url module allows you to download files via HTTP, HTTPS, and FTP. the destination must be an absolute path.
- Basic and x509 authentication are supported.
- Can perform checksum verification.
- Supports proxy network access.
ansible-doc get_url
Examples
ansible centos -m get_url -a "url=http://google.com dest=/home/ansible/google.html"
- The archive and unarchive modules can work with various types of file archives (tar, gunzip (default), and zip).
Example
ansible centos -m lineinfile -a "line='test text for file 3' path=/home/ansible/file3 create=yes"
ansible centos -m archive -a "path=/home/ansible/file3 format=zip dest=/tmp/file3.zip"
ansible centos -m unarchive -a "remote_src=yes src=/tmp/file3.zip dest=/tmp"
- The user module can be used to create, remove, and modify users.
- If you remove a user but don't use the
remove=yes
argument, the user will be removed from /etc/passwd but other artifacts (such as home directory) will remain. - Args:
append
: add user to specified groupsgenerate_ssh_key
: duhname
: user namestate
:absent
to remove andpresent
to create (default)
Examples
ansible centos -b -m user -a "name=thedude"
ansible centos -b -m user -a "name=thedude state=absent remove=yes"
- Similar to user module
Examples
ansible centos -b -m group -a "name=consultants"
ansible centos -b -m user -a "name=thedude group=consultants"
# You wouldn't be able to delete the group while it's the primary group of thedude
ansible centos -b -m user -a "name=thedude group=ansible"
ansible centos -b -m group -a "name=consultants state=absent"
- Depending on the distro, you can use
package
,yum
, andapt
.package
: will detect which package manager to use. Best practice for mixed distro environment.
- Ansible cannot handle when packages aren't named the same (e.g.,
apache2
for Ubuntu vshttpd
for CentOS).
Examples
ansible centos -b -m package -a "name=ntpdate state=latest"
- The service module is compatible with systemd and the older BSD init style of daemon management.
Example
ansible -b -m service -a "name=httpd state=started enabled=yes"
-B
is used to provide a timeout value for Ansible to consider the task failed if it exceeds that value.-P
allows you to poll the operation on a set interval.- The status may be checked with the async_status module (with playbooks, not ad hoc).
Examples
# timeout of 15 seconds
ansible centos -a "/home/ansible/sleep.sh" -B 15
# Polling interval should be < timeout interval
ansible centos -a "/home/ansible/sleep.sh" -B 60 -P 20
- Ansible uses forks to execute tasks in parallel.
- Each fork is able to run a task against a target host.
- The default is to execute five forks.
- E.g., one command against 5 hosts results in near simultaneous execution on all hosts. If over five hosts are targetted, a fork must be freed for host six.
- The number of forks used by Ansible may be configured in ansible.cfg or with the
-f
or--forks
flag. - More forks = more resources required on control node.
- Check out the Ansible Playbooks Deep Dive course, part 2 of this course.
- There's also Git, and DevOps training in general.
# Create the user accounts noted in /home/ansible/userlist.txt.
ansible dbsystems -b -m user -a "name=consultant"
ansible dbsystems -b -m user -a "name=supervisor"
# Create the directory for the authorized keys
ansible dbsystems -b -m file -a "path=/home/consultant/.ssh state=directory owner=consultant group=consultant mode=0755"
ansible dbsystems -b -m file -a "path=/home/supervisor/.ssh state=directory owner=supervisor group=supervisor mode=0755"
# Copy the authorized_keys file from control node to target nodes
ansible dbsystems -b -m copy -a "src=/home/ansible/keys/consultant/authorized_keys dest=/home/consultant/.ssh owner=consultant group=consultant mode=0600"
ansible dbsystems -b -m copy -a "src=/home/ansible/keys/supervisor/authorized_keys dest=/home/supervisor/.ssh owner=supervisor group=supervisor mode=0600"
# Ensure auditd is enabled and running on all systems.
ansible dbsystems -b -m service -a "name=auditd state=started enabled=yes"