Ansible
This is about ansible standalone, you could also run this via vagrant (provision), see vagrant doc for that. This can also be done with python itself. That actually gives you much more control but of course less pre-cooked installation tasks. See the lang repository for a complete install script using python only.
installation
osx installation
Since there are plenty of problems occurring in various versions it would be easy to switch between versions rather quickly. Therefore installation with pip looks like the easiest way. Also install yolk to see which versions are available:
if you get this error while running yolk :
yolk -l
...
UnicodeEncodeError: 'ascii' codec can't encode character u'u2014' in position 1189: ordinal not in range(128)
It seems to be a bug, upgrading yolk might help :
The last command will show something like :
ansible 2.1.0.0
ansible 2.0.2.0
ansible 2.0.1.0
ansible 2.0.0.2
ansible 2.0.0.1
ansible 1.9.6
ansible 1.9.5
ansible 1.9.4
Sadly at the time of writing yolk crashed on execution, but you could get a similar list if you invoke pip with a non-existent version of the package you want :
sudo pip install ansible==3.0
Collecting ansible==4.0
Could not find a version that satisfies the requirement ansible==4.0 (from versions: 1.0, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.9.0.1, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 2.0.0.0, 2.0.0.1, 2.0.0.2, 2.0.1.0, 2.0.2.0, 2.1.0.0, 2.1.1.0, 2.1.2.0, 2.1.3.0, 2.1.4.0, 2.1.5.0, 2.2.0.0, 2.2.1.0, 2.2.2.0)
No matching distribution found for ansible==4.0
So take you pick.. AND skip 2.2.0.0 , it does not work correctly.
setup ssh key
The simplest way ?
It will fix all details for you, create ~/.ssh/authorized_keys with the right(s) and it can cross-install keys, so you can install the key of yourself as root on the other machine. So :
kees@localhost> ssh-copy-id root@server
...
kees@localhost> ssh root@server
root@server>
yaml
The base language used : see http://www.yaml.org/spec/1.2/spec.html
The yaml syntax is quite simple, here is a quick cheatsheet found here http://cheat.readthedocs.io/en/latest/yaml.html
A value:
value named "foo":
List:
A list named "bar":
Alternative list syntax ("Flow style"):
Dictionary:
A dictionary named "joe":
Dictionary in flow style:
A list of dictionaries:
inventory
Also known as hosts file, it is advertised to be /etc/ansible/hosts, but on my mac it just can't find that, so use the -i option. It contains the ip's of all hosts you added with ssh-copy-id above.
You can add a line to the ansible.cfg file to run without -i hosts. I added some more useful directives as well :
role_path = ../../:roles #take dev roles before current directory
inventory = hosts
retry_files_enabled = False # do NOT make a playbook.retry
debugging
Some tricks to use when debugging ansible scripts.
dumping the Facts
A very neat one, also to see if you might want to use some variables there:
Or any host instead of all, it will dump the complete Facts db so better redirect it into some file.
debug messages
These can be used throughout the playbooks and roles, simply to display a message or dump a variable, this next example gets the result of a shell command and displays it :
- shell: grep nameserver /etc/resolv.conf | wc -l
register: resolv_conf_filled
- debug: var=resolv_conf_filled
output (when resolv.conf is empty)
TASK: [common | debug var=resolv_conf_filled] *********************************
ok: [10.10.7.23] => {
"resolv_conf_filled": {
"changed": true,
"cmd": "grep nameserver /etc/resolv.conf | wc -l",
"delta": "0:00:00.005865",
"end": "2015-02-26 09:19:03.848714",
"invocation": {
"module_args": "grep nameserver /etc/resolv.conf | wc -l",
"module_name": "shell"
},
"rc": 0,
"start": "2015-02-26 09:19:03.842849",
"stderr": "grep: /etc/resolv.conf: No such file or directory",
"stdout": "0",
"stdout_lines": [ "0" ],
"warnings": []
}
}
You could also shorten it to :
keeping the scripts on the target
To keep the command files that ansible creates on the remote host, set this environment variable:
The files will be places in /root/.ansible/tmp, and you can view what is attempted to execute. Also use -vvvv option of ansible-playbook to see which files are created.
speed up development playbooks
Mostly the scripts at RINIS require double login for each run: one for the user and one for the vault. At least one of these can be skipped when developing. We use vagrant to create the base VM's so we can use the insecure_private_key it uses by setting insert_key off :
If this setting is true (the default) vagrant will try to replace the insecure_private_key with a less insecure one and use that for login. That's exactly what we don't want, so set it to false.
The key is normally stored in your home directory : ~/.vagrant.d/insecure_private_key To use it ansible use this section in you playbook :
This will cause ansible to login as vagrant and after that become root (don't forget become or you will just stay 'vagrant' !)
Now you could run with the --private-key option :
ansible-playbook Rinis_Bootstrap.yml --private-key=~/.vagrant.d/insecure_private_key --extra-vars="target=vbox"
But that's actually more typing than the password, so place it in ansible.cfg :
detecting system
Sometimes you want to know what system you are running on, for instance detecting if this is a VM or a real machine. You can use this command to get some info about your system.
On my workstation this says :
On a Virtualbox VM it will say :
Innotek was probably the creator of VirtualBox since it was acquired in 2008 by SUN Microsystems which in turn was acquired by Oracle in 2010. To test these values with ansible you need the variable "ansible_system_vendor" for instance look for it in the output of :
Shell vs. Command
A typical example are the Ansible modules Shell and Command. In the most use cases both modules lead to the same goal. Here are the main differences between these modules.
- With the Command module the command will be executed without being proceeded through a shell. As a consequence some variables like $HOME are not available. And also stream operations like <, >, | and & will not work.
- The Shell module runs a command through a shell, by default /bin/sh. This can be changed with the option executable. Piping and redirection are here therefor available.
- The command module is more secure, because it will not be affected by the user's environment.