diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
commit | a453ac31f3428614cceb99027f8efbdb9258a40b (patch) | |
tree | f61f87408f32a8511cbd91799f9cececb53e0374 /docs/docsite/rst/reference_appendices | |
parent | Initial commit. (diff) | |
download | ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.tar.xz ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.zip |
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docs/docsite/rst/reference_appendices')
15 files changed, 2614 insertions, 0 deletions
diff --git a/docs/docsite/rst/reference_appendices/.rstcheck.cfg b/docs/docsite/rst/reference_appendices/.rstcheck.cfg new file mode 100644 index 00000000..5b33c076 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/.rstcheck.cfg @@ -0,0 +1,2 @@ +[rstcheck] +ignore_directives=autoclass,automodule diff --git a/docs/docsite/rst/reference_appendices/YAMLSyntax.rst b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst new file mode 100644 index 00000000..7d439664 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/YAMLSyntax.rst @@ -0,0 +1,242 @@ +.. _yaml_syntax: + + +YAML Syntax +=========== + +This page provides a basic overview of correct YAML syntax, which is how Ansible +playbooks (our configuration management language) are expressed. + +We use YAML because it is easier for humans to read and write than other common +data formats like XML or JSON. Further, there are libraries available in most +programming languages for working with YAML. + +You may also wish to read :ref:`working_with_playbooks` at the same time to see how this +is used in practice. + + +YAML Basics +----------- + +For Ansible, nearly every YAML file starts with a list. +Each item in the list is a list of key/value pairs, commonly +called a "hash" or a "dictionary". So, we need to know how +to write lists and dictionaries in YAML. + +There's another small quirk to YAML. All YAML files (regardless of their association with Ansible or not) can optionally +begin with ``---`` and end with ``...``. This is part of the YAML format and indicates the start and end of a document. + +All members of a list are lines beginning at the same indentation level starting with a ``"- "`` (a dash and a space):: + + --- + # A list of tasty fruits + - Apple + - Orange + - Strawberry + - Mango + ... + +A dictionary is represented in a simple ``key: value`` form (the colon must be followed by a space):: + + # An employee record + martin: + name: Martin D'vloper + job: Developer + skill: Elite + +More complicated data structures are possible, such as lists of dictionaries, dictionaries whose values are lists or a mix of both:: + + # Employee records + - martin: + name: Martin D'vloper + job: Developer + skills: + - python + - perl + - pascal + - tabitha: + name: Tabitha Bitumen + job: Developer + skills: + - lisp + - fortran + - erlang + +Dictionaries and lists can also be represented in an abbreviated form if you really want to:: + + --- + martin: {name: Martin D'vloper, job: Developer, skill: Elite} + ['Apple', 'Orange', 'Strawberry', 'Mango'] + +These are called "Flow collections". + +.. _truthiness: + +Ansible doesn't really use these too much, but you can also specify a boolean value (true/false) in several forms:: + + create_key: yes + needs_agent: no + knows_oop: True + likes_emacs: TRUE + uses_cvs: false + +Use lowercase 'true' or 'false' for boolean values in dictionaries if you want to be compatible with default yamllint options. + +Values can span multiple lines using ``|`` or ``>``. Spanning multiple lines using a "Literal Block Scalar" ``|`` will include the newlines and any trailing spaces. +Using a "Folded Block Scalar" ``>`` will fold newlines to spaces; it's used to make what would otherwise be a very long line easier to read and edit. +In either case the indentation will be ignored. +Examples are:: + + include_newlines: | + exactly as you see + will appear these three + lines of poetry + + fold_newlines: > + this is really a + single line of text + despite appearances + +While in the above ``>`` example all newlines are folded into spaces, there are two ways to enforce a newline to be kept:: + + fold_some_newlines: > + a + b + + c + d + e + f + same_as: "a b\nc d\n e\nf\n" + +Let's combine what we learned so far in an arbitrary YAML example. +This really has nothing to do with Ansible, but will give you a feel for the format:: + + --- + # An employee record + name: Martin D'vloper + job: Developer + skill: Elite + employed: True + foods: + - Apple + - Orange + - Strawberry + - Mango + languages: + perl: Elite + python: Elite + pascal: Lame + education: | + 4 GCSEs + 3 A-Levels + BSc in the Internet of Things + +That's all you really need to know about YAML to start writing `Ansible` playbooks. + +Gotchas +------- + +While you can put just about anything into an unquoted scalar, there are some exceptions. +A colon followed by a space (or newline) ``": "`` is an indicator for a mapping. +A space followed by the pound sign ``" #"`` starts a comment. + +Because of this, the following is going to result in a YAML syntax error:: + + foo: somebody said I should put a colon here: so I did + + windows_drive: c: + +...but this will work:: + + windows_path: c:\windows + +You will want to quote hash values using colons followed by a space or the end of the line:: + + foo: 'somebody said I should put a colon here: so I did' + + windows_drive: 'c:' + +...and then the colon will be preserved. + +Alternatively, you can use double quotes:: + + foo: "somebody said I should put a colon here: so I did" + + windows_drive: "c:" + +The difference between single quotes and double quotes is that in double quotes +you can use escapes:: + + foo: "a \t TAB and a \n NEWLINE" + +The list of allowed escapes can be found in the YAML Specification under "Escape Sequences" (YAML 1.1) or "Escape Characters" (YAML 1.2). + +The following is invalid YAML: + +.. code-block:: text + + foo: "an escaped \' single quote" + + +Further, Ansible uses "{{ var }}" for variables. If a value after a colon starts +with a "{", YAML will think it is a dictionary, so you must quote it, like so:: + + foo: "{{ variable }}" + +If your value starts with a quote the entire value must be quoted, not just part of it. Here are some additional examples of how to properly quote things:: + + foo: "{{ variable }}/additional/string/literal" + foo2: "{{ variable }}\\backslashes\\are\\also\\special\\characters" + foo3: "even if it's just a string literal it must all be quoted" + +Not valid:: + + foo: "E:\\path\\"rest\\of\\path + +In addition to ``'`` and ``"`` there are a number of characters that are special (or reserved) and cannot be used +as the first character of an unquoted scalar: ``[] {} > | * & ! % # ` @ ,``. + +You should also be aware of ``? : -``. In YAML, they are allowed at the beginning of a string if a non-space +character follows, but YAML processor implementations differ, so it's better to use quotes. + +In Flow Collections, the rules are a bit more strict:: + + a scalar in block mapping: this } is [ all , valid + + flow mapping: { key: "you { should [ use , quotes here" } + +Boolean conversion is helpful, but this can be a problem when you want a literal `yes` or other boolean values as a string. +In these cases just use quotes:: + + non_boolean: "yes" + other_string: "False" + + +YAML converts certain strings into floating-point values, such as the string +`1.0`. If you need to specify a version number (in a requirements.yml file, for +example), you will need to quote the value if it looks like a floating-point +value:: + + version: "1.0" + + +.. seealso:: + + :ref:`working_with_playbooks` + Learn what playbooks can do and how to write/run them. + `YAMLLint <http://yamllint.com/>`_ + YAML Lint (online) helps you debug YAML syntax if you are having problems + `GitHub examples directory <https://github.com/ansible/ansible-examples>`_ + Complete playbook files from the github project source + `Wikipedia YAML syntax reference <https://en.wikipedia.org/wiki/YAML>`_ + A good guide to YAML syntax + `Mailing List <https://groups.google.com/group/ansible-project>`_ + Questions? Help? Ideas? Stop by the list on Google Groups + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel and #yaml for YAML specific questions + `YAML 1.1 Specification <https://yaml.org/spec/1.1/>`_ + The Specification for YAML 1.1, which PyYAML and libyaml are currently + implementing + `YAML 1.2 Specification <https://yaml.org/spec/1.2/spec.html>`_ + For completeness, YAML 1.2 is the successor of 1.1 diff --git a/docs/docsite/rst/reference_appendices/automationhub.rst b/docs/docsite/rst/reference_appendices/automationhub.rst new file mode 100644 index 00000000..dd70b98f --- /dev/null +++ b/docs/docsite/rst/reference_appendices/automationhub.rst @@ -0,0 +1,10 @@ +.. _automation_hub: + +Ansible Automation Hub +====================== + +`Ansible Automation Hub <https://www.ansible.com/products/automation-hub>`_ is the official location to discover and download supported :ref:`collections <collections>`, included as part of an Ansible Automation Platform subscription. These content collections contain modules, plugins, roles, and playbooks in a downloadable package. + +Ansible Automation Hub gives you direct access to trusted content collections from Red Hat and Certified Partners. You can find content by topic or Ansible Partner organizations. + +Ansible Automation Hub is the downstream Red Hat supported product version of Ansible Galaxy. Find out more about Ansible Automation Hub features and how to access it at `Ansible Automation Hub <https://www.ansible.com/products/automation-hub>`_. Ansible Automation Hub is part of the Red Hat Ansible Automation Platform subscription, and comes bundled with support from Red Hat, Inc. diff --git a/docs/docsite/rst/reference_appendices/common_return_values.rst b/docs/docsite/rst/reference_appendices/common_return_values.rst new file mode 100644 index 00000000..392dc96c --- /dev/null +++ b/docs/docsite/rst/reference_appendices/common_return_values.rst @@ -0,0 +1,251 @@ +.. _common_return_values: + +Return Values +------------- + +.. contents:: Topics + +Ansible modules normally return a data structure that can be registered into a variable, or seen directly when output by +the `ansible` program. Each module can optionally document its own unique return values (visible through ansible-doc and on the :ref:`main docsite<ansible_documentation>`). + +This document covers return values common to all modules. + +.. note:: Some of these keys might be set by Ansible itself once it processes the module's return information. + + +Common +^^^^^^ + +backup_file +``````````` +For those modules that implement `backup=no|yes` when manipulating files, a path to the backup file created. + + .. code-block:: console + + "backup_file": "./foo.txt.32729.2020-07-30@06:24:19~" + + +changed +``````` +A boolean indicating if the task had to make changes. + + .. code-block:: console + + "changed": true + +diff +```` +Information on differences between the previous and current state. Often a dictionary with entries ``before`` and ``after``, which will then be formatted by the callback plugin to a diff view. + + .. code-block:: console + + "diff": [ + { + "after": "", + "after_header": "foo.txt (content)", + "before": "", + "before_header": "foo.txt (content)" + }, + { + "after_header": "foo.txt (file attributes)", + "before_header": "foo.txt (file attributes)" + } + +failed +`````` +A boolean that indicates if the task was failed or not. + + .. code-block:: console + + "failed": false + +invocation +`````````` +Information on how the module was invoked. + + .. code-block:: console + + "invocation": { + "module_args": { + "_original_basename": "foo.txt", + "attributes": null, + "backup": true, + "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "content": null, + "delimiter": null, + "dest": "./foo.txt", + "directory_mode": null, + "follow": false, + "force": true, + "group": null, + "local_follow": null, + "mode": "666", + "owner": null, + "regexp": null, + "remote_src": null, + "selevel": null, + "serole": null, + "setype": null, + "seuser": null, + "src": "/Users/foo/.ansible/tmp/ansible-tmp-1596115458.110205-105717464505158/source", + "unsafe_writes": null, + "validate": null + } + +msg +``` +A string with a generic message relayed to the user. + + .. code-block:: console + + "msg": "line added" + +rc +`` +Some modules execute command line utilities or are geared for executing commands directly (raw, shell, command, and so on), this field contains 'return code' of these utilities. + + .. code-block:: console + + "rc": 257 + +results +``````` +If this key exists, it indicates that a loop was present for the task and that it contains a list of the normal module 'result' per item. + + .. code-block:: console + + "results": [ + { + "ansible_loop_var": "item", + "backup": "foo.txt.83170.2020-07-30@07:03:05~", + "changed": true, + "diff": [ + { + "after": "", + "after_header": "foo.txt (content)", + "before": "", + "before_header": "foo.txt (content)" + }, + { + "after_header": "foo.txt (file attributes)", + "before_header": "foo.txt (file attributes)" + } + ], + "failed": false, + "invocation": { + "module_args": { + "attributes": null, + "backrefs": false, + "backup": true + } + }, + "item": "foo", + "msg": "line added" + }, + { + "ansible_loop_var": "item", + "backup": "foo.txt.83187.2020-07-30@07:03:05~", + "changed": true, + "diff": [ + { + "after": "", + "after_header": "foo.txt (content)", + "before": "", + "before_header": "foo.txt (content)" + }, + { + "after_header": "foo.txt (file attributes)", + "before_header": "foo.txt (file attributes)" + } + ], + "failed": false, + "invocation": { + "module_args": { + "attributes": null, + "backrefs": false, + "backup": true + } + }, + "item": "bar", + "msg": "line added" + } + ] + +skipped +``````` +A boolean that indicates if the task was skipped or not + + .. code-block:: console + + "skipped": true + +stderr +`````` +Some modules execute command line utilities or are geared for executing commands directly (raw, shell, command, and so on), this field contains the error output of these utilities. + + .. code-block:: console + + "stderr": "ls: foo: No such file or directory" + +stderr_lines +```````````` +When `stderr` is returned we also always provide this field which is a list of strings, one item per line from the original. + + .. code-block:: console + + "stderr_lines": [ + "ls: doesntexist: No such file or directory" + ] + +stdout +`````` +Some modules execute command line utilities or are geared for executing commands directly (raw, shell, command, and so on). This field contains the normal output of these utilities. + + .. code-block:: console + + "stdout": "foo!" + +stdout_lines +```````````` +When `stdout` is returned, Ansible always provides a list of strings, each containing one item per line from the original output. + + .. code-block:: console + + "stdout_lines": [ + "foo!" + ] + + +.. _internal_return_values: + +Internal use +^^^^^^^^^^^^ + +These keys can be added by modules but will be removed from registered variables; they are 'consumed' by Ansible itself. + +ansible_facts +````````````` +This key should contain a dictionary which will be appended to the facts assigned to the host. These will be directly accessible and don't require using a registered variable. + +exception +````````` +This key can contain traceback information caused by an exception in a module. It will only be displayed on high verbosity (-vvv). + +warnings +```````` +This key contains a list of strings that will be presented to the user. + +deprecations +```````````` +This key contains a list of dictionaries that will be presented to the user. Keys of the dictionaries are `msg` and `version`, values are string, value for the `version` key can be an empty string. + +.. seealso:: + + :ref:`list_of_collections` + Browse existing collections, modules, and plugins + `GitHub modules directory <https://github.com/ansible/ansible/tree/devel/lib/ansible/modules>`_ + Browse source of core and extras modules + `Mailing List <https://groups.google.com/group/ansible-devel>`_ + Development mailing list + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel diff --git a/docs/docsite/rst/reference_appendices/faq.rst b/docs/docsite/rst/reference_appendices/faq.rst new file mode 100644 index 00000000..329e2b4c --- /dev/null +++ b/docs/docsite/rst/reference_appendices/faq.rst @@ -0,0 +1,766 @@ +.. _ansible_faq: + +Frequently Asked Questions +========================== + +Here are some commonly asked questions and their answers. + +.. _collections_transition: + +Where did all the modules go? ++++++++++++++++++++++++++++++ + +In July, 2019, we announced that collections would be the `future of Ansible content delivery <https://www.ansible.com/blog/the-future-of-ansible-content-delivery>`_. A collection is a distribution format for Ansible content that can include playbooks, roles, modules, and plugins. In Ansible 2.9 we added support for collections. In Ansible 2.10 we extracted most modules from the main ansible/ansible repository and placed them in :ref:`collections <list_of_collections>`. Collections may be maintained by the Ansible team, by the Ansible community, or by Ansible partners. The `ansible/ansible repository <https://github.com/ansible/ansible>`_ now contains the code for basic features and functions, such as copying module code to managed nodes. This code is also known as ``ansible-base``. + +* To learn more about using collections, see :ref:`collections`. +* To learn more about developing collections, see :ref:`developing_collections`. +* To learn more about contributing to existing collections, see the individual collection repository for guidelines, or see :ref:`contributing_maintained_collections` to contribute to one of the Ansible-maintained collections. + +.. _find_my_module: + +Where did this specific module go? +++++++++++++++++++++++++++++++++++ + +IF you are searching for a specific module, you can check the `runtime.yml <https://github.com/ansible/ansible/blob/devel/lib/ansible/config/ansible_builtin_runtime.yml>`_ file, which lists the first destination for each module that we extracted from the main ansible/ansible repository. Some modules have moved again since then. You can also search on `Ansible Galaxy <https://galaxy.ansible.com/>`_ or ask on one of our :ref:`IRC channels <communication_irc>`. + +.. _set_environment: + +How can I set the PATH or any other environment variable for a task or entire play? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Setting environment variables can be done with the `environment` keyword. It can be used at the task or other levels in the play. + +.. code-block:: yaml + + shell: + cmd: date + environment: + LANG=fr_FR.UTF-8 + +.. code-block:: yaml + + hosts: servers + environment: + PATH: "{{ ansible_env.PATH }}:/thingy/bin" + SOME: value + +.. note:: starting in 2.0.1 the setup task from ``gather_facts`` also inherits the environment directive from the play, you might need to use the ``|default`` filter to avoid errors if setting this at play level. + +.. _faq_setting_users_and_ports: + +How do I handle different machines needing different user accounts or ports to log in with? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Setting inventory variables in the inventory file is the easiest way. + +For instance, suppose these hosts have different usernames and ports: + +.. code-block:: ini + + [webservers] + asdf.example.com ansible_port=5000 ansible_user=alice + jkl.example.com ansible_port=5001 ansible_user=bob + +You can also dictate the connection type to be used, if you want: + +.. code-block:: ini + + [testcluster] + localhost ansible_connection=local + /path/to/chroot1 ansible_connection=chroot + foo.example.com ansible_connection=paramiko + +You may also wish to keep these in group variables instead, or file them in a group_vars/<groupname> file. +See the rest of the documentation for more information about how to organize variables. + +.. _use_ssh: + +How do I get ansible to reuse connections, enable Kerberized SSH, or have Ansible pay attention to my local SSH config file? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Switch your default connection type in the configuration file to ``ssh``, or use ``-c ssh`` to use +Native OpenSSH for connections instead of the python paramiko library. In Ansible 1.2.1 and later, ``ssh`` will be used +by default if OpenSSH is new enough to support ControlPersist as an option. + +Paramiko is great for starting out, but the OpenSSH type offers many advanced options. You will want to run Ansible +from a machine new enough to support ControlPersist, if you are using this connection type. You can still manage +older clients. If you are using RHEL 6, CentOS 6, SLES 10 or SLES 11 the version of OpenSSH is still a bit old, so +consider managing from a Fedora or openSUSE client even though you are managing older nodes, or just use paramiko. + +We keep paramiko as the default as if you are first installing Ansible on these enterprise operating systems, it offers a better experience for new users. + +.. _use_ssh_jump_hosts: + +How do I configure a jump host to access servers that I have no direct access to? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +You can set a ``ProxyCommand`` in the +``ansible_ssh_common_args`` inventory variable. Any arguments specified in +this variable are added to the sftp/scp/ssh command line when connecting +to the relevant host(s). Consider the following inventory group: + +.. code-block:: ini + + [gatewayed] + foo ansible_host=192.0.2.1 + bar ansible_host=192.0.2.2 + +You can create `group_vars/gatewayed.yml` with the following contents:: + + ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"' + +Ansible will append these arguments to the command line when trying to +connect to any hosts in the group ``gatewayed``. (These arguments are used +in addition to any ``ssh_args`` from ``ansible.cfg``, so you do not need to +repeat global ``ControlPersist`` settings in ``ansible_ssh_common_args``.) + +Note that ``ssh -W`` is available only with OpenSSH 5.4 or later. With +older versions, it's necessary to execute ``nc %h:%p`` or some equivalent +command on the bastion host. + +With earlier versions of Ansible, it was necessary to configure a +suitable ``ProxyCommand`` for one or more hosts in ``~/.ssh/config``, +or globally by setting ``ssh_args`` in ``ansible.cfg``. + +.. _ssh_serveraliveinterval: + +How do I get Ansible to notice a dead target in a timely manner? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +You can add ``-o ServerAliveInterval=NumberOfSeconds`` in ``ssh_args`` from ``ansible.cfg``. Without this option, +SSH and therefore Ansible will wait until the TCP connection times out. Another solution is to add ``ServerAliveInterval`` +into your global SSH configuration. A good value for ``ServerAliveInterval`` is up to you to decide; keep in mind that +``ServerAliveCountMax=3`` is the SSH default so any value you set will be tripled before terminating the SSH session. + +.. _cloud_provider_performance: + +How do I speed up run of ansible for servers from cloud providers (EC2, openstack,.. )? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Don't try to manage a fleet of machines of a cloud provider from your laptop. +Rather connect to a management node inside this cloud provider first and run Ansible from there. + +.. _python_interpreters: + +How do I handle not having a Python interpreter at /usr/bin/python on a remote machine? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +While you can write Ansible modules in any language, most Ansible modules are written in Python, +including the ones central to letting Ansible work. + +By default, Ansible assumes it can find a :command:`/usr/bin/python` on your remote system that is +either Python2, version 2.6 or higher or Python3, 3.5 or higher. + +Setting the inventory variable ``ansible_python_interpreter`` on any host will tell Ansible to +auto-replace the Python interpreter with that value instead. Thus, you can point to any Python you +want on the system if :command:`/usr/bin/python` on your system does not point to a compatible +Python interpreter. + +Some platforms may only have Python 3 installed by default. If it is not installed as +:command:`/usr/bin/python`, you will need to configure the path to the interpreter via +``ansible_python_interpreter``. Although most core modules will work with Python 3, there may be some +special purpose ones which do not or you may encounter a bug in an edge case. As a temporary +workaround you can install Python 2 on the managed host and configure Ansible to use that Python via +``ansible_python_interpreter``. If there's no mention in the module's documentation that the module +requires Python 2, you can also report a bug on our `bug tracker +<https://github.com/ansible/ansible/issues>`_ so that the incompatibility can be fixed in a future release. + +Do not replace the shebang lines of your python modules. Ansible will do this for you automatically at deploy time. + +Also, this works for ANY interpreter, for example ruby: ``ansible_ruby_interpreter``, perl: ``ansible_perl_interpreter``, and so on, +so you can use this for custom modules written in any scripting language and control the interpreter location. + +Keep in mind that if you put ``env`` in your module shebang line (``#!/usr/bin/env <other>``), +this facility will be ignored so you will be at the mercy of the remote `$PATH`. + +.. _installation_faqs: + +How do I handle the package dependencies required by Ansible package dependencies during Ansible installation ? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +While installing Ansible, sometimes you may encounter errors such as `No package 'libffi' found` or `fatal error: Python.h: No such file or directory` +These errors are generally caused by the missing packages, which are dependencies of the packages required by Ansible. +For example, `libffi` package is dependency of `pynacl` and `paramiko` (Ansible -> paramiko -> pynacl -> libffi). + +In order to solve these kinds of dependency issues, you might need to install required packages using +the OS native package managers, such as `yum`, `dnf`, or `apt`, or as mentioned in the package installation guide. + +Refer to the documentation of the respective package for such dependencies and their installation methods. + +Common Platform Issues +++++++++++++++++++++++ + +What customer platforms does Red Hat support? +--------------------------------------------- + +A number of them! For a definitive list please see this `Knowledge Base article <https://access.redhat.com/articles/3168091>`_. + +Running in a virtualenv +----------------------- + +You can install Ansible into a virtualenv on the controller quite simply: + +.. code-block:: shell + + $ virtualenv ansible + $ source ./ansible/bin/activate + $ pip install ansible + +If you want to run under Python 3 instead of Python 2 you may want to change that slightly: + +.. code-block:: shell + + $ virtualenv -p python3 ansible + $ source ./ansible/bin/activate + $ pip install ansible + +If you need to use any libraries which are not available via pip (for instance, SELinux Python +bindings on systems such as Red Hat Enterprise Linux or Fedora that have SELinux enabled), then you +need to install them into the virtualenv. There are two methods: + +* When you create the virtualenv, specify ``--system-site-packages`` to make use of any libraries + installed in the system's Python: + + .. code-block:: shell + + $ virtualenv ansible --system-site-packages + +* Copy those files in manually from the system. For instance, for SELinux bindings you might do: + + .. code-block:: shell + + $ virtualenv ansible --system-site-packages + $ cp -r -v /usr/lib64/python3.*/site-packages/selinux/ ./py3-ansible/lib64/python3.*/site-packages/ + $ cp -v /usr/lib64/python3.*/site-packages/*selinux*.so ./py3-ansible/lib64/python3.*/site-packages/ + + +Running on BSD +-------------- + +.. seealso:: :ref:`working_with_bsd` + + +Running on Solaris +------------------ + +By default, Solaris 10 and earlier run a non-POSIX shell which does not correctly expand the default +tmp directory Ansible uses ( :file:`~/.ansible/tmp`). If you see module failures on Solaris machines, this +is likely the problem. There are several workarounds: + +* You can set ``remote_tmp`` to a path that will expand correctly with the shell you are using + (see the plugin documentation for :ref:`C shell<csh_shell>`, :ref:`fish shell<fish_shell>`, + and :ref:`Powershell<powershell_shell>`). For example, in the ansible config file you can set:: + + remote_tmp=$HOME/.ansible/tmp + + In Ansible 2.5 and later, you can also set it per-host in inventory like this:: + + solaris1 ansible_remote_tmp=$HOME/.ansible/tmp + +* You can set :ref:`ansible_shell_executable<ansible_shell_executable>` to the path to a POSIX compatible shell. For + instance, many Solaris hosts have a POSIX shell located at :file:`/usr/xpg4/bin/sh` so you can set + this in inventory like so:: + + solaris1 ansible_shell_executable=/usr/xpg4/bin/sh + + (bash, ksh, and zsh should also be POSIX compatible if you have any of those installed). + +Running on z/OS +--------------- + +There are a few common errors that one might run into when trying to execute Ansible on z/OS as a target. + +* Version 2.7.6 of python for z/OS will not work with Ansible because it represents strings internally as EBCDIC. + + To get around this limitation, download and install a later version of `python for z/OS <https://www.rocketsoftware.com/zos-open-source>`_ (2.7.13 or 3.6.1) that represents strings internally as ASCII. Version 2.7.13 is verified to work. + +* When ``pipelining = False`` in `/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with + + .. error:: + SyntaxError: Non-UTF-8 code starting with \'\\x83\' in file /a/user1/.ansible/tmp/ansible-tmp-1548232945.35-274513842609025/AnsiballZ_stat.py on line 1, but no encoding declared; see https://python.org/dev/peps/pep-0263/ for details + + To fix it set ``pipelining = True`` in `/etc/ansible/ansible.cfg`. + +* Python interpret cannot be found in default location ``/usr/bin/python`` on target host. + + .. error:: + /usr/bin/python: EDC5129I No such file or directory + + To fix this set the path to the python installation in your inventory like so:: + + zos1 ansible_python_interpreter=/usr/lpp/python/python-2017-04-12-py27/python27/bin/python + +* Start of python fails with ``The module libpython2.7.so was not found.`` + + .. error:: + EE3501S The module libpython2.7.so was not found. + + On z/OS, you must execute python from gnu bash. If gnu bash is installed at ``/usr/lpp/bash``, you can fix this in your inventory by specifying an ``ansible_shell_executable``:: + + zos1 ansible_shell_executable=/usr/lpp/bash/bin/bash + + +Running under fakeroot +---------------------- + +Some issues arise as ``fakeroot`` does not create a full nor POSIX compliant system by default. +It is known that it will not correctly expand the default tmp directory Ansible uses (:file:`~/.ansible/tmp`). +If you see module failures, this is likely the problem. +The simple workaround is to set ``remote_tmp`` to a path that will expand correctly (see documentation of the shell plugin you are using for specifics). + +For example, in the ansible config file (or via environment variable) you can set:: + + remote_tmp=$HOME/.ansible/tmp + + + +.. _use_roles: + +What is the best way to make content reusable/redistributable? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +If you have not done so already, read all about "Roles" in the playbooks documentation. This helps you make playbook content +self-contained, and works well with things like git submodules for sharing content with others. + +If some of these plugin types look strange to you, see the API documentation for more details about ways Ansible can be extended. + +.. _configuration_file: + +Where does the configuration file live and what can I configure in it? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +See :ref:`intro_configuration`. + +.. _who_would_ever_want_to_disable_cowsay_but_ok_here_is_how: + +How do I disable cowsay? +++++++++++++++++++++++++ + +If cowsay is installed, Ansible takes it upon itself to make your day happier when running playbooks. If you decide +that you would like to work in a professional cow-free environment, you can either uninstall cowsay, set ``nocows=1`` +in ``ansible.cfg``, or set the :envvar:`ANSIBLE_NOCOWS` environment variable: + +.. code-block:: shell-session + + export ANSIBLE_NOCOWS=1 + +.. _browse_facts: + +How do I see a list of all of the ansible\_ variables? +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ansible by default gathers "facts" about the machines under management, and these facts can be accessed in playbooks +and in templates. To see a list of all of the facts that are available about a machine, you can run the ``setup`` module +as an ad-hoc action: + +.. code-block:: shell-session + + ansible -m setup hostname + +This will print out a dictionary of all of the facts that are available for that particular host. You might want to pipe +the output to a pager.This does NOT include inventory variables or internal 'magic' variables. See the next question +if you need more than just 'facts'. + + +.. _browse_inventory_vars: + +How do I see all the inventory variables defined for my host? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +By running the following command, you can see inventory variables for a host: + +.. code-block:: shell-session + + ansible-inventory --list --yaml + + +.. _browse_host_vars: + +How do I see all the variables specific to my host? ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To see all host specific variables, which might include facts and other sources: + +.. code-block:: shell-session + + ansible -m debug -a "var=hostvars['hostname']" localhost + +Unless you are using a fact cache, you normally need to use a play that gathers facts first, for facts included in the task above. + + +.. _host_loops: + +How do I loop over a list of hosts in a group, inside of a template? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A pretty common pattern is to iterate over a list of hosts inside of a host group, perhaps to populate a template configuration +file with a list of servers. To do this, you can just access the "$groups" dictionary in your template, like this: + +.. code-block:: jinja + + {% for host in groups['db_servers'] %} + {{ host }} + {% endfor %} + +If you need to access facts about these hosts, for instance, the IP address of each hostname, +you need to make sure that the facts have been populated. For example, make sure you have a play that talks to db_servers:: + + - hosts: db_servers + tasks: + - debug: msg="doesn't matter what you do, just that they were talked to previously." + +Then you can use the facts inside your template, like this: + +.. code-block:: jinja + + {% for host in groups['db_servers'] %} + {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }} + {% endfor %} + +.. _programatic_access_to_a_variable: + +How do I access a variable name programmatically? ++++++++++++++++++++++++++++++++++++++++++++++++++ + +An example may come up where we need to get the ipv4 address of an arbitrary interface, where the interface to be used may be supplied +via a role parameter or other input. Variable names can be built by adding strings together, like so: + +.. code-block:: jinja + + {{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }} + +The trick about going through hostvars is necessary because it's a dictionary of the entire namespace of variables. ``inventory_hostname`` +is a magic variable that indicates the current host you are looping over in the host loop. + +In the example above, if your interface names have dashes, you must replace them with underscores: + +.. code-block:: jinja + + {{ hostvars[inventory_hostname]['ansible_' + which_interface | replace('_', '-') ]['ipv4']['address'] }} + +Also see dynamic_variables_. + + +.. _access_group_variable: + +How do I access a group variable? ++++++++++++++++++++++++++++++++++ + +Technically, you don't, Ansible does not really use groups directly. Groups are labels for host selection and a way to bulk assign variables, +they are not a first class entity, Ansible only cares about Hosts and Tasks. + +That said, you could just access the variable by selecting a host that is part of that group, see first_host_in_a_group_ below for an example. + + +.. _first_host_in_a_group: + +How do I access a variable of the first host in a group? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +What happens if we want the ip address of the first webserver in the webservers group? Well, we can do that too. Note that if we +are using dynamic inventory, which host is the 'first' may not be consistent, so you wouldn't want to do this unless your inventory +is static and predictable. (If you are using :ref:`ansible_tower`, it will use database order, so this isn't a problem even if you are using cloud +based inventory scripts). + +Anyway, here's the trick: + +.. code-block:: jinja + + {{ hostvars[groups['webservers'][0]]['ansible_eth0']['ipv4']['address'] }} + +Notice how we're pulling out the hostname of the first machine of the webservers group. If you are doing this in a template, you +could use the Jinja2 '#set' directive to simplify this, or in a playbook, you could also use set_fact:: + + - set_fact: headnode={{ groups['webservers'][0] }} + + - debug: msg={{ hostvars[headnode].ansible_eth0.ipv4.address }} + +Notice how we interchanged the bracket syntax for dots -- that can be done anywhere. + +.. _file_recursion: + +How do I copy files recursively onto a target host? ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The ``copy`` module has a recursive parameter. However, take a look at the ``synchronize`` module if you want to do something more efficient +for a large number of files. The ``synchronize`` module wraps rsync. See the module index for info on both of these modules. + +.. _shell_env: + +How do I access shell environment variables? +++++++++++++++++++++++++++++++++++++++++++++ + + +**On controller machine :** Access existing variables from controller use the ``env`` lookup plugin. +For example, to access the value of the HOME environment variable on the management machine:: + + --- + # ... + vars: + local_home: "{{ lookup('env','HOME') }}" + + +**On target machines :** Environment variables are available via facts in the ``ansible_env`` variable: + +.. code-block:: jinja + + {{ ansible_env.HOME }} + +If you need to set environment variables for TASK execution, see :ref:`playbooks_environment` +in the :ref:`Advanced Playbooks <playbooks_special_topics>` section. +There are several ways to set environment variables on your target machines. You can use the +:ref:`template <template_module>`, :ref:`replace <replace_module>`, or :ref:`lineinfile <lineinfile_module>` +modules to introduce environment variables into files. The exact files to edit vary depending on your OS +and distribution and local configuration. + +.. _user_passwords: + +How do I generate encrypted passwords for the user module? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ansible ad-hoc command is the easiest option: + +.. code-block:: shell-session + + ansible all -i localhost, -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}" + +The ``mkpasswd`` utility that is available on most Linux systems is also a great option: + +.. code-block:: shell-session + + mkpasswd --method=sha-512 + + +If this utility is not installed on your system (for example, you are using macOS) then you can still easily +generate these passwords using Python. First, ensure that the `Passlib <https://foss.heptapod.net/python-libs/passlib/-/wikis/home>`_ +password hashing library is installed: + +.. code-block:: shell-session + + pip install passlib + +Once the library is ready, SHA512 password values can then be generated as follows: + +.. code-block:: shell-session + + python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))" + +Use the integrated :ref:`hash_filters` to generate a hashed version of a password. +You shouldn't put plaintext passwords in your playbook or host_vars; instead, use :ref:`playbooks_vault` to encrypt sensitive data. + +In OpenBSD, a similar option is available in the base system called ``encrypt (1)`` + +.. _dot_or_array_notation: + +Ansible allows dot notation and array notation for variables. Which notation should I use? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The dot notation comes from Jinja and works fine for variables without special +characters. If your variable contains dots (.), colons (:), or dashes (-), if +a key begins and ends with two underscores, or if a key uses any of the known +public attributes, it is safer to use the array notation. See :ref:`playbooks_variables` +for a list of the known public attributes. + +.. code-block:: jinja + + item[0]['checksum:md5'] + item['section']['2.1'] + item['region']['Mid-Atlantic'] + It is {{ temperature['Celsius']['-3'] }} outside. + +Also array notation allows for dynamic variable composition, see dynamic_variables_. + +Another problem with 'dot notation' is that some keys can cause problems because they collide with attributes and methods of python dictionaries. + +.. code-block:: jinja + + item.update # this breaks if item is a dictionary, as 'update()' is a python method for dictionaries + item['update'] # this works + + +.. _argsplat_unsafe: + +When is it unsafe to bulk-set task arguments from a variable? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +You can set all of a task's arguments from a dictionary-typed variable. This +technique can be useful in some dynamic execution scenarios. However, it +introduces a security risk. We do not recommend it, so Ansible issues a +warning when you do something like this:: + + #... + vars: + usermod_args: + name: testuser + state: present + update_password: always + tasks: + - user: '{{ usermod_args }}' + +This particular example is safe. However, constructing tasks like this is +risky because the parameters and values passed to ``usermod_args`` could +be overwritten by malicious values in the ``host facts`` on a compromised +target machine. To mitigate this risk: + +* set bulk variables at a level of precedence greater than ``host facts`` in the order of precedence + found in :ref:`ansible_variable_precedence` (the example above is safe because play vars take + precedence over facts) +* disable the :ref:`inject_facts_as_vars` configuration setting to prevent fact values from colliding + with variables (this will also disable the original warning) + + +.. _commercial_support: + +Can I get training on Ansible? +++++++++++++++++++++++++++++++ + +Yes! See our `services page <https://www.ansible.com/products/consulting>`_ for information on our services +and training offerings. Email `info@ansible.com <mailto:info@ansible.com>`_ for further details. + +We also offer free web-based training classes on a regular basis. See our +`webinar page <https://www.ansible.com/resources/webinars-training>`_ for more info on upcoming webinars. + + +.. _web_interface: + +Is there a web interface / REST API / GUI? +++++++++++++++++++++++++++++++++++++++++++++ + +Yes! Ansible, Inc makes a great product that makes Ansible even more powerful and easy to use. See :ref:`ansible_tower`. + + +.. _keep_secret_data: + +How do I keep secret data in my playbook? ++++++++++++++++++++++++++++++++++++++++++ + +If you would like to keep secret data in your Ansible content and still share it publicly or keep things in source control, see :ref:`playbooks_vault`. + +If you have a task that you don't want to show the results or command given to it when using -v (verbose) mode, the following task or playbook attribute can be useful:: + + - name: secret task + shell: /usr/bin/do_something --value={{ secret_value }} + no_log: True + +This can be used to keep verbose output but hide sensitive information from others who would otherwise like to be able to see the output. + +The ``no_log`` attribute can also apply to an entire play:: + + - hosts: all + no_log: True + +Though this will make the play somewhat difficult to debug. It's recommended that this +be applied to single tasks only, once a playbook is completed. Note that the use of the +``no_log`` attribute does not prevent data from being shown when debugging Ansible itself via +the :envvar:`ANSIBLE_DEBUG` environment variable. + + +.. _when_to_use_brackets: +.. _dynamic_variables: +.. _interpolate_variables: + +When should I use {{ }}? Also, how to interpolate variables or dynamic variable names ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A steadfast rule is 'always use ``{{ }}`` except when ``when:``'. +Conditionals are always run through Jinja2 as to resolve the expression, +so ``when:``, ``failed_when:`` and ``changed_when:`` are always templated and you should avoid adding ``{{ }}``. + +In most other cases you should always use the brackets, even if previously you could use variables without +specifying (like ``loop`` or ``with_`` clauses), as this made it hard to distinguish between an undefined variable and a string. + +Another rule is 'moustaches don't stack'. We often see this: + +.. code-block:: jinja + + {{ somevar_{{other_var}} }} + +The above DOES NOT WORK as you expect, if you need to use a dynamic variable use the following as appropriate: + +.. code-block:: jinja + + {{ hostvars[inventory_hostname]['somevar_' + other_var] }} + +For 'non host vars' you can use the :ref:`vars lookup<vars_lookup>` plugin: + +.. code-block:: jinja + + {{ lookup('vars', 'somevar_' + other_var) }} + + +.. _why_no_wheel: + +Why don't you ship ansible in wheel format (or other packaging format) ? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In most cases it has to do with maintainability. There are many ways to ship software and we do not have +the resources to release Ansible on every platform. +In some cases there are technical issues. For example, our dependencies are not present on Python Wheels. + +.. _ansible_host_delegated: + +How do I get the original ansible_host when I delegate a task? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +As the documentation states, connection variables are taken from the ``delegate_to`` host so ``ansible_host`` is overwritten, +but you can still access the original via ``hostvars``:: + + original_host: "{{ hostvars[inventory_hostname]['ansible_host'] }}" + +This works for all overridden connection variables, like ``ansible_user``, ``ansible_port``, and so on. + + +.. _scp_protocol_error_filename: + +How do I fix 'protocol error: filename does not match request' when fetching a file? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Since release ``7.9p1`` of OpenSSH there is a `bug <https://bugzilla.mindrot.org/show_bug.cgi?id=2966>`_ +in the SCP client that can trigger this error on the Ansible controller when using SCP as the file transfer mechanism:: + + failed to transfer file to /tmp/ansible/file.txt\r\nprotocol error: filename does not match request + +In these releases, SCP tries to validate that the path of the file to fetch matches the requested path. +The validation +fails if the remote filename requires quotes to escape spaces or non-ascii characters in its path. To avoid this error: + +* Use SFTP instead of SCP by setting ``scp_if_ssh`` to ``smart`` (which tries SFTP first) or to ``False``. You can do this in one of four ways: + * Rely on the default setting, which is ``smart`` - this works if ``scp_if_ssh`` is not explicitly set anywhere + * Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>` in inventory: ``ansible_scp_if_ssh: False`` + * Set an environment variable on your control node: ``export ANSIBLE_SCP_IF_SSH=False`` + * Pass an environment variable when you run Ansible: ``ANSIBLE_SCP_IF_SSH=smart ansible-playbook`` + * Modify your ``ansible.cfg`` file: add ``scp_if_ssh=False`` to the ``[ssh_connection]`` section +* If you must use SCP, set the ``-T`` arg to tell the SCP client to ignore path validation. You can do this in one of three ways: + * Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>`: ``ansible_scp_extra_args=-T``, + * Export or pass an environment variable: ``ANSIBLE_SCP_EXTRA_ARGS=-T`` + * Modify your ``ansible.cfg`` file: add ``scp_extra_args=-T`` to the ``[ssh_connection]`` section + +.. note:: If you see an ``invalid argument`` error when using ``-T``, then your SCP client is not performing filename validation and will not trigger this error. + +.. _docs_contributions: + +How do I submit a change to the documentation? +++++++++++++++++++++++++++++++++++++++++++++++ + +Documentation for Ansible is kept in the main project git repository, and complete instructions +for contributing can be found in the docs README `viewable on GitHub <https://github.com/ansible/ansible/blob/devel/docs/docsite/README.md>`_. Thanks! + +.. _i_dont_see_my_question: + +I don't see my question here +++++++++++++++++++++++++++++ + +Please see the section below for a link to IRC and the Google Group, where you can ask your question there. + +.. seealso:: + + :ref:`working_with_playbooks` + An introduction to playbooks + :ref:`playbooks_best_practices` + Tips and tricks for playbooks + `User Mailing List <https://groups.google.com/group/ansible-project>`_ + Have a question? Stop by the google group! + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel diff --git a/docs/docsite/rst/reference_appendices/general_precedence.rst b/docs/docsite/rst/reference_appendices/general_precedence.rst new file mode 100644 index 00000000..90494b69 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/general_precedence.rst @@ -0,0 +1,140 @@ +.. _general_precedence_rules: + +Controlling how Ansible behaves: precedence rules +================================================= + +To give you maximum flexibility in managing your environments, Ansible offers many ways to control how Ansible behaves: how it connects to managed nodes, how it works once it has connected. +If you use Ansible to manage a large number of servers, network devices, and cloud resources, you may define Ansible behavior in several different places and pass that information to Ansible in several different ways. +This flexibility is convenient, but it can backfire if you do not understand the precedence rules. + +These precedence rules apply to any setting that can be defined in multiple ways (by configuration settings, command-line options, playbook keywords, variables). + +.. contents:: + :local: + +Precedence categories +--------------------- + +Ansible offers four sources for controlling its behavior. In order of precedence from lowest (most easily overridden) to highest (overrides all others), the categories are: + + * Configuration settings + * Command-line options + * Playbook keywords + * Variables + +Each category overrides any information from all lower-precedence categories. For example, a playbook keyword will override any configuration setting. + +Within each precedence category, specific rules apply. However, generally speaking, 'last defined' wins and overrides any previous definitions. + +Configuration settings +^^^^^^^^^^^^^^^^^^^^^^ + +:ref:`Configuration settings<ansible_configuration_settings>` include both values from the ``ansible.cfg`` file and environment variables. Within this category, values set in configuration files have lower precedence. Ansible uses the first ``ansible.cfg`` file it finds, ignoring all others. Ansible searches for ``ansible.cfg`` in these locations in order: + + * ``ANSIBLE_CONFIG`` (environment variable if set) + * ``ansible.cfg`` (in the current directory) + * ``~/.ansible.cfg`` (in the home directory) + * ``/etc/ansible/ansible.cfg`` + +Environment variables have a higher precedence than entries in ``ansible.cfg``. If you have environment variables set on your control node, they override the settings in whichever ``ansible.cfg`` file Ansible loads. The value of any given environment variable follows normal shell precedence: the last value defined overwrites previous values. + +Command-line options +^^^^^^^^^^^^^^^^^^^^ + +Any command-line option will override any configuration setting. + +When you type something directly at the command line, you may feel that your hand-crafted values should override all others, but Ansible does not work that way. Command-line options have low precedence - they override configuration only. They do not override playbook keywords, variables from inventory or variables from playbooks. + +You can override all other settings from all other sources in all other precedence categories at the command line by :ref:`general_precedence_extra_vars`, but that is not a command-line option, it is a way of passing a :ref:`variable<general_precedence_variables>`. + +At the command line, if you pass multiple values for a parameter that accepts only a single value, the last defined value wins. For example, this :ref:`ad-hoc task<intro_adhoc>` will connect as ``carol``, not as ``mike``:: + + ansible -u mike -m ping myhost -u carol + +Some parameters allow multiple values. In this case, Ansible will append all values from the hosts listed in inventory files inventory1 and inventory2:: + + ansible -i /path/inventory1 -i /path/inventory2 -m ping all + +The help for each :ref:`command-line tool<command_line_tools>` lists available options for that tool. + +Playbook keywords +^^^^^^^^^^^^^^^^^ + +Any :ref:`playbook keyword<playbook_keywords>` will override any command-line option and any configuration setting. + +Within playbook keywords, precedence flows with the playbook itself; the more specific wins against the more general: + +- play (most general) +- blocks/includes/imports/roles (optional and can contain tasks and each other) +- tasks (most specific) + +A simple example:: + + - hosts: all + connection: ssh + tasks: + - name: This task uses ssh. + ping: + + - name: This task uses paramiko. + connection: paramiko + ping: + +In this example, the ``connection`` keyword is set to ``ssh`` at the play level. The first task inherits that value, and connects using ``ssh``. The second task inherits that value, overrides it, and connects using ``paramiko``. +The same logic applies to blocks and roles as well. All tasks, blocks, and roles within a play inherit play-level keywords; any task, block, or role can override any keyword by defining a different value for that keyword within the task, block, or role. + +Remember that these are KEYWORDS, not variables. Both playbooks and variable files are defined in YAML but they have different significance. +Playbooks are the command or 'state description' structure for Ansible, variables are data we use to help make playbooks more dynamic. + +.. _general_precedence_variables: + +Variables +^^^^^^^^^ + +Any variable will override any playbook keyword, any command-line option, and any configuration setting. + +Variables that have equivalent playbook keywords, command-line options, and configuration settings are known as :ref:`connection_variables`. Originally designed for connection parameters, this category has expanded to include other core variables like the temporary directory and the python interpreter. + +Connection variables, like all variables, can be set in multiple ways and places. You can define variables for hosts and groups in :ref:`inventory<intro_inventory>`. You can define variables for tasks and plays in ``vars:`` blocks in :ref:`playbooks<about_playbooks>`. However, they are still variables - they are data, not keywords or configuration settings. Variables that override playbook keywords, command-line options, and configuration settings follow the same rules of :ref:`variable precedence <ansible_variable_precedence>` as any other variables. + +When set in a playbook, variables follow the same inheritance rules as playbook keywords. You can set a value for the play, then override it in a task, block, or role:: + + - hosts: cloud + gather_facts: false + become: yes + vars: + ansible_become_user: admin + tasks: + - name: This task uses admin as the become user. + dnf: + name: some-service + state: latest + - block: + - name: This task uses service-admin as the become user. + # a task to configure the new service + - name: This task also uses service-admin as the become user, defined in the block. + # second task to configure the service + vars: + ansible_become_user: service-admin + - name: This task (outside of the block) uses admin as the become user again. + service: + name: some-service + state: restarted + +Variable scope: how long is a value available? +"""""""""""""""""""""""""""""""""""""""""""""" + +Variable values set in a playbook exist only within the playbook object that defines them. These 'playbook object scope' variables are not available to subsequent objects, including other plays. + +Variable values associated directly with a host or group, including variables defined in inventory, by vars plugins, or using modules like :ref:`set_fact<set_fact_module>` and :ref:`include_vars<include_vars_module>`, are available to all plays. These 'host scope' variables are also available via the ``hostvars[]`` dictionary. + +.. _general_precedence_extra_vars: + +Using ``-e`` extra variables at the command line +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To override all other settings in all other categories, you can use extra variables: ``--extra-vars`` or ``-e`` at the command line. Values passed with ``-e`` are variables, not command-line options, and they will override configuration settings, command-line options, and playbook keywords as well as variables set elsewhere. For example, this task will connect as ``brian`` not as ``carol``:: + + ansible -u carol -e 'ansible_user=brian' -a whoami all + +You must specify both the variable name and the value with ``--extra-vars``. diff --git a/docs/docsite/rst/reference_appendices/glossary.rst b/docs/docsite/rst/reference_appendices/glossary.rst new file mode 100644 index 00000000..c1170c6d --- /dev/null +++ b/docs/docsite/rst/reference_appendices/glossary.rst @@ -0,0 +1,528 @@ +Glossary +======== + +The following is a list (and re-explanation) of term definitions used elsewhere in the Ansible documentation. + +Consult the documentation home page for the full documentation and to see the terms in context, but this should be a good resource +to check your knowledge of Ansible's components and understand how they fit together. It's something you might wish to read for review or +when a term comes up on the mailing list. + +.. glossary:: + + Action + An action is a part of a task that specifies which of the modules to + run and which arguments to pass to that module. Each task can have + only one action, but it may also have other parameters. + + Ad Hoc + Refers to running Ansible to perform some quick command, using + :command:`/usr/bin/ansible`, rather than the :term:`orchestration` + language, which is :command:`/usr/bin/ansible-playbook`. An example + of an ad hoc command might be rebooting 50 machines in your + infrastructure. Anything you can do ad hoc can be accomplished by + writing a :term:`playbook <playbooks>` and playbooks can also glue + lots of other operations together. + + Ansible (the package) + A software package (Python, deb, rpm, and so on) that contains ansible-base and a select group of collections. Playbooks that worked with Ansible 2.9 should still work with the Ansible 2.10 package. See the :file:`ansible-<version>.build` file in the release-specific directory at `ansible-build-data <https://github.com/ansible-community/ansible-build-data>`_ for a list of collections included in Ansible, as well as the included ``ansible-base`` version. + + ansible-base + New for 2.10. The installable package (RPM/Python/Deb package) generated from the `ansible/ansible repository <https://github.com/ansible/ansible>`_. Contains the command-line tools and the code for basic features and functions, such as copying module code to managed nodes. The ``ansible-base`` package includes a few modules and plugins and allows you to add others by installing collections. + + Ansible Galaxy + An `online resource <galaxy.ansible.com>`_ for finding and sharing Ansible community content. Also, the command-line utility that lets users install individual Ansible Collections, for example`` ansible-galaxy install community.crypto``. + + Async + Refers to a task that is configured to run in the background rather + than waiting for completion. If you have a long process that would + run longer than the SSH timeout, it would make sense to launch that + task in async mode. Async modes can poll for completion every so many + seconds or can be configured to "fire and forget", in which case + Ansible will not even check on the task again; it will just kick it + off and proceed to future steps. Async modes work with both + :command:`/usr/bin/ansible` and :command:`/usr/bin/ansible-playbook`. + + Callback Plugin + Refers to some user-written code that can intercept results from + Ansible and do something with them. Some supplied examples in the + GitHub project perform custom logging, send email, or even play sound + effects. + + Check Mode + Refers to running Ansible with the ``--check`` option, which does not + make any changes on the remote systems, but only outputs the changes + that might occur if the command ran without this flag. This is + analogous to so-called "dry run" modes in other systems, though the + user should be warned that this does not take into account unexpected + command failures or cascade effects (which is true of similar modes in + other systems). Use this to get an idea of what might happen, but do + not substitute it for a good staging environment. + + Collection + A packaging format for bundling and distributing Ansible content, including plugins, roles, modules, and more. Collections release independent of other collections or ``ansible-base`` so features can be available sooner to users. Some collections are packaged with Ansible (version 2.10 or later). You can install other collections (or other versions of collections) with ``ansible-galaxy collection install <namespace.collection>``. + + Collection name + The second part of a Fully Qualified Collection Name. The collection name divides the collection namespace and usually reflects the function of the collection content. For example, the ``cisco`` namespace might contain ``cisco.ios``, ``cisco.aci``, and ``cisco.nxos``, with content for managing the different network devices maintained by Cisco. + + community.general (collection) + A special collection managed by the Ansible Community Team containing all the modules and plugins which shipped in Ansible 2.9 that do ont have their own dedicated Collection. See `community.general <https://galaxy.ansible.com/community/general>`_` on Galaxy. + + community.network (collection) + Similar to ``community.general``, focusing on network content. `community.network <https://galaxy.ansible.com/community/network>`_` on Galaxy. + + Connection Plugin + By default, Ansible talks to remote machines through pluggable + libraries. Ansible uses native OpenSSH (:term:`SSH (Native)`) or + a Python implementation called :term:`paramiko`. OpenSSH is preferred + if you are using a recent version, and also enables some features like + Kerberos and jump hosts. This is covered in the :ref:`getting + started section <remote_connection_information>`. There are also + other connection types like ``accelerate`` mode, which must be + bootstrapped over one of the SSH-based connection types but is very + fast, and local mode, which acts on the local system. Users can also + write their own connection plugins. + + Conditionals + A conditional is an expression that evaluates to true or false that + decides whether a given task is executed on a given machine or not. + Ansible's conditionals are powered by the 'when' statement, which are + discussed in the :ref:`working_with_playbooks`. + + Declarative + An approach to achieving a task that uses a description of the + final state rather than a description of the sequence of steps + necessary to achieve that state. For a real world example, a + declarative specification of a task would be: "put me in California". + Depending on your current location, the sequence of steps to get you to + California may vary, and if you are already in California, nothing + at all needs to be done. Ansible's Resources are declarative; it + figures out the steps needed to achieve the final state. It also lets + you know whether or not any steps needed to be taken to get to the + final state. + + Diff Mode + A ``--diff`` flag can be passed to Ansible to show what changed on + modules that support it. You can combine it with ``--check`` to get a + good 'dry run'. File diffs are normally in unified diff format. + + Executor + A core software component of Ansible that is the power behind + :command:`/usr/bin/ansible` directly -- and corresponds to the + invocation of each task in a :term:`playbook <playbooks>`. The + Executor is something Ansible developers may talk about, but it's not + really user land vocabulary. + + Facts + Facts are simply things that are discovered about remote nodes. While + they can be used in :term:`playbooks` and templates just like + variables, facts are things that are inferred, rather than set. Facts + are automatically discovered by Ansible when running plays by + executing the internal :ref:`setup module <setup_module>` on the remote nodes. You + never have to call the setup module explicitly, it just runs, but it + can be disabled to save time if it is not needed or you can tell + ansible to collect only a subset of the full facts via the + ``gather_subset:`` option. For the convenience of users who are + switching from other configuration management systems, the fact module + will also pull in facts from the :program:`ohai` and :program:`facter` + tools if they are installed. These are fact libraries from Chef and + Puppet, respectively. (These may also be disabled via + ``gather_subset:``) + + Filter Plugin + A filter plugin is something that most users will never need to + understand. These allow for the creation of new :term:`Jinja2` + filters, which are more or less only of use to people who know what + Jinja2 filters are. If you need them, you can learn how to write them + in the :ref:`API docs section <developing_filter_plugins>`. + + Forks + Ansible talks to remote nodes in parallel and the level of parallelism + can be set either by passing ``--forks`` or editing the default in + a configuration file. The default is a very conservative five (5) + forks, though if you have a lot of RAM, you can easily set this to + a value like 50 for increased parallelism. + + Fully Qualified Collection Name (FQCN) + The full definition of a module, plugin, or role hosted within a collection, in the form <namespace.collection.content_name>. Allows a Playbook to refer to a specific module or plugin from a specific source in an unambiguous manner, for example, ``community.grafana.grafana_dashboard``. The FQCN is required when you want to specify the exact source of a plugin. For example, if multiple collections contain a module plugin called ``user``, the FQCN specifies which one to use for a given task. When you have multiple collections installed, the FQCN is always the explicit and authoritative indicator of which collection to search for the correct plugin for each task. + + Gather Facts (Boolean) + :term:`Facts` are mentioned above. Sometimes when running a multi-play + :term:`playbook <playbooks>`, it is desirable to have some plays that + don't bother with fact computation if they aren't going to need to + utilize any of these values. Setting ``gather_facts: False`` on + a playbook allows this implicit fact gathering to be skipped. + + Globbing + Globbing is a way to select lots of hosts based on wildcards, rather + than the name of the host specifically, or the name of the group they + are in. For instance, it is possible to select ``ww*`` to match all + hosts starting with ``www``. This concept is pulled directly from + :program:`Func`, one of Michael DeHaan's (an Ansible Founder) earlier + projects. In addition to basic globbing, various set operations are + also possible, such as 'hosts in this group and not in another group', + and so on. + + Group + A group consists of several hosts assigned to a pool that can be + conveniently targeted together, as well as given variables that they + share in common. + + Group Vars + The :file:`group_vars/` files are files that live in a directory + alongside an inventory file, with an optional filename named after + each group. This is a convenient place to put variables that are + provided to a given group, especially complex data structures, so that + these variables do not have to be embedded in the :term:`inventory` + file or :term:`playbook <playbooks>`. + + Handlers + Handlers are just like regular tasks in an Ansible + :term:`playbook <playbooks>` (see :term:`Tasks`) but are only run if + the Task contains a ``notify`` directive and also indicates that it + changed something. For example, if a config file is changed, then the + task referencing the config file templating operation may notify + a service restart handler. This means services can be bounced only if + they need to be restarted. Handlers can be used for things other than + service restarts, but service restarts are the most common usage. + + Host + A host is simply a remote machine that Ansible manages. They can have + individual variables assigned to them, and can also be organized in + groups. All hosts have a name they can be reached at (which is either + an IP address or a domain name) and, optionally, a port number, if they + are not to be accessed on the default SSH port. + + Host Specifier + Each :term:`Play <plays>` in Ansible maps a series of :term:`tasks` (which define the role, + purpose, or orders of a system) to a set of systems. + + This ``hosts:`` directive in each play is often called the hosts specifier. + + It may select one system, many systems, one or more groups, or even + some hosts that are in one group and explicitly not in another. + + Host Vars + Just like :term:`Group Vars`, a directory alongside the inventory file named + :file:`host_vars/` can contain a file named after each hostname in the + inventory file, in :term:`YAML` format. This provides a convenient place to + assign variables to the host without having to embed them in the + :term:`inventory` file. The Host Vars file can also be used to define complex + data structures that can't be represented in the inventory file. + + Idempotency + An operation is idempotent if the result of performing it once is + exactly the same as the result of performing it repeatedly without + any intervening actions. + + Includes + The idea that :term:`playbook <playbooks>` files (which are nothing + more than lists of :term:`plays`) can include other lists of plays, + and task lists can externalize lists of :term:`tasks` in other files, + and similarly with :term:`handlers`. Includes can be parameterized, + which means that the loaded file can pass variables. For instance, an + included play for setting up a WordPress blog may take a parameter + called ``user`` and that play could be included more than once to + create a blog for both ``alice`` and ``bob``. + + Inventory + A file (by default, Ansible uses a simple INI format) that describes + :term:`Hosts <Host>` and :term:`Groups <Group>` in Ansible. Inventory + can also be provided via an :term:`Inventory Script` (sometimes called + an "External Inventory Script"). + + Inventory Script + A very simple program (or a complicated one) that looks up + :term:`hosts <Host>`, :term:`group` membership for hosts, and variable + information from an external resource -- whether that be a SQL + database, a CMDB solution, or something like LDAP. This concept was + adapted from Puppet (where it is called an "External Nodes + Classifier") and works more or less exactly the same way. + + Jinja2 + Jinja2 is the preferred templating language of Ansible's template + module. It is a very simple Python template language that is + generally readable and easy to write. + + JSON + Ansible uses JSON for return data from remote modules. This allows + modules to be written in any language, not just Python. + + Lazy Evaluation + In general, Ansible evaluates any variables in + :term:`playbook <playbooks>` content at the last possible second, + which means that if you define a data structure that data structure + itself can define variable values within it, and everything "just + works" as you would expect. This also means variable strings can + include other variables inside of those strings. + + Library + A collection of modules made available to :command:`/usr/bin/ansible` + or an Ansible :term:`playbook <playbooks>`. + + Limit Groups + By passing ``--limit somegroup`` to :command:`ansible` or + :command:`ansible-playbook`, the commands can be limited to a subset + of :term:`hosts <Host>`. For instance, this can be used to run + a :term:`playbook <playbooks>` that normally targets an entire set of + servers to one particular server. + + Local Action + A local_action directive in a :term:`playbook <playbooks>` targeting + remote machines means that the given step will actually occur on the + local machine, but that the variable ``{{ ansible_hostname }}`` can be + passed in to reference the remote hostname being referred to in that + step. This can be used to trigger, for example, an rsync operation. + + Local Connection + By using ``connection: local`` in a :term:`playbook <playbooks>`, or + passing ``-c local`` to :command:`/usr/bin/ansible`, this indicates + that we are managing the local host and not a remote machine. + + Lookup Plugin + A lookup plugin is a way to get data into Ansible from the outside world. + Lookup plugins are an extension of Jinja2 and can be accessed in templates, for example, + ``{{ lookup('file','/path/to/file') }}``. + These are how such things as ``with_items``, are implemented. + There are also lookup plugins like ``file`` which loads data from + a file and ones for querying environment variables, DNS text records, + or key value stores. + + Loops + Generally, Ansible is not a programming language. It prefers to be + more declarative, though various constructs like ``loop`` allow + a particular task to be repeated for multiple items in a list. + Certain modules, like :ref:`yum <yum_module>` and :ref:`apt <apt_module>`, actually take + lists directly, and can install all packages given in those lists + within a single transaction, dramatically speeding up total time to + configuration, so they can be used without loops. + + Modules + Modules are the units of work that Ansible ships out to remote + machines. Modules are kicked off by either + :command:`/usr/bin/ansible` or :command:`/usr/bin/ansible-playbook` + (where multiple tasks use lots of different modules in conjunction). + Modules can be implemented in any language, including Perl, Bash, or + Ruby -- but can leverage some useful communal library code if written + in Python. Modules just have to return :term:`JSON`. Once modules are + executed on remote machines, they are removed, so no long running + daemons are used. Ansible refers to the collection of available + modules as a :term:`library`. + + Multi-Tier + The concept that IT systems are not managed one system at a time, but + by interactions between multiple systems and groups of systems in + well defined orders. For instance, a web server may need to be + updated before a database server and pieces on the web server may + need to be updated after *THAT* database server and various load + balancers and monitoring servers may need to be contacted. Ansible + models entire IT topologies and workflows rather than looking at + configuration from a "one system at a time" perspective. + + Namespace + The first part of a fully qualified collection name, the namespace usually reflects a functional content category. Example: in ``cisco.ios.ios_config``, ``cisco`` is the namespace. Namespaces are reserved and distributed by Red Hat at Red Hat's discretion. Many, but not all, namespaces will correspond with vendor names. See `Galaxy namespaces <https://galaxy.ansible.com/docs/contributing/namespaces.html#galaxy-namespaces>`_ on the Galaxy docsite for namespace requirements. + + Notify + The act of a :term:`task <tasks>` registering a change event and + informing a :term:`handler <handlers>` task that another + :term:`action` needs to be run at the end of the :term:`play <plays>`. If + a handler is notified by multiple tasks, it will still be run only + once. Handlers are run in the order they are listed, not in the order + that they are notified. + + Orchestration + Many software automation systems use this word to mean different + things. Ansible uses it as a conductor would conduct an orchestra. + A datacenter or cloud architecture is full of many systems, playing + many parts -- web servers, database servers, maybe load balancers, + monitoring systems, continuous integration systems, and so on. In + performing any process, it is necessary to touch systems in particular + orders, often to simulate rolling updates or to deploy software + correctly. Some system may perform some steps, then others, then + previous systems already processed may need to perform more steps. + Along the way, emails may need to be sent or web services contacted. + Ansible orchestration is all about modeling that kind of process. + + paramiko + By default, Ansible manages machines over SSH. The library that + Ansible uses by default to do this is a Python-powered library called + paramiko. The paramiko library is generally fast and easy to manage, + though users who want to use Kerberos or Jump Hosts may wish to switch + to a native SSH binary such as OpenSSH by specifying the connection + type in their :term:`playbooks`, or using the ``-c ssh`` flag. + + Playbooks + Playbooks are the language by which Ansible orchestrates, configures, + administers, or deploys systems. They are called playbooks partially + because it's a sports analogy, and it's supposed to be fun using them. + They aren't workbooks :) + + Plays + A :term:`playbook <playbooks>` is a list of plays. A play is + minimally a mapping between a set of :term:`hosts <Host>` selected by a host + specifier (usually chosen by :term:`groups <Group>` but sometimes by + hostname :term:`globs <Globbing>`) and the :term:`tasks` which run on those + hosts to define the role that those systems will perform. There can be + one or many plays in a playbook. + + Pull Mode + By default, Ansible runs in :term:`push mode`, which allows it very + fine-grained control over when it talks to each system. Pull mode is + provided for when you would rather have nodes check in every N minutes + on a particular schedule. It uses a program called + :command:`ansible-pull` and can also be set up (or reconfigured) using + a push-mode :term:`playbook <playbooks>`. Most Ansible users use push + mode, but pull mode is included for variety and the sake of having + choices. + + :command:`ansible-pull` works by checking configuration orders out of + git on a crontab and then managing the machine locally, using the + :term:`local connection` plugin. + + Push Mode + Push mode is the default mode of Ansible. In fact, it's not really + a mode at all -- it's just how Ansible works when you aren't thinking + about it. Push mode allows Ansible to be fine-grained and conduct + nodes through complex orchestration processes without waiting for them + to check in. + + Register Variable + The result of running any :term:`task <tasks>` in Ansible can be + stored in a variable for use in a template or a conditional statement. + The keyword used to define the variable is called ``register``, taking + its name from the idea of registers in assembly programming (though + Ansible will never feel like assembly programming). There are an + infinite number of variable names you can use for registration. + + Resource Model + Ansible modules work in terms of resources. For instance, the + :ref:`file module <file_module>` will select a particular file and ensure + that the attributes of that resource match a particular model. As an + example, we might wish to change the owner of :file:`/etc/motd` to + ``root`` if it is not already set to ``root``, or set its mode to + ``0644`` if it is not already set to ``0644``. The resource models + are :term:`idempotent <idempotency>` meaning change commands are not + run unless needed, and Ansible will bring the system back to a desired + state regardless of the actual state -- rather than you having to tell + it how to get to the state. + + Roles + Roles are units of organization in Ansible. Assigning a role to + a group of :term:`hosts <Host>` (or a set of :term:`groups <group>`, + or :term:`host patterns <Globbing>`, and so on) implies that they should + implement a specific behavior. A role may include applying certain + variable values, certain :term:`tasks`, and certain :term:`handlers` + -- or just one or more of these things. Because of the file structure + associated with a role, roles become redistributable units that allow + you to share behavior among :term:`playbooks` -- or even with other users. + + Rolling Update + The act of addressing a number of nodes in a group N at a time to + avoid updating them all at once and bringing the system offline. For + instance, in a web topology of 500 nodes handling very large volume, + it may be reasonable to update 10 or 20 machines at a time, moving on + to the next 10 or 20 when done. The ``serial:`` keyword in an Ansible + :term:`playbooks` control the size of the rolling update pool. The + default is to address the batch size all at once, so this is something + that you must opt-in to. OS configuration (such as making sure config + files are correct) does not typically have to use the rolling update + model, but can do so if desired. + + Serial + .. seealso:: + + :term:`Rolling Update` + + Sudo + Ansible does not require root logins, and since it's daemonless, + definitely does not require root level daemons (which can be + a security concern in sensitive environments). Ansible can log in and + perform many operations wrapped in a sudo command, and can work with + both password-less and password-based sudo. Some operations that + don't normally work with sudo (like scp file transfer) can be achieved + with Ansible's :ref:`copy <copy_module>`, :ref:`template <template_module>`, and + :ref:`fetch <fetch_module>` modules while running in sudo mode. + + SSH (Native) + Native OpenSSH as an Ansible transport is specified with ``-c ssh`` + (or a config file, or a directive in the :term:`playbook <playbooks>`) + and can be useful if wanting to login via Kerberized SSH or using SSH + jump hosts, and so on. In 1.2.1, ``ssh`` will be used by default if the + OpenSSH binary on the control machine is sufficiently new. + Previously, Ansible selected ``paramiko`` as a default. Using + a client that supports ``ControlMaster`` and ``ControlPersist`` is + recommended for maximum performance -- if you don't have that and + don't need Kerberos, jump hosts, or other features, ``paramiko`` is + a good choice. Ansible will warn you if it doesn't detect + ControlMaster/ControlPersist capability. + + Tags + Ansible allows tagging resources in a :term:`playbook <playbooks>` + with arbitrary keywords, and then running only the parts of the + playbook that correspond to those keywords. For instance, it is + possible to have an entire OS configuration, and have certain steps + labeled ``ntp``, and then run just the ``ntp`` steps to reconfigure + the time server information on a remote host. + + Task + :term:`Playbooks` exist to run tasks. Tasks combine an :term:`action` + (a module and its arguments) with a name and optionally some other + keywords (like :term:`looping directives <loops>`). :term:`Handlers` + are also tasks, but they are a special kind of task that do not run + unless they are notified by name when a task reports an underlying + change on a remote system. + + Tasks + A list of :term:`Task`. + + Templates + Ansible can easily transfer files to remote systems but often it is + desirable to substitute variables in other files. Variables may come + from the :term:`inventory` file, :term:`Host Vars`, :term:`Group + Vars`, or :term:`Facts`. Templates use the :term:`Jinja2` template + engine and can also include logical constructs like loops and if + statements. + + Transport + Ansible uses :term:``Connection Plugins`` to define types of available + transports. These are simply how Ansible will reach out to managed + systems. Transports included are :term:`paramiko`, + :term:`ssh <SSH (Native)>` (using OpenSSH), and + :term:`local <Local Connection>`. + + When + An optional conditional statement attached to a :term:`task <tasks>` that is used to + determine if the task should run or not. If the expression following + the ``when:`` keyword evaluates to false, the task will be ignored. + + Vars (Variables) + As opposed to :term:`Facts`, variables are names of values (they can + be simple scalar values -- integers, booleans, strings) or complex + ones (dictionaries/hashes, lists) that can be used in templates and + :term:`playbooks`. They are declared things, not things that are + inferred from the remote system's current state or nature (which is + what Facts are). + + YAML + Ansible does not want to force people to write programming language + code to automate infrastructure, so Ansible uses YAML to define + :term:`playbook <playbooks>` configuration languages and also variable + files. YAML is nice because it has a minimum of syntax and is very + clean and easy for people to skim. It is a good data format for + configuration files and humans, but also machine readable. Ansible's + usage of YAML stemmed from Michael DeHaan's first use of it inside of + Cobbler around 2006. YAML is fairly popular in the dynamic language + community and the format has libraries available for serialization in + many languages (Python, Perl, Ruby, and so on). + +.. seealso:: + + :ref:`ansible_faq` + Frequently asked questions + :ref:`working_with_playbooks` + An introduction to playbooks + :ref:`playbooks_best_practices` + Tips and tricks for playbooks + `User Mailing List <https://groups.google.com/group/ansible-devel>`_ + Have a question? Stop by the google group! + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel diff --git a/docs/docsite/rst/reference_appendices/interpreter_discovery.rst b/docs/docsite/rst/reference_appendices/interpreter_discovery.rst new file mode 100644 index 00000000..9fa7d585 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/interpreter_discovery.rst @@ -0,0 +1,51 @@ +.. _interpreter_discovery: + +Interpreter Discovery +===================== + +Most Ansible modules that execute under a POSIX environment require a Python +interpreter on the target host. Unless configured otherwise, Ansible will +attempt to discover a suitable Python interpreter on each target host +the first time a Python module is executed for that host. + +To control the discovery behavior: + +* for individual hosts and groups, use the ``ansible_python_interpreter`` inventory variable +* globally, use the ``interpreter_python`` key in the ``[defaults]`` section of ``ansible.cfg`` + +Use one of the following values: + +auto_legacy : (default in 2.8) + Detects the target OS platform, distribution, and version, then consults a + table listing the correct Python interpreter and path for each + platform/distribution/version. If an entry is found, and ``/usr/bin/python`` is absent, uses the discovered interpreter (and path). If an entry + is found, and ``/usr/bin/python`` is present, uses ``/usr/bin/python`` + and issues a warning. + This exception provides temporary compatibility with previous versions of + Ansible that always defaulted to ``/usr/bin/python``, so if you have + installed Python and other dependencies at ``/usr/bin/python`` on some hosts, + Ansible will find and use them with this setting. + If no entry is found, or the listed Python is not present on the + target host, searches a list of common Python interpreter + paths and uses the first one found; also issues a warning that future + installation of another Python interpreter could alter the one chosen. + +auto : (future default in 2.12) + Detects the target OS platform, distribution, and version, then consults a + table listing the correct Python interpreter and path for each + platform/distribution/version. If an entry is found, uses the discovered + interpreter. + If no entry is found, or the listed Python is not present on the + target host, searches a list of common Python interpreter + paths and uses the first one found; also issues a warning that future + installation of another Python interpreter could alter the one chosen. + +auto_legacy_silent + Same as ``auto_legacy``, but does not issue warnings. + +auto_silent + Same as ``auto``, but does not issue warnings. + +You can still set ``ansible_python_interpreter`` to a specific path at any +variable level (for example, in host_vars, in vars files, in playbooks, and so on). +Setting a specific path completely disables automatic interpreter discovery; Ansible always uses the path specified. diff --git a/docs/docsite/rst/reference_appendices/logging.rst b/docs/docsite/rst/reference_appendices/logging.rst new file mode 100644 index 00000000..6fbd0440 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/logging.rst @@ -0,0 +1,14 @@ +********************** +Logging Ansible output +********************** + +By default Ansible sends output about plays, tasks, and module arguments to your screen (STDOUT) on the control node. If you want to capture Ansible output in a log, you have three options: + +* To save Ansible output in a single log on the control node, set the ``log_path`` :ref:`configuration file setting <intro_configuration>`. You may also want to set ``display_args_to_stdout``, which helps to differentiate similar tasks by including variable values in the Ansible output. +* To save Ansible output in separate logs, one on each managed node, set the ``no_target_syslog`` and ``syslog_facility`` :ref:`configuration file settings <intro_configuration>`. +* To save Ansible output to a secure database, use :ref:`Ansible Tower <ansible_tower>`. Tower allows you to review history based on hosts, projects, and particular inventories over time, using graphs and/or a REST API. + +Protecting sensitive data with ``no_log`` +========================================= + +If you save Ansible output to a log, you expose any secret data in your Ansible output, such as passwords and user names. To keep sensitive values out of your logs, mark tasks that expose them with the ``no_log: True`` attribute. However, the ``no_log`` attribute does not affect debugging output, so be careful not to debug playbooks in a production environment. See :ref:`keep_secret_data` for an example. diff --git a/docs/docsite/rst/reference_appendices/module_utils.rst b/docs/docsite/rst/reference_appendices/module_utils.rst new file mode 100644 index 00000000..7fa4620c --- /dev/null +++ b/docs/docsite/rst/reference_appendices/module_utils.rst @@ -0,0 +1,27 @@ +.. _ansible.module_utils: +.. _module_utils: + +*************************************************************** +Ansible Reference: Module Utilities +*************************************************************** + +This page documents utilities intended to be helpful when writing +Ansible modules in Python. + + +AnsibleModule +-------------- + +To use this functionality, include ``from ansible.module_utils.basic import AnsibleModule`` in your module. + +.. autoclass:: ansible.module_utils.basic.AnsibleModule + :members: + :noindex: + +Basic +------ + +To use this functionality, include ``import ansible.module_utils.basic`` in your module. + +.. automodule:: ansible.module_utils.basic + :members: diff --git a/docs/docsite/rst/reference_appendices/python_3_support.rst b/docs/docsite/rst/reference_appendices/python_3_support.rst new file mode 100644 index 00000000..da06023c --- /dev/null +++ b/docs/docsite/rst/reference_appendices/python_3_support.rst @@ -0,0 +1,95 @@ +================ +Python 3 Support +================ + +Ansible 2.5 and above work with Python 3. Previous to 2.5, using Python 3 was +considered a tech preview. This topic discusses how to set up your controller and managed machines +to use Python 3. + +.. note:: On the controller we support Python 3.5 or greater and Python 2.7 or greater. Module-side, we support Python 3.5 or greater and Python 2.6 or greater. + +On the controller side +---------------------- + +The easiest way to run :command:`/usr/bin/ansible` under Python 3 is to install it with the Python3 +version of pip. This will make the default :command:`/usr/bin/ansible` run with Python3: + +.. code-block:: shell + + $ pip3 install ansible + $ ansible --version | grep "python version" + python version = 3.6.2 (default, Sep 22 2017, 08:28:09) [GCC 7.2.1 20170915 (Red Hat 7.2.1-2)] + +If you are running Ansible :ref:`from_source` and want to use Python 3 with your source checkout, run your +command via ``python3``. For example: + +.. code-block:: shell + + $ source ./hacking/env-setup + $ python3 $(which ansible) localhost -m ping + $ python3 $(which ansible-playbook) sample-playbook.yml + +.. note:: Individual Linux distribution packages may be packaged for Python2 or Python3. When running from + distro packages you'll only be able to use Ansible with the Python version for which it was + installed. Sometimes distros will provide a means of installing for several Python versions + (via a separate package or via some commands that are run after install). You'll need to check + with your distro to see if that applies in your case. + + +Using Python 3 on the managed machines with commands and playbooks +------------------------------------------------------------------ + +* Ansible will automatically detect and use Python 3 on many platforms that ship with it. To explicitly configure a + Python 3 interpreter, set the ``ansible_python_interpreter`` inventory variable at a group or host level to the + location of a Python 3 interpreter, such as :command:`/usr/bin/python3`. The default interpreter path may also be + set in ``ansible.cfg``. + +.. seealso:: :ref:`interpreter_discovery` for more information. + +.. code-block:: ini + + # Example inventory that makes an alias for localhost that uses Python3 + localhost-py3 ansible_host=localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3 + + # Example of setting a group of hosts to use Python3 + [py3-hosts] + ubuntu16 + fedora27 + + [py3-hosts:vars] + ansible_python_interpreter=/usr/bin/python3 + +.. seealso:: :ref:`intro_inventory` for more information. + +* Run your command or playbook: + +.. code-block:: shell + + $ ansible localhost-py3 -m ping + $ ansible-playbook sample-playbook.yml + + +Note that you can also use the `-e` command line option to manually +set the python interpreter when you run a command. This can be useful if you want to test whether +a specific module or playbook has any bugs under Python 3. For example: + +.. code-block:: shell + + $ ansible localhost -m ping -e 'ansible_python_interpreter=/usr/bin/python3' + $ ansible-playbook sample-playbook.yml -e 'ansible_python_interpreter=/usr/bin/python3' + +What to do if an incompatibility is found +----------------------------------------- + +We have spent several releases squashing bugs and adding new tests so that Ansible's core feature +set runs under both Python 2 and Python 3. However, bugs may still exist in edge cases and many of +the modules shipped with Ansible are maintained by the community and not all of those may be ported +yet. + +If you find a bug running under Python 3 you can submit a bug report on `Ansible's GitHub project +<https://github.com/ansible/ansible/issues/>`_. Be sure to mention Python3 in the bug report so +that the right people look at it. + +If you would like to fix the code and submit a pull request on github, you can +refer to :ref:`developing_python_3` for information on how we fix +common Python3 compatibility issues in the Ansible codebase. diff --git a/docs/docsite/rst/reference_appendices/release_and_maintenance.rst b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst new file mode 100644 index 00000000..eef77130 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst @@ -0,0 +1,33 @@ +.. _release_and_maintenance: + +Release and maintenance +======================= + +.. _release_cycle: +.. _release_schedule: +.. _support_life: +.. _methods: +.. _development_and_stable_version_maintenance_workflow: +.. _release_changelogs: +.. _release_freezing: + +Please go to `the devel release and maintenance page <https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html>`_ for up to date information. + +.. note:: + + This link takes you to a different version of the Ansible documentation. Use the version selection on the left or your browser back button to return to this version of the documentation. + +.. seealso:: + + :ref:`community_committer_guidelines` + Guidelines for Ansible core contributors and maintainers + :ref:`testing_strategies` + Testing strategies + :ref:`ansible_community_guide` + Community information and contributing + `Ansible release tarballs <https://releases.ansible.com/ansible/>`_ + Ansible release tarballs + `Development Mailing List <https://groups.google.com/group/ansible-devel>`_ + Mailing list for development topics + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel diff --git a/docs/docsite/rst/reference_appendices/special_variables.rst b/docs/docsite/rst/reference_appendices/special_variables.rst new file mode 100644 index 00000000..e4ecc177 --- /dev/null +++ b/docs/docsite/rst/reference_appendices/special_variables.rst @@ -0,0 +1,167 @@ +.. _special_variables: + +Special Variables +================= + +Magic variables +--------------- +These variables cannot be set directly by the user; Ansible will always override them to reflect internal state. + +ansible_check_mode + Boolean that indicates if we are in check mode or not + +ansible_config_file + The full path of used Ansible configuration file + +ansible_dependent_role_names + The names of the roles currently imported into the current play as dependencies of other plays + +ansible_diff_mode + Boolean that indicates if we are in diff mode or not + +ansible_forks + Integer reflecting the number of maximum forks available to this run + +ansible_inventory_sources + List of sources used as inventory + +ansible_limit + Contents of the ``--limit`` CLI option for the current execution of Ansible + +ansible_loop + A dictionary/map containing extended loop information when enabled via ``loop_control.extended`` + +ansible_loop_var + The name of the value provided to ``loop_control.loop_var``. Added in ``2.8`` + +ansible_index_var + The name of the value provided to ``loop_control.index_var``. Added in ``2.9`` + +ansible_parent_role_names + When the current role is being executed by means of an :ref:`include_role <include_role_module>` or :ref:`import_role <import_role_module>` action, this variable contains a list of all parent roles, with the most recent role (in other words, the role that included/imported this role) being the first item in the list. + When multiple inclusions occur, this list lists the *last* role (in other words, the role that included this role) as the *first* item in the list. It is also possible that a specific role exists more than once in this list. + + For example: When role **A** includes role **B**, inside role B, ``ansible_parent_role_names`` will equal to ``['A']``. If role **B** then includes role **C**, the list becomes ``['B', 'A']``. + +ansible_parent_role_paths + When the current role is being executed by means of an :ref:`include_role <include_role_module>` or :ref:`import_role <import_role_module>` action, this variable contains a list of all parent roles, with the most recent role (in other words, the role that included/imported this role) being the first item in the list. + Please refer to ``ansible_parent_role_names`` for the order of items in this list. + +ansible_play_batch + List of active hosts in the current play run limited by the serial, aka 'batch'. Failed/Unreachable hosts are not considered 'active'. + +ansible_play_hosts + List of hosts in the current play run, not limited by the serial. Failed/Unreachable hosts are included in this list. + +ansible_play_hosts_all + List of all the hosts that were targeted by the play + +ansible_play_role_names + The names of the roles currently imported into the current play. This list does **not** contain the role names that are + implicitly included via dependencies. + +ansible_playbook_python + The path to the python interpreter being used by Ansible on the controller + +ansible_role_names + The names of the roles currently imported into the current play, or roles referenced as dependencies of the roles + imported into the current play. + +ansible_role_name + The fully qualified collection role name, in the format of ``namespace.collection.role_name`` + +ansible_collection_name + The name of the collection the task that is executing is a part of. In the format of ``namespace.collection`` + +ansible_run_tags + Contents of the ``--tags`` CLI option, which specifies which tags will be included for the current run. + +ansible_search_path + Current search path for action plugins and lookups, in other words, where we search for relative paths when you do ``template: src=myfile`` + +ansible_skip_tags + Contents of the ``--skip-tags`` CLI option, which specifies which tags will be skipped for the current run. + +ansible_verbosity + Current verbosity setting for Ansible + +ansible_version + Dictionary/map that contains information about the current running version of ansible, it has the following keys: full, major, minor, revision and string. + +group_names + List of groups the current host is part of + +groups + A dictionary/map with all the groups in inventory and each group has the list of hosts that belong to it + +hostvars + A dictionary/map with all the hosts in inventory and variables assigned to them + +inventory_hostname + The inventory name for the 'current' host being iterated over in the play + +inventory_hostname_short + The short version of `inventory_hostname` + +inventory_dir + The directory of the inventory source in which the `inventory_hostname` was first defined + +inventory_file + The file name of the inventory source in which the `inventory_hostname` was first defined + +omit + Special variable that allows you to 'omit' an option in a task, for example ``- user: name=bob home={{ bobs_home|default(omit) }}`` + +play_hosts + Deprecated, the same as ansible_play_batch + +ansible_play_name + The name of the currently executed play. Added in ``2.8``. + +playbook_dir + The path to the directory of the playbook that was passed to the ``ansible-playbook`` command line. + +role_name + The name of the role currently being executed. + +role_names + Deprecated, the same as ansible_play_role_names + +role_path + The path to the dir of the currently running role + +Facts +----- +These are variables that contain information pertinent to the current host (`inventory_hostname`). They are only available if gathered first. See :ref:`vars_and_facts` for more information. + +ansible_facts + Contains any facts gathered or cached for the `inventory_hostname` + Facts are normally gathered by the :ref:`setup <setup_module>` module automatically in a play, but any module can return facts. + +ansible_local + Contains any 'local facts' gathered or cached for the `inventory_hostname`. + The keys available depend on the custom facts created. + See the :ref:`setup <setup_module>` module and :ref:`local_facts` for more details. + +.. _connection_variables: + +Connection variables +--------------------- +Connection variables are normally used to set the specifics on how to execute actions on a target. Most of them correspond to connection plugins, but not all are specific to them; other plugins like shell, terminal and become are normally involved. +Only the common ones are described as each connection/become/shell/etc plugin can define its own overrides and specific variables. +See :ref:`general_precedence_rules` for how connection variables interact with :ref:`configuration settings<ansible_configuration_settings>`, :ref:`command-line options<command_line_tools>`, and :ref:`playbook keywords<playbook_keywords>`. + +ansible_become_user + The user Ansible 'becomes' after using privilege escalation. This must be available to the 'login user'. + +ansible_connection + The connection plugin actually used for the task on the target host. + +ansible_host + The ip/name of the target host to use instead of `inventory_hostname`. + +ansible_python_interpreter + The path to the Python executable Ansible should use on the target host. + +ansible_user + The user Ansible 'logs in' as. diff --git a/docs/docsite/rst/reference_appendices/test_strategies.rst b/docs/docsite/rst/reference_appendices/test_strategies.rst new file mode 100644 index 00000000..01da667a --- /dev/null +++ b/docs/docsite/rst/reference_appendices/test_strategies.rst @@ -0,0 +1,275 @@ +.. _testing_strategies: + +Testing Strategies +================== + +.. _testing_intro: + +Integrating Testing With Ansible Playbooks +`````````````````````````````````````````` + +Many times, people ask, "how can I best integrate testing with Ansible playbooks?" There are many options. Ansible is actually designed +to be a "fail-fast" and ordered system, therefore it makes it easy to embed testing directly in Ansible playbooks. In this chapter, +we'll go into some patterns for integrating tests of infrastructure and discuss the right level of testing that may be appropriate. + +.. note:: This is a chapter about testing the application you are deploying, not the chapter on how to test Ansible modules during development. For that content, please hop over to the Development section. + +By incorporating a degree of testing into your deployment workflow, there will be fewer surprises when code hits production and, in many cases, +tests can be leveraged in production to prevent failed updates from migrating across an entire installation. Since it's push-based, it's +also very easy to run the steps on the localhost or testing servers. Ansible lets you insert as many checks and balances into your upgrade workflow as you would like to have. + +The Right Level of Testing +`````````````````````````` + +Ansible resources are models of desired-state. As such, it should not be necessary to test that services are started, packages are +installed, or other such things. Ansible is the system that will ensure these things are declaratively true. Instead, assert these +things in your playbooks. + +.. code-block:: yaml + + tasks: + - service: + name: foo + state: started + enabled: yes + +If you think the service may not be started, the best thing to do is request it to be started. If the service fails to start, Ansible +will yell appropriately. (This should not be confused with whether the service is doing something functional, which we'll show more about how to +do later). + +.. _check_mode_drift: + +Check Mode As A Drift Test +`````````````````````````` + +In the above setup, `--check` mode in Ansible can be used as a layer of testing as well. If running a deployment playbook against an +existing system, using the `--check` flag to the `ansible` command will report if Ansible thinks it would have had to have made any changes to +bring the system into a desired state. + +This can let you know up front if there is any need to deploy onto the given system. Ordinarily scripts and commands don't run in check mode, so if you +want certain steps to execute in normal mode even when the `--check` flag is used, such as calls to the script module, disable check mode for those tasks:: + + + roles: + - webserver + + tasks: + - script: verify.sh + check_mode: no + +Modules That Are Useful for Testing +``````````````````````````````````` + +Certain playbook modules are particularly good for testing. Below is an example that ensures a port is open:: + + tasks: + + - wait_for: + host: "{{ inventory_hostname }}" + port: 22 + delegate_to: localhost + +Here's an example of using the URI module to make sure a web service returns:: + + tasks: + + - action: uri url=http://www.example.com return_content=yes + register: webpage + + - fail: + msg: 'service is not happy' + when: "'AWESOME' not in webpage.content" + +It's easy to push an arbitrary script (in any language) on a remote host and the script will automatically fail if it has a non-zero return code:: + + tasks: + + - script: test_script1 + - script: test_script2 --parameter value --parameter2 value + +If using roles (you should be, roles are great!), scripts pushed by the script module can live in the 'files/' directory of a role. + +And the assert module makes it very easy to validate various kinds of truth:: + + tasks: + + - shell: /usr/bin/some-command --parameter value + register: cmd_result + + - assert: + that: + - "'not ready' not in cmd_result.stderr" + - "'gizmo enabled' in cmd_result.stdout" + +Should you feel the need to test for existence of files that are not declaratively set by your Ansible configuration, the 'stat' module is a great choice:: + + tasks: + + - stat: + path: /path/to/something + register: p + + - assert: + that: + - p.stat.exists and p.stat.isdir + + +As mentioned above, there's no need to check things like the return codes of commands. Ansible is checking them automatically. +Rather than checking for a user to exist, consider using the user module to make it exist. + +Ansible is a fail-fast system, so when there is an error creating that user, it will stop the playbook run. You do not have +to check up behind it. + +Testing Lifecycle +````````````````` + +If writing some degree of basic validation of your application into your playbooks, they will run every time you deploy. + +As such, deploying into a local development VM and a staging environment will both validate that things are according to plan +ahead of your production deploy. + +Your workflow may be something like this:: + + - Use the same playbook all the time with embedded tests in development + - Use the playbook to deploy to a staging environment (with the same playbooks) that simulates production + - Run an integration test battery written by your QA team against staging + - Deploy to production, with the same integrated tests. + +Something like an integration test battery should be written by your QA team if you are a production webservice. This would include +things like Selenium tests or automated API tests and would usually not be something embedded into your Ansible playbooks. + +However, it does make sense to include some basic health checks into your playbooks, and in some cases it may be possible to run +a subset of the QA battery against remote nodes. This is what the next section covers. + +Integrating Testing With Rolling Updates +```````````````````````````````````````` + +If you have read into :ref:`playbooks_delegation` it may quickly become apparent that the rolling update pattern can be extended, and you +can use the success or failure of the playbook run to decide whether to add a machine into a load balancer or not. + +This is the great culmination of embedded tests:: + + --- + + - hosts: webservers + serial: 5 + + pre_tasks: + + - name: take out of load balancer pool + command: /usr/bin/take_out_of_pool {{ inventory_hostname }} + delegate_to: 127.0.0.1 + + roles: + + - common + - webserver + - apply_testing_checks + + post_tasks: + + - name: add back to load balancer pool + command: /usr/bin/add_back_to_pool {{ inventory_hostname }} + delegate_to: 127.0.0.1 + +Of course in the above, the "take out of the pool" and "add back" steps would be replaced with a call to a Ansible load balancer +module or appropriate shell command. You might also have steps that use a monitoring module to start and end an outage window +for the machine. + +However, what you can see from the above is that tests are used as a gate -- if the "apply_testing_checks" step is not performed, +the machine will not go back into the pool. + +Read the delegation chapter about "max_fail_percentage" and you can also control how many failing tests will stop a rolling update +from proceeding. + +This above approach can also be modified to run a step from a testing machine remotely against a machine:: + + --- + + - hosts: webservers + serial: 5 + + pre_tasks: + + - name: take out of load balancer pool + command: /usr/bin/take_out_of_pool {{ inventory_hostname }} + delegate_to: 127.0.0.1 + + roles: + + - common + - webserver + + tasks: + - script: /srv/qa_team/app_testing_script.sh --server {{ inventory_hostname }} + delegate_to: testing_server + + post_tasks: + + - name: add back to load balancer pool + command: /usr/bin/add_back_to_pool {{ inventory_hostname }} + delegate_to: 127.0.0.1 + +In the above example, a script is run from the testing server against a remote node prior to bringing it back into +the pool. + +In the event of a problem, fix the few servers that fail using Ansible's automatically generated +retry file to repeat the deploy on just those servers. + +Achieving Continuous Deployment +``````````````````````````````` + +If desired, the above techniques may be extended to enable continuous deployment practices. + +The workflow may look like this:: + + - Write and use automation to deploy local development VMs + - Have a CI system like Jenkins deploy to a staging environment on every code change + - The deploy job calls testing scripts to pass/fail a build on every deploy + - If the deploy job succeeds, it runs the same deploy playbook against production inventory + +Some Ansible users use the above approach to deploy a half-dozen or dozen times an hour without taking all of their infrastructure +offline. A culture of automated QA is vital if you wish to get to this level. + +If you are still doing a large amount of manual QA, you should still make the decision on whether to deploy manually as well, but +it can still help to work in the rolling update patterns of the previous section and incorporate some basic health checks using +modules like 'script', 'stat', 'uri', and 'assert'. + +Conclusion +`````````` + +Ansible believes you should not need another framework to validate basic things of your infrastructure is true. This is the case +because Ansible is an order-based system that will fail immediately on unhandled errors for a host, and prevent further configuration +of that host. This forces errors to the top and shows them in a summary at the end of the Ansible run. + +However, as Ansible is designed as a multi-tier orchestration system, it makes it very easy to incorporate tests into the end of +a playbook run, either using loose tasks or roles. When used with rolling updates, testing steps can decide whether to put a machine +back into a load balanced pool or not. + +Finally, because Ansible errors propagate all the way up to the return code of the Ansible program itself, and Ansible by default +runs in an easy push-based mode, Ansible is a great step to put into a build environment if you wish to use it to roll out systems +as part of a Continuous Integration/Continuous Delivery pipeline, as is covered in sections above. + +The focus should not be on infrastructure testing, but on application testing, so we strongly encourage getting together with your +QA team and ask what sort of tests would make sense to run every time you deploy development VMs, and which sort of tests they would like +to run against the staging environment on every deploy. Obviously at the development stage, unit tests are great too. But don't unit +test your playbook. Ansible describes states of resources declaratively, so you don't have to. If there are cases where you want +to be sure of something though, that's great, and things like stat/assert are great go-to modules for that purpose. + +In all, testing is a very organizational and site-specific thing. Everybody should be doing it, but what makes the most sense for your +environment will vary with what you are deploying and who is using it -- but everyone benefits from a more robust and reliable deployment +system. + +.. seealso:: + + :ref:`list_of_collections` + Browse existing collections, modules, and plugins + :ref:`working_with_playbooks` + An introduction to playbooks + :ref:`playbooks_delegation` + Delegation, useful for working with load balancers, clouds, and locally executed steps. + `User Mailing List <https://groups.google.com/group/ansible-project>`_ + Have a question? Stop by the google group! + `irc.freenode.net <http://irc.freenode.net>`_ + #ansible IRC chat channel + diff --git a/docs/docsite/rst/reference_appendices/tower.rst b/docs/docsite/rst/reference_appendices/tower.rst new file mode 100644 index 00000000..0ef8fe7d --- /dev/null +++ b/docs/docsite/rst/reference_appendices/tower.rst @@ -0,0 +1,13 @@ +.. _ansible_tower: + +Red Hat Ansible Tower +===================== + +`Red Hat Ansible Tower <https://www.ansible.com/products/tower>`_ is a web console and REST API for operationalizing Ansible across your team, organization, and enterprise. It's designed to be the hub for all of your automation tasks. + +Ansible Tower gives you role-based access control, including control over the use of securely stored credentials for SSH and other services. You can sync your Ansible Tower inventory with a wide variety of cloud sources, and powerful multi-playbook workflows allow you to model +complex processes. + +It logs all of your jobs, integrates well with LDAP, SAML, and other authentication sources, and has an amazing browsable REST API. Command line tools are available for easy integration with Jenkins as well. + +Ansible Tower is the downstream Red-Hat supported product version of Ansible AWX. Find out more about Ansible Tower features and how to download it on the `Ansible Tower webpage <https://www.ansible.com/products/tower>`_. Ansible Tower is part of the Red Hat Ansible Automation subscription, and comes bundled with amazing support from Red Hat, Inc. |