Difference between revisions of "Ansible"

From Freephile Wiki
Jump to navigation Jump to search
(update best practices)
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[wp:Ansible_(software)]]  is an open-source software platform for configuring and managing computers. It combines multi-node software deployment, ad hoc task execution, and configuration management.  Written in Python, it is packaged by [[RedHat]].  As of July 2016, we're using Ansible 2.2.0
 
[[wp:Ansible_(software)]]  is an open-source software platform for configuring and managing computers. It combines multi-node software deployment, ad hoc task execution, and configuration management.  Written in Python, it is packaged by [[RedHat]].  As of July 2016, we're using Ansible 2.2.0
  
== Installation ==
 
The preferred way to [http://docs.ansible.com/intro_installation.html install] is to just <code>git clone</code> the source.  Having the source makes it easy to upgrade, and it's self-contained, plus best of all you get all the examples and contribs. 
 
  
<source lang="bash">
+
{{ambox|
cd
+
|text=A lot of this page is outdated.
mkdir ~/bin
+
 
cd bin
+
We're working on it [[User:Admin|freephile]] ([[User talk:Admin|talk]]) 08:36, 14 August 2024 (EDT)}}
git clone git://github.com/ansible/ansible.git --recursive
+
 
cd ./ansible
+
 
source ./hacking/env-setup
+
Also, RedHat seems to have purposely made things very convoluted in terms of versioning, release cycles and product naming. So check https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html and see if you can figure it out. <ref>In 2024 people are still '''[https://www.reddit.com/r/ansible/comments/1chyjdc/confused_about_ansible_documentation_and_versions/ Confused about Ansible documentation and versions]''' It's rather ridiculous that their ansible-core project does NOT use SemVer</ref>
</source>
+
 
 +
==Installation==
 +
 
 +
Historical note: it used to be that you'd just <code>git clone</code> the source. And then <code>source</code> the env-setup script. <ref>Having the source makes it easy to upgrade, and it's self-contained, plus best of all you get all the examples and contribs.</ref>
  
If you see this error message:
+
Fast-forward a decade and you'll need to figure out the correct path for your situation. https://docs.ansible.com/ansible/latest/installation_guide/index.html
<pre>
 
Traceback (most recent call last):
 
  File "/usr/local/bin/ansible-playbook", line 44, in <module>
 
    import ansible.constants as C
 
ImportError: No module named ansible.constants
 
</pre>
 
Be sure to source the env-setup script
 
  
== Getting Started ==
+
==Getting Started==
 
You must source the environment setup script to begin using Ansible (assuming you are running from a git checkout) <code>source ~/bin/ansible/hacking/env-setup</code>
 
You must source the environment setup script to begin using Ansible (assuming you are running from a git checkout) <code>source ~/bin/ansible/hacking/env-setup</code>
 
Ansible provides three main commands:
 
Ansible provides three main commands:
# <code>ansible-playbook</code> - to execute an Ansible playbook on the specified systems
 
# <code>ansible</code> - to execute an individual shell command or Ansible module on the specified systems
 
# <code>ansible-vault</code> - (optional) to encrypt or decrypt YAML files that Ansible uses.
 
  
=== Global Config ===
+
#<code>ansible-playbook</code> - to execute an Ansible playbook on the specified systems
 +
#<code>ansible</code> - to execute an individual shell command or Ansible module on the specified systems
 +
#<code>ansible-vault</code> - (optional) to encrypt or decrypt YAML files that Ansible uses.
 +
 
 +
===Global Config===
 
<code>export ANSIBLE_HOST_KEY_CHECKING=False</code>
 
<code>export ANSIBLE_HOST_KEY_CHECKING=False</code>
 
or set it in your ~/.ansible.cfg so that as you add new hosts it won't prompt you.
 
or set it in your ~/.ansible.cfg so that as you add new hosts it won't prompt you.
Line 35: Line 30:
 
Also [https://docs.ansible.com/ansible/intro_getting_started.html#your-first-commands use 'ssh' instead of paramiko] when doing this.
 
Also [https://docs.ansible.com/ansible/intro_getting_started.html#your-first-commands use 'ssh' instead of paramiko] when doing this.
  
=== Initialize a Project ===
+
===Initialize a Project===
'''Ansible Galaxy''' If you want to do a new project, you can use the <code>ansible-galaxy foo init</code> command which will create the directory and file structure for 'foo' in the current working directory.
+
Use '''[https://galaxy.ansible.com/ui/ Ansible Galaxy]''' If you want to do a new project, you can use the <code>ansible-galaxy foo init</code> command which will create the directory and file structure for 'foo' in the current working directory.
 +
 
 +
Also, if you want to install other Ansible Galaxy projects, you can either do it "manually" <code> ansible-galaxy install -r </code> Or, setup a 'requirements.yml' file in your playbook that then gets run by your stack. <ref>https://stackoverflow.com/questions/25230376/how-to-automatically-install-ansible-galaxy-roles</ref> <ref>Supposedly this only works for newer versions of Ansible, per the warning on their homepage:<blockquote> Warning alert:To be able to download content from galaxy it is required to have ansible-core>=2.13.9 Please, check it running the command: ansible --version</blockquote>
  
Also, if you want to install other Ansible Galaxy projects, you can either do it "manually" <code> ansible-galaxy install -r </code> Or, setup a 'requirements.yml' file in your playbook that then gets run by your stack. <ref>https://stackoverflow.com/questions/25230376/how-to-automatically-install-ansible-galaxy-roles</ref> <code>ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options]</code>
+
'''But''', it worked fine for me in the Meza 1_39 upgrade using Ansible 2.9.27
 +
</ref>  
  
== Modules ==
+
<code>ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options]</code>
 +
 
 +
==Modules==
 
Ansible comes with [https://docs.ansible.com/ansible/modules_by_category.html over 200 modules] that you should get familiar with in order to use the system effectively.
 
Ansible comes with [https://docs.ansible.com/ansible/modules_by_category.html over 200 modules] that you should get familiar with in order to use the system effectively.
  
Line 50: Line 50:
  
  
 +
==Example Commands==
 +
Note: control verbosity with <code>-vvvv</code>
  
== Example Commands ==
+
#<code>ansible --help</code> display help
Note: control verbosity with <code>-vvvv</code>
+
#<code>ansible --version</code> show version info
# <code>ansible --help</code> display help
+
#<code>ansible -c local -i ~/ansible_hosts -m ping all</code> ping all the hosts in the inventory file
# <code>ansible --version</code> show version info
+
#<code>ansible '''-m setup''' wiki.example.com</code> Use the '''[https://docs.ansible.com/ansible/latest/setup_module.html setup]''' module to gather ansible 'facts' (aka [[ansible_variables]]) about that host.
# <code>ansible -c local -i ~/ansible_hosts -m ping all</code> ping all the hosts in the inventory file
+
#<code>ansible '''localhost''' -m setup -a 'gather_subset=!all'</code> or look at the localhost
# <code>ansible '''-m setup''' wiki.example.com</code> Use the '''[https://docs.ansible.com/ansible/latest/setup_module.html setup]''' module to gather ansible 'facts' (aka [[ansible_variables]]) about that host.
+
#<code>ansible all -m setup -a '''"filter=ansible_distribution*"'''</code> use a filter action to see specific variables
# <code>ansible '''localhost''' -m setup -a 'gather_subset=!all'</code> or look at the localhost
+
#<code>ansible localhost -m setup --tree /tmp/facts</code> store all facts in a file 'tree', based on hostname
# <code>ansible all -m setup -a '''"filter=ansible_distribution*"'''</code> use a filter action to see specific variables
 
# <code>ansible localhost -m setup --tree /tmp/facts</code> store all facts in a file 'tree', based on hostname
 
 
#<code>ansible -m debug -a "var=hostvars['wiki.example.com']" localhost</code> gives you the '[[ansible hostvars]]'
 
#<code>ansible -m debug -a "var=hostvars['wiki.example.com']" localhost</code> gives you the '[[ansible hostvars]]'
# <code>ansible-playbook play1.yml play2.yml</code> Run multiple playbooks
+
#<code>ansible-playbook play1.yml play2.yml</code> Run multiple playbooks
# <code>ansible-playbook -i production webservers.yml --tags ntp '''--list-tasks'''</code> confirm what task names would be run if I ran this command and said "just ntp tasks"
+
#<code>ansible-playbook -i production webservers.yml --tags ntp '''--list-tasks'''</code> confirm what task names would be run if I ran this command and said "just ntp tasks"
# <code>ansible-playbook '''--list-tags''' launch.yml</code> see what tags exist in my playbook (the tasks list shows more detail + the tags)
+
#<code>ansible-playbook '''--list-tags''' launch.yml</code> see what tags exist in my playbook (the tasks list shows more detail + the tags)
# <code>ansible-playbook -i production webservers.yml --limit boston '''--list-hosts'''</code> confirm what hostnames might be communicated with if I said "limit to boston" <ref>Choosing which host(s) to operate on https://docs.ansible.com/ansible/intro_patterns.html</ref>
+
#<code>ansible-playbook -i production webservers.yml --limit boston '''--list-hosts'''</code> confirm what hostnames might be communicated with if I said "limit to boston" <ref>Choosing which host(s) to operate on https://docs.ansible.com/ansible/intro_patterns.html</ref>
# <code>~/bin/ansible/contrib/inventory/digital_ocean.py --list --pretty --api-token TOKEN_HERE</code> use the DO api to list your droplets (dynamic inventory)
+
#<code>~/bin/ansible/contrib/inventory/digital_ocean.py --list --pretty --api-token TOKEN_HERE</code> use the DO api to list your droplets (dynamic inventory)
# <code>ansible-playbook -vvv launch.yml -l wiki.example.com --user=root -e do_name=wiki.example.com '''--start-at-task'''='remove empty wiki schema from database if it already exists'</code> start at a particular point in the task list
+
#<code>ansible-playbook -vvv launch.yml -l wiki.example.com --user=root -e do_name=wiki.example.com '''--start-at-task'''='remove empty wiki schema from database if it already exists'</code> start at a particular point in the task list
# <code>php -r 'var_dump(json_decode(file_get_contents("/tmp/facts/localhost"), true));'</code> look at the json with php (or more interesting tools) With Ansible's Jinja2 filters, you can specify the output of a variable to be 'pretty' <nowiki>{{ some_variable | to_nice_json }}</nowiki>
+
#<code>php -r 'var_dump(json_decode(file_get_contents("/tmp/facts/localhost"), true));'</code> look at the json with php (or more interesting tools) With Ansible's Jinja2 filters, you can specify the output of a variable to be 'pretty' <nowiki>{{ some_variable | to_nice_json }}</nowiki>
  
== Variables ==
+
==Variables==
; You have 3 plays in one playbook.  Will play 3 be able to reference facts registered in play 1?:
 
: facts, yes, play vars, no
 
: vars associated to the host, persist, vars defined in the play, do not, set_facts, registered vars and gathered facts associate to the host so those do persist for the run
 
  
== Playbooks ==
+
;You have 3 plays in one playbook.  Will play 3 be able to reference facts registered in play 1?:
 +
:facts, yes, play vars, no
 +
:vars associated to the host, persist, vars defined in the play, do not, set_facts, registered vars and gathered facts associate to the host so those do persist for the run
 +
 
 +
==Playbooks==
 
Ansible "[http://docs.ansible.com/playbooks.html Playbooks]" use an easy and descriptive language based on YAML.
 
Ansible "[http://docs.ansible.com/playbooks.html Playbooks]" use an easy and descriptive language based on YAML.
  
== Targets ==
+
==Roles==
 +
[https://www.redhat.com/sysadmin/developing-ansible-role 8 steps to developing an Ansible role] (aka when a playbook becomes a re-usable role)
 +
 
 +
==Targets==
 
Ansible can deploy to virtualization environments and public and private cloud environments including VMWare, OpenStack, AWS, Eucalyptus Cloud, KVM, and CloudStack
 
Ansible can deploy to virtualization environments and public and private cloud environments including VMWare, OpenStack, AWS, Eucalyptus Cloud, KVM, and CloudStack
  
  
== Testing ==
+
==Testing==
There is a spectrum of testing you can employ in your Ansible deployments<ref>https://www.youtube.com/live/FaXVZ60o8L8?si=gFoxE-ig5X0psuul&t=1244</ref>
+
{{#evu:https://www.youtube.com/watch?v=FaXVZ60o8L8&t=1244s
# <code>yamllint</code>
+
|alignment=right
# <code>ansible-playbook --syntax-check</code>
+
}}
# <code>ansible-lint</code>
+
 
# molecule test (integration)
+
 
# <code>ansible-playbook --check</code> (against prod)
+
[[File:Ansible linting and testing spectrum.png|thumb|left|The spectrum of testing you can employ in your Ansible deployments]]
# parallel infrastructure
+
Jeff Geerling talks about the spectrum of testing you can employ in your Ansible deployments<ref>https://www.youtube.com/live/FaXVZ60o8L8?si=gFoxE-ig5X0psuul&t=1244</ref>
 +
 
 +
#<code>yamllint</code>
 +
#<code>ansible-playbook --syntax-check</code>
 +
#<code>ansible-lint</code>   https://ansible.readthedocs.io/projects/lint/ TLDR; you might want to setup a venv and then pip3 install ansible-lint
 +
#molecule test (integration)
 +
#<code>ansible-playbook --check</code> (against prod)
 +
#parallel infrastructure
  
 
In development
 
In development
# Use the <tt>debug</tt> module
 
# Use the <tt>fail</tt> module to fail
 
# Use the <tt>assert</tt> module to make assertions (and fail if they don't match)
 
  
== Best Practices ==
+
#Use the <tt>debug</tt> module
 +
#Use the <tt>fail</tt> module to fail
 +
#Use the <tt>assert</tt> module to make assertions (and fail if they don't match)
 +
 
 +
==Best Practices==
 
Building Ansible Automation Platform execution environments (EE)  
 
Building Ansible Automation Platform execution environments (EE)  
* https://www.redhat.com/architect/ansible-execution-environment-tips
+
 
 +
*https://www.redhat.com/architect/ansible-execution-environment-tips
  
 
Using Python 3
 
Using Python 3
* https://docs.ansible.com/ansible/latest/reference_appendices/python_3_support.html
 
* https://docs.ansible.com/ansible/latest/dev_guide/developing_python_3.html
 
  
* Use tags to organize your Ansible work
+
*https://docs.ansible.com/ansible/latest/reference_appendices/python_3_support.html
 +
*https://docs.ansible.com/ansible/latest/dev_guide/developing_python_3.html
  
* Use caching (default is off) to be able to refer to host 'facts' without having to hit each host in a playbook.
+
*Use tags to organize your Ansible work
  
* Use register of [https://docs.ansible.com/ansible/playbooks_variables.html variables] to create more 'facts'.  Results vary from module to module. Use -v to see possible values.  
+
*Use caching (default is off) to be able to refer to host 'facts' without having to hit each host in a playbook.
  
* There is an order of precedence with [https://docs.ansible.com/ansible/playbooks_variables.html playbook variables], with role defaults the lowest priority and extra vars the winner.
+
*Use register of [https://docs.ansible.com/ansible/playbooks_variables.html variables] to create more 'facts'.  Results vary from module to module. Use -v to see possible values.
 +
 
 +
*There is an order of precedence with [https://docs.ansible.com/ansible/playbooks_variables.html playbook variables], with role defaults the lowest priority and extra vars the winner.
 +
 
 +
*The array notation is preferred over the dot notation for accessing variables.<br />
  
* The array notation is preferred over the dot notation for accessing variables.<br />
 
 
<nowiki>{{ ansible_eth0["ipv4"]["address"] }} over {{ ansible_eth0.ipv4.address }}</nowiki> because some keywords in Python would conflict
 
<nowiki>{{ ansible_eth0["ipv4"]["address"] }} over {{ ansible_eth0.ipv4.address }}</nowiki> because some keywords in Python would conflict
  
* Reserved words:
+
*Reserved words:
** hostvars
+
**hostvars
** group_names
+
**group_names
** groups
+
**groups
** environemnt
+
**environemnt
  
* '''<code>inventory_hostname</code>''' is the name of the hostname as configured in Ansible's inventory host file.  '''<code>ansible_hostname</code>''' is the discovered hostname  
+
*'''<code>inventory_hostname</code>''' is the name of the hostname as configured in Ansible's inventory host file.  '''<code>ansible_hostname</code>''' is the discovered hostname
  
* You can use a variables file to put sensitive data in a different file (one excluded from git).
+
*You can use a variables file to put sensitive data in a different file (one excluded from git).
 
<source lang="yaml">
 
<source lang="yaml">
 
- hosts: all
 
- hosts: all
Line 132: Line 147:
 
</source>
 
</source>
  
* You can use variables on the command line (and besides key=value pairs, you can use json or yml)
+
*You can use variables on the command line (and besides key=value pairs, you can use json or yml)
 
<source lang="yaml">
 
<source lang="yaml">
 
---
 
---
Line 144: Line 159:
 
<code>ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"</code>
 
<code>ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"</code>
  
* Check [https://www.ansible.com/blog/ansible-performance-tuning Performance Tuning] like enabling <code>pipelining</code> which is off by default.
+
*Check [https://www.ansible.com/blog/ansible-performance-tuning Performance Tuning] like enabling <code>pipelining</code> which is off by default.
 +
 
 +
*Truthy values should always be expressed as '''one of <code>[false, true]</code>'''. Although the Ansible docs show that [https://docs.ansible.com/ansible/latest/YAMLSyntax.html#yaml-basics you can use several forms of expression for boolean values], and [http://yaml.org/type/bool.html the YAML spec specifies a fuller range of possibilities] described below, the Ansible documentation now also [https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html clarifies that only lowercase 'true' or 'false'] is compatible with [[yamllint]] options.
  
* Truthy values should always be expressed as '''one of <code>[false, true]</code>'''. Although the Ansible docs show that [https://docs.ansible.com/ansible/latest/YAMLSyntax.html#yaml-basics you can use several forms of expression for boolean values], and [http://yaml.org/type/bool.html the YAML spec specifies a fuller range of possibilities] described below, the Ansible documentation now also [https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html clarifies that only lowercase 'true' or 'false'] is compatible with [[yamllint]] options.
 
 
;YAML boolean values, not Ansible:
 
;YAML boolean values, not Ansible:
:<syntaxhighlight lang=ebnf>
+
:<syntaxhighlight lang="ebnf">
 
y|Y|yes|Yes|YES|n|N|no|No|NO
 
y|Y|yes|Yes|YES|n|N|no|No|NO
 
|true|True|TRUE|false|False|FALSE
 
|true|True|TRUE|false|False|FALSE
Line 154: Line 170:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Scope ==
+
==Scope==
 
Ansible has 3 main scopes:
 
Ansible has 3 main scopes:
  
Line 161: Line 177:
 
'''Host''': variables directly associated to a host, like inventory, facts or registered task outputs
 
'''Host''': variables directly associated to a host, like inventory, facts or registered task outputs
  
== Ansible with Vagrant ==
+
Another aspect of scope is <tt>includes</tt> vs. <tt>imports</tt> and loosely speaking, control structures like <tt>loop</tt> and the deprecated <tt>with_items</tt>
 +
 
 +
*https://stackoverflow.com/questions/68863854/iterate-list-within-role-task-provide-each-element-as-vars-to-include-tasks
 +
*https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse.html#comparing-includes-and-imports-dynamic-and-static-re-use
 +
 
 +
==Ansible with VSCode==
 +
https://marketplace.visualstudio.com/items?itemName=redhat.ansible
 +
 
 +
==Ansible with Vagrant==
 
https://docs.ansible.com/ansible/guide_vagrant.html and [[Private:QualityBox/Vagrant]]
 
https://docs.ansible.com/ansible/guide_vagrant.html and [[Private:QualityBox/Vagrant]]
  
== Ansible with MediaWiki ==
+
==Ansible with MediaWiki==
  
 
https://github.com/Orain
 
https://github.com/Orain
 
I've cloned the '[https://github.com/freephile/ansible-playbook.git ansible-playbook]'
 
I've cloned the '[https://github.com/freephile/ansible-playbook.git ansible-playbook]'
  
== Ansible with Drupal ==
+
==Ansible with Drupal==
* Jeff Geerling (geerlingguy) has his code on github https://github.com/geerlingguy/drupal-vm, and also a website http://www.drupalvm.com/.  He's the author of Ansible for DevOps.  The only problem I see with his code is that it installs everything from his own 'roles' (individual components) via the sharing site/mechanism called Ansible Galaxy.  So, for example, phpMyAdmin comes from https://github.com/geerlingguy/ansible-role-phpmyadmin  This is good in that he can make his system work, but it's bad in that you're getting all your bits from him and can't tweak any of it without manually checking each role for the code and instructions behind it so you know what you can set via variables and such.  I'd rather see each of these roles contained in the project, community sourced, installed via git.
+
 
 +
*Jeff Geerling (geerlingguy) has his code on github https://github.com/geerlingguy/drupal-vm, and also a website http://www.drupalvm.com/.  He's the author of Ansible for DevOps.  The only problem I see with his code is that it installs everything from his own 'roles' (individual components) via the sharing site/mechanism called Ansible Galaxy.  So, for example, phpMyAdmin comes from https://github.com/geerlingguy/ansible-role-phpmyadmin  This is good in that he can make his system work, but it's bad in that you're getting all your bits from him and can't tweak any of it without manually checking each role for the code and instructions behind it so you know what you can set via variables and such.  I'd rather see each of these roles contained in the project, community sourced, installed via git.
 
<pre>
 
<pre>
 
geerlingguy.firewall
 
geerlingguy.firewall
Line 192: Line 217:
 
</pre>
 
</pre>
  
* on [https://www.digitalocean.com/community/tutorials/how-to-create-an-ansible-playbook-to-automate-drupal-installation-on-ubuntu-14-04 Digital Ocean]
+
*on [https://www.digitalocean.com/community/tutorials/how-to-create-an-ansible-playbook-to-automate-drupal-installation-on-ubuntu-14-04 Digital Ocean]
  
  
== Ansible in the cloud ==
+
==Ansible in the cloud==
 
Ansible has several core modules for working with various [http://docs.ansible.com/list_of_cloud_modules.html cloud providers].  These include
 
Ansible has several core modules for working with various [http://docs.ansible.com/list_of_cloud_modules.html cloud providers].  These include
  
* Amazon
+
*Amazon
* [[Digital Ocean]] http://docs.ansible.com/digital_ocean_module.html
+
*[[Digital Ocean]] http://docs.ansible.com/digital_ocean_module.html
* [[Linode]] http://docs.ansible.com/linode_module.html
+
*[[Linode]] http://docs.ansible.com/linode_module.html
* [[LXC]]
+
*[[LXC]]
  
* OpenStack
+
*OpenStack
  
== Ansible on Fedora ==
+
==Ansible on Fedora==
 
The [https://fedoraproject.org/wiki/Fedora_Project_Wiki Fedora Project] uses Ansible in it's Infrastructure team, and they publish their whole setup https://infrastructure.fedoraproject.org/cgit/ansible.git/tree/README
 
The [https://fedoraproject.org/wiki/Fedora_Project_Wiki Fedora Project] uses Ansible in it's Infrastructure team, and they publish their whole setup https://infrastructure.fedoraproject.org/cgit/ansible.git/tree/README
  
== Ansible Docs ==
+
== Ansible on Rocky Linux ==
 +
If you're working on [https://www.mediawiki.org/wiki/Meza Meza], you're going to want to test things on '''Rocky Linux 8''' - because that is the reference OS for the "[https://www.mediawiki.org/wiki/Meza/Common_Meza_Test_Environment_(CMTE) Common Meza Test Environment]". Jeff Geerling has a [https://github.com/geerlingguy/docker-rockylinux8-ansible Rocky Linux 8 Docker setup for testing Ansbile].  Similar to [https://www.mediawiki.org/wiki/Meza/Install_on_existing_server installing Meza on an existing server] it should be relatively quick to spin up Meza on Docker.
 +
 
 +
<syntaxhighlight lang="bash">
 +
# from your host
 +
docker pull geerlingguy/docker-rockylinux8-ansible:latest
 +
cd ~/src/meza/
 +
docker run --detach --privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:rw --cgroupns=host --volume=`pwd`:/etc/ansible/roles/role_under_test:ro geerlingguy/docker-rockylinux8-ansible:latest
 +
 
 +
# then inside the container
 +
cd /etc/ansible/roles/role_under_test/config
 +
ansible-playbook ../src/playbooks/site.yml --syntax-check
 +
</syntaxhighlight>
 +
 
 +
 
 +
==Ansible Docs==
 
Some of the docs pages I've visited
 
Some of the docs pages I've visited
  
* https://docs.ansible.com/ansible/playbooks_intro.html
+
*https://docs.ansible.com/ansible/playbooks_intro.html
* https://docs.ansible.com/ansible/intro_inventory.html
+
*https://docs.ansible.com/ansible/intro_inventory.html
* http://docs.ansible.com/playbooks_best_practices.html
+
*http://docs.ansible.com/playbooks_best_practices.html
* http://docs.ansible.com/playbooks_loops.html
+
*http://docs.ansible.com/playbooks_loops.html
* https://docs.ansible.com/ansible/playbooks_conditionals.html
+
*https://docs.ansible.com/ansible/playbooks_conditionals.html
* https://docs.ansible.com/ansible/playbooks_startnstep.html
+
*https://docs.ansible.com/ansible/playbooks_startnstep.html
* https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse
+
*https://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse
* http://docs.ansible.com/YAMLSyntax.html
+
*http://docs.ansible.com/YAMLSyntax.html
* https://docs.ansible.com/ansible/become.html
+
*https://docs.ansible.com/ansible/become.html
* https://docs.ansible.com/ansible/debug_module.html
+
*https://docs.ansible.com/ansible/debug_module.html
* https://docs.ansible.com/ansible/playbooks_debugger.html  (<code>strategy:debug</code>)
+
*https://docs.ansible.com/ansible/playbooks_debugger.html  (<code>strategy:debug</code>)
* https://docs.ansible.com/ansible/playbooks_conditionals.html#sts=The When Statement%C2%B6
+
*https://docs.ansible.com/ansible/playbooks_conditionals.html#sts=The When Statement%C2%B6
 +
 
 +
 
 +
==Controlling Whitespace in Jinja2 Templates==
 +
See [[Controlling whitespace in Jinja2 templates]]
 +
 
 +
==Ansible References==
  
 +
*http://tjelvarolsson.com/blog/taking-the-effort-out-of-server-configuration-using-ansible/
 +
*http://tjelvarolsson.com/blog/how-to-create-automated-and-reproducible-work-flows-for-installing-scientific-software/ < with Vagrant
 +
*http://jpmens.net/2012/06/06/configuration-management-with-ansible/
 +
*[http://jinja.pocoo.org/docs/dev/ Jinja] - the template engine for Ansible
 +
*[https://cheat.readthedocs.io/en/latest/ansible/index.html Dan's Cheat Sheets]
  
== Ansible References ==
+
== To Do ==
* http://tjelvarolsson.com/blog/taking-the-effort-out-of-server-configuration-using-ansible/
 
* http://tjelvarolsson.com/blog/how-to-create-automated-and-reproducible-work-flows-for-installing-scientific-software/ < with Vagrant
 
* http://jpmens.net/2012/06/06/configuration-management-with-ansible/
 
* [http://jinja.pocoo.org/docs/dev/ Jinja] - the template engine for Ansible
 
  
* [https://cheat.readthedocs.io/en/latest/ansible/index.html Dan's Cheat Sheets]
+
# Follow and learn from Jeff Geerling's Drupal site https://github.com/geerlingguy/jeffgeerling-com because his techniques embody best practices for PHP, Drupal, Docker, Ansible, etc.  In episode 12 of Ansible 101 - Real-world Ansible Playbooks [https://www.youtube.com/live/_QZr4xKhir4?si=LOyBibByqdmLb7M6&t=1107 here] he discusses his Drupal playbook and the 'deploy' tag. But sadly the playbooks are private (Midwestern Mac infrastructure), so you'll have to read the screen to emulate it exactly. The closest I found was https://github.com/geerlingguy/ansible-awx-varnish-php-app/blob/master/main.yml
 +
# Add info (separate page) about the Ansible clone of the Ruby deployment system 'Capistrano' called 'Anistrano'
 +
## https://www.oliverdavies.uk/talks/deploying-php-ansible-ansistrano
 +
## https://github.com/ansistrano/deploy
 
{{References}}
 
{{References}}
  

Latest revision as of 15:57, 21 August 2024

wp:Ansible_(software) is an open-source software platform for configuring and managing computers. It combines multi-node software deployment, ad hoc task execution, and configuration management. Written in Python, it is packaged by RedHat. As of July 2016, we're using Ansible 2.2.0



Also, RedHat seems to have purposely made things very convoluted in terms of versioning, release cycles and product naming. So check https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html and see if you can figure it out. [1]

Installation[edit | edit source]

Historical note: it used to be that you'd just git clone the source. And then source the env-setup script. [2]

Fast-forward a decade and you'll need to figure out the correct path for your situation. https://docs.ansible.com/ansible/latest/installation_guide/index.html

Getting Started[edit | edit source]

You must source the environment setup script to begin using Ansible (assuming you are running from a git checkout) source ~/bin/ansible/hacking/env-setup Ansible provides three main commands:

  1. ansible-playbook - to execute an Ansible playbook on the specified systems
  2. ansible - to execute an individual shell command or Ansible module on the specified systems
  3. ansible-vault - (optional) to encrypt or decrypt YAML files that Ansible uses.

Global Config[edit | edit source]

export ANSIBLE_HOST_KEY_CHECKING=False or set it in your ~/.ansible.cfg so that as you add new hosts it won't prompt you.

Also use 'ssh' instead of paramiko when doing this.

Initialize a Project[edit | edit source]

Use Ansible Galaxy If you want to do a new project, you can use the ansible-galaxy foo init command which will create the directory and file structure for 'foo' in the current working directory.

Also, if you want to install other Ansible Galaxy projects, you can either do it "manually" ansible-galaxy install -r Or, setup a 'requirements.yml' file in your playbook that then gets run by your stack. [3][4]

ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options]

Modules[edit | edit source]

Ansible comes with over 200 modules that you should get familiar with in order to use the system effectively.

There are a bunch of modules in Ansible, like the MySQL module, the Monit module, or the File module and other interesting modules like jabber, mail, sendgrid, dpkg_selections, composer, yum, redhat_subscription, digital ocean, the authorized_key module for working with SSH keys, and a whole section of system modules.

You can use the command module (secure but simple) or the shell module. The latter may be useful if you need to run bash explicitly (defaults to /bin/sh); or anytime you need $HOME and redirection.

To sanitize any variables passed to the shell module, you should use "{{ var | quote }}" instead of just "{{ var }}" to make sure they don't include evil things like semicolons.


Example Commands[edit | edit source]

Note: control verbosity with -vvvv

  1. ansible --help display help
  2. ansible --version show version info
  3. ansible -c local -i ~/ansible_hosts -m ping all ping all the hosts in the inventory file
  4. ansible -m setup wiki.example.com Use the setup module to gather ansible 'facts' (aka ansible_variables) about that host.
  5. ansible localhost -m setup -a 'gather_subset=!all' or look at the localhost
  6. ansible all -m setup -a "filter=ansible_distribution*" use a filter action to see specific variables
  7. ansible localhost -m setup --tree /tmp/facts store all facts in a file 'tree', based on hostname
  8. ansible -m debug -a "var=hostvars['wiki.example.com']" localhost gives you the 'ansible hostvars'
  9. ansible-playbook play1.yml play2.yml Run multiple playbooks
  10. ansible-playbook -i production webservers.yml --tags ntp --list-tasks confirm what task names would be run if I ran this command and said "just ntp tasks"
  11. ansible-playbook --list-tags launch.yml see what tags exist in my playbook (the tasks list shows more detail + the tags)
  12. ansible-playbook -i production webservers.yml --limit boston --list-hosts confirm what hostnames might be communicated with if I said "limit to boston" [5]
  13. ~/bin/ansible/contrib/inventory/digital_ocean.py --list --pretty --api-token TOKEN_HERE use the DO api to list your droplets (dynamic inventory)
  14. ansible-playbook -vvv launch.yml -l wiki.example.com --user=root -e do_name=wiki.example.com --start-at-task='remove empty wiki schema from database if it already exists' start at a particular point in the task list
  15. php -r 'var_dump(json_decode(file_get_contents("/tmp/facts/localhost"), true));' look at the json with php (or more interesting tools) With Ansible's Jinja2 filters, you can specify the output of a variable to be 'pretty' {{ some_variable | to_nice_json }}

Variables[edit | edit source]

You have 3 plays in one playbook. Will play 3 be able to reference facts registered in play 1?
facts, yes, play vars, no
vars associated to the host, persist, vars defined in the play, do not, set_facts, registered vars and gathered facts associate to the host so those do persist for the run

Playbooks[edit | edit source]

Ansible "Playbooks" use an easy and descriptive language based on YAML.

Roles[edit | edit source]

8 steps to developing an Ansible role (aka when a playbook becomes a re-usable role)

Targets[edit | edit source]

Ansible can deploy to virtualization environments and public and private cloud environments including VMWare, OpenStack, AWS, Eucalyptus Cloud, KVM, and CloudStack


Testing[edit | edit source]


The spectrum of testing you can employ in your Ansible deployments

Jeff Geerling talks about the spectrum of testing you can employ in your Ansible deployments[6]

  1. yamllint
  2. ansible-playbook --syntax-check
  3. ansible-lint https://ansible.readthedocs.io/projects/lint/ TLDR; you might want to setup a venv and then pip3 install ansible-lint
  4. molecule test (integration)
  5. ansible-playbook --check (against prod)
  6. parallel infrastructure

In development

  1. Use the debug module
  2. Use the fail module to fail
  3. Use the assert module to make assertions (and fail if they don't match)

Best Practices[edit | edit source]

Building Ansible Automation Platform execution environments (EE)

Using Python 3

  • Use tags to organize your Ansible work
  • Use caching (default is off) to be able to refer to host 'facts' without having to hit each host in a playbook.
  • Use register of variables to create more 'facts'. Results vary from module to module. Use -v to see possible values.
  • There is an order of precedence with playbook variables, with role defaults the lowest priority and extra vars the winner.
  • The array notation is preferred over the dot notation for accessing variables.

{{ ansible_eth0["ipv4"]["address"] }} over {{ ansible_eth0.ipv4.address }} because some keywords in Python would conflict

  • Reserved words:
    • hostvars
    • group_names
    • groups
    • environemnt
  • inventory_hostname is the name of the hostname as configured in Ansible's inventory host file. ansible_hostname is the discovered hostname
  • You can use a variables file to put sensitive data in a different file (one excluded from git).
- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/top_secret.yml
  • You can use variables on the command line (and besides key=value pairs, you can use json or yml)
---

- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'

  tasks:
     - ...

ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

YAML boolean values, not Ansible
y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

Scope[edit | edit source]

Ansible has 3 main scopes:

Global: this is set by config, environment variables and the command line Play: each play and contained structures, vars entries, include_vars, role defaults and vars. Host: variables directly associated to a host, like inventory, facts or registered task outputs

Another aspect of scope is includes vs. imports and loosely speaking, control structures like loop and the deprecated with_items

Ansible with VSCode[edit | edit source]

https://marketplace.visualstudio.com/items?itemName=redhat.ansible

Ansible with Vagrant[edit | edit source]

https://docs.ansible.com/ansible/guide_vagrant.html and Private:QualityBox/Vagrant

Ansible with MediaWiki[edit | edit source]

https://github.com/Orain I've cloned the 'ansible-playbook'

Ansible with Drupal[edit | edit source]

  • Jeff Geerling (geerlingguy) has his code on github https://github.com/geerlingguy/drupal-vm, and also a website http://www.drupalvm.com/. He's the author of Ansible for DevOps. The only problem I see with his code is that it installs everything from his own 'roles' (individual components) via the sharing site/mechanism called Ansible Galaxy. So, for example, phpMyAdmin comes from https://github.com/geerlingguy/ansible-role-phpmyadmin This is good in that he can make his system work, but it's bad in that you're getting all your bits from him and can't tweak any of it without manually checking each role for the code and instructions behind it so you know what you can set via variables and such. I'd rather see each of these roles contained in the project, community sourced, installed via git.
geerlingguy.firewall
geerlingguy.git
geerlingguy.apache
geerlingguy.memcached
geerlingguy.mysql
geerlingguy.php
geerlingguy.php-pecl
geerlingguy.php-memcached
geerlingguy.php-mysql
geerlingguy.php-xdebug
geerlingguy.php-xhprof
geerlingguy.phpmyadmin
geerlingguy.composer
geerlingguy.drush
geerlingguy.daemonize
geerlingguy.mailhog
geerlingguy.java
geerlingguy.solr


Ansible in the cloud[edit | edit source]

Ansible has several core modules for working with various cloud providers. These include

  • OpenStack

Ansible on Fedora[edit | edit source]

The Fedora Project uses Ansible in it's Infrastructure team, and they publish their whole setup https://infrastructure.fedoraproject.org/cgit/ansible.git/tree/README

Ansible on Rocky Linux[edit | edit source]

If you're working on Meza, you're going to want to test things on Rocky Linux 8 - because that is the reference OS for the "Common Meza Test Environment". Jeff Geerling has a Rocky Linux 8 Docker setup for testing Ansbile. Similar to installing Meza on an existing server it should be relatively quick to spin up Meza on Docker.

# from your host
docker pull geerlingguy/docker-rockylinux8-ansible:latest
cd ~/src/meza/
docker run --detach --privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:rw --cgroupns=host --volume=`pwd`:/etc/ansible/roles/role_under_test:ro geerlingguy/docker-rockylinux8-ansible:latest

# then inside the container
cd /etc/ansible/roles/role_under_test/config
ansible-playbook ../src/playbooks/site.yml --syntax-check


Ansible Docs[edit | edit source]

Some of the docs pages I've visited


Controlling Whitespace in Jinja2 Templates[edit | edit source]

See Controlling whitespace in Jinja2 templates

Ansible References[edit | edit source]

To Do[edit | edit source]

  1. Follow and learn from Jeff Geerling's Drupal site https://github.com/geerlingguy/jeffgeerling-com because his techniques embody best practices for PHP, Drupal, Docker, Ansible, etc. In episode 12 of Ansible 101 - Real-world Ansible Playbooks here he discusses his Drupal playbook and the 'deploy' tag. But sadly the playbooks are private (Midwestern Mac infrastructure), so you'll have to read the screen to emulate it exactly. The closest I found was https://github.com/geerlingguy/ansible-awx-varnish-php-app/blob/master/main.yml
  2. Add info (separate page) about the Ansible clone of the Ruby deployment system 'Capistrano' called 'Anistrano'
    1. https://www.oliverdavies.uk/talks/deploying-php-ansible-ansistrano
    2. https://github.com/ansistrano/deploy

References[edit source]

  1. In 2024 people are still Confused about Ansible documentation and versions It's rather ridiculous that their ansible-core project does NOT use SemVer
  2. Having the source makes it easy to upgrade, and it's self-contained, plus best of all you get all the examples and contribs.
  3. https://stackoverflow.com/questions/25230376/how-to-automatically-install-ansible-galaxy-roles
  4. Supposedly this only works for newer versions of Ansible, per the warning on their homepage:

    Warning alert:To be able to download content from galaxy it is required to have ansible-core>=2.13.9 Please, check it running the command: ansible --version

    But, it worked fine for me in the Meza 1_39 upgrade using Ansible 2.9.27

  5. Choosing which host(s) to operate on https://docs.ansible.com/ansible/intro_patterns.html
  6. https://www.youtube.com/live/FaXVZ60o8L8?si=gFoxE-ig5X0psuul&t=1244