Ansible: Difference between revisions
From charlesreid1
| Line 141: | Line 141: | ||
To specify default values for SSH key, username, and inventory filename, use this config file: | To specify default values for SSH key, username, and inventory filename, use this config file: | ||
'''ansible.cfg:''' | '''<code>ansible.cfg</code>:''' | ||
<pre> | <pre> | ||
| Line 149: | Line 149: | ||
private_key_file = .vagrant/machines/default/virtualbox/private_key | private_key_file = .vagrant/machines/default/virtualbox/private_key | ||
host_key_checking = False | host_key_checking = False | ||
</pre> | |||
Now we can also simplify the hosts file: | |||
'''<code>playbooks/hosts</code>:''' | |||
<pre> | |||
myvagrantbox ansible_host=127.0.0.1 ansible_port=2222 | |||
</pre> | |||
Because the hosts file is already specified as the inventory file, we don't have to use the -i flag: | |||
<pre> | |||
$ ansible myvagrantbox -m ping | |||
</pre> | |||
===Executing arbitrary commands=== | |||
We have already seen the <code>-m</code> flag used with ansible to specify an ansible module. This is a command or set of commands or a script that is run on the vagrant machine(s) that we specify. | |||
We can use the <code>command</code> module to run arbitrary commands on the vagrant machines that ansible is managing. | |||
To run the uptime command on our vagrant box: | |||
<pre> | |||
$ ansible myvagrantbox -m command -a uptime | |||
</pre> | |||
Results in: | |||
<pre> | |||
testserver | success | rc=0 >> | |||
17:14:07 up 1:16, 1 user, load average: 0.16, 0.05, 0.04 | |||
</pre> | |||
Note that '''this is actually the default module'''!!! So we don't need to specify <code>-m command</code>, that is the default value: | |||
<pre> | |||
$ ansible testserver -a uptime | |||
</pre> | |||
If the command has spaces in it, use quotes: | |||
<pre> | |||
$ ansible testserver -a "tail /var/log/dmesg" | |||
</pre> | </pre> | ||
Revision as of 02:34, 5 November 2018
Notes
Ansible can be thought of as a for-loop over SSH scripts, but it's also much more than that.
Basic Features
Ansible config management scripts (playbooks) are in YAML. This is like executable documentation - kind of like a readme containing all the commands you would otherwise be running, all typed out, except instructions won't go out of date because they're actually being executed.
Ansible servers require SSH and Python.
Push Based
Ansible is push-based, which means the workflow looks like this:
- You make a change to the playbook
- You run the new playbook
- Ansible connects to servers and executes modules, changing the server state
The ansible-playbook command is the gateway to connecting to the remote server.
The push-based approach means you control when things happen to the server, making scaling easier.
Scaling Down, Too
Ansible obeys Alan Kay’s maxim: “Simple things should be simple; complex things should be possible.”
Modules
Ansible allows you to execute arbitrary shell commands.
Ansible also offers more powerful feature: modules, which perform tasks like installing packages restarting services, or copying config files.
Modules are declarative: describe/declare the state you want the server to be in. Example: invoke the user module to ensure there is an account named "deploy" that is in the group "web"
user: name=deploy group=web
Ansible is idempotent - meaning, if the user already exists, it will do nothing. This makes it safe to run the Ansible script multiple times.
What You Should Know
List of things you should know how to do before getting started:
- connect to remote machine via SSH
- interact with bash command line shell (pipes and redirects)
- install packages
- use sudo command
- check and set file permissions
- start/stop services
- set env vars
- write scripts (any language)
Ansible also uses uses YAML and Jinja and is Python-based.
Directory Structure
The basic directory structure we'll use with Ansible is to create a playbooks directory to hold everything:
playbooks/
.vagrant/ <-- directory used by vagrant for keys/machines
hosts <-- ansible inventory file
Using Ansible Locally with Vagrant
Vagrant allows you to set up virtual machine(s) using VirtualBox, which can give you a way of testing Ansible scripts locally (without using the AWS or Google Cloud platforms). You can then connect Ansible with vagrant to manage and set up compute nodes using Ansible.
Before you begin: set up vagrant box
See the Basic Startup and Shutdown Procedure section of the Vagrant page for steps to set up a Vagrant box, connect to it via SSH, and (when we're done) shut down the box.
Connect Ansible to Vagrant
Once we start up a Vagrant box, we can get Ansible working with the Vagrant boxes by telling Ansible about how to connect to the machines that Vagrant created.
To do this, we create an inventory file in playbooks/hosts. Recall from the Vagrant page that Vagrant started a Ubuntu server, which was available via IP address 127.0.0.1 on port 2222 (see output of vagrant ssh-config from Connect to Vagrant Machine section). We were able to SSH to the machine both using the vagrant ssh command, and a plain ssh command that used the private key in the .vagrant directory.
These details should all be passed to Ansible via the inventory file:
$ cat playbooks/hosts myvagrantbox ansible_host=127.0.0.1 ansible_port=2222 ansible_user=vagrant ansible_private_key_file=.vagrant/machines/default/virtualbox/private_key
(Note that the private key file is shown when you run vagrant ssh-config with the vagrant box running.)
Side note: once you are ready to run with an AWS EC2 node, you would specify the hostname of the EC2 node and the AWS .pem private key, like so:
$ cat playbooks/hosts myamazonbox ansible_host=ec2-203-0-113-120.compute-1.amazonaws.com ansible_user=ubuntu ansible_private_key_file=/path/to/keyfile.pem
Your vagrant boxes should be up and running with the vagrant up command.
Ping Vagrant box
Now connect to the machine and test that it is up. Pass the -i flag and the name of the inventory file, and -m and the name of the module you want to run. We'll run the ping module:
$ ansible myvagrantbox -i hosts -m ping
You should see some output like this:
myvagrantbox | success >> {
"changed": false,
"ping": "pong"
}
If it did not succeed, re-run with the -vvvv flag for max verbosity to help debug the issue.
This is a basic vagrant script (module) that just runs a ping test; if the server on the other end responds, it results in a pong. The "'changed': false" indicates that Ansible is not changing the state of the machine.
Use a config file
The inventory file (hosts) required lots of details, and if we have many nodes to deal with that is not going to scale well.
To make it easier to deal with, we can use the ansible.cfg file to set some defaults and variables.
Where to put ansible.cfg? Here is where Ansible looks:
ANSIBLE_CONFIGenv var (specifies the config file)/ansible.cfg(current directory)~/.ansible.cfg(.ansible.cfg in your home directory/etc/ansible/ansible.cfg
A good place for it is alongside the playbooks, in the current directory.
This dir structure allows you to place the config file, plus the playbooks, under version control in a single repo.
Example config file
To specify default values for SSH key, username, and inventory filename, use this config file:
ansible.cfg:
[defaults] inventory = hosts remote_user = vagrant private_key_file = .vagrant/machines/default/virtualbox/private_key host_key_checking = False
Now we can also simplify the hosts file:
playbooks/hosts:
myvagrantbox ansible_host=127.0.0.1 ansible_port=2222
Because the hosts file is already specified as the inventory file, we don't have to use the -i flag:
$ ansible myvagrantbox -m ping
Executing arbitrary commands
We have already seen the -m flag used with ansible to specify an ansible module. This is a command or set of commands or a script that is run on the vagrant machine(s) that we specify.
We can use the command module to run arbitrary commands on the vagrant machines that ansible is managing.
To run the uptime command on our vagrant box:
$ ansible myvagrantbox -m command -a uptime
Results in:
testserver | success | rc=0 >> 17:14:07 up 1:16, 1 user, load average: 0.16, 0.05, 0.04
Note that this is actually the default module!!! So we don't need to specify -m command, that is the default value:
$ ansible testserver -a uptime
If the command has spaces in it, use quotes:
$ ansible testserver -a "tail /var/log/dmesg"