Write a playbook that uses multiple plays and per-play privilege escalation, and effectively use automation content navigator to find new modules in available Ansible Content Collections and use them to implement tasks for a play.
A playbook is a YAML file containing a list of one or more plays. Each play in the playbook is written as a top-level list item in the playbook.
A single play is an ordered list of tasks to execute against hosts selected from the inventory. If a playbook contains multiple plays, each play can apply its tasks to a separate set of hosts.
You can create a playbook with multiple plays to orchestrate a complex deployment involving different tasks on different hosts.
The following example shows a playbook with two plays.
The first play runs against the ios inventory group, and the second play runs against the junos inventory group.
Although both plays create configuration backups, the plays use different inventory groups and modules from collections that are specific to each network platform.
The configbackups directory must exist.
---
# This is a playbook with two plays
- name: First play - Back up Cisco IOS configurations
hosts: ios
gather_facts: false
tasks:
# This task uses the ios_config module from the cisco.ios collection.
- name: Back up IOS configurations
cisco.ios.ios_config:
backup: true
backup_options:
filename: {{ inventory_hostname }}.cfg
dir_path: /configbackups
- name: Second play - Back up Juniper Junos configurations
hosts: junos
gather_facts: false
tasks:
# This task uses the junos_config module from the junipernetworks.junos collection.
- name: Back up Junos configurations
junipernetworks.junos.junos_config:
backup: true
backup_options:
filename: {{ inventory_hostname }}.cfg
dir_path: /configbackupsMany network devices require credentials to enter a privileged mode where you can make configuration changes. You can configure privilege escalation in a play to automatically send privileged credentials to managed nodes.
Use the become Boolean keyword to enable or disable privilege escalation for an individual play or task.
Set become to true to enable privilege escalation, or set it to false to disable it.
become: true
If become is set to true, use the become_method keyword in the play to specify the privilege escalation method to use for that play.
For network devices, set the become_method to enable.
become_method: enable
For privilege escalation to work successfully on managed network nodes, you must set the connection type to either connection: ansible.netcommon.network_cli or connection: ansible.netcommon.httpapi.
The connection: ansible.common.netconf connection type does not support privilege escalation.
To use this connection type, you must create a user on the managed nodes with the correct privilege level.
You can also enable privilege escalation by configuring the ansible_become and ansible_become_method connection variables.
One way to configure these variables is in the inventory file, as shown in the following example:
ansible_network_os: cisco.ios.ios ansible_connection: ansible.netcommon.network_cli ansible_become: yes ansible_become_method: enable ansible_user: student
The large number of modules packaged with Ansible provides you with many tools for common tasks.
The ansible.builtin collection provides modules to copy files, read files from a remote inventory system, use templates to dynamically generate configuration files, and debug playbooks.
The following table lists some useful ansible.builtin modules:
Table 2.2. Ansible Built-in Modules
| Module | Description |
|---|---|
ansible.builtin.copy
| Copy files from the local machine to remote hosts. |
ansible.builtin.fetch
| Copy files from remote hosts to the local machine. |
ansible.builtin.file
| Create and manage files and directories. |
ansible.builtin.lineinfile
| Ensure a particular line is or is not in a file. |
ansible.builtin.slurp
| Read a file from a remote host. |
ansible.builtin.template
| Dynamically generate text files and transfer them to managed nodes. |
ansible.builtin.service
| Manage Linux services. |
ansible.builtin.debug
| Print statements during playbook execution. |
ansible.builtin.get_url
| Download files over HTTP, HTTPS, or FTP. |
ansible.builtin.uri
| Interact with web services. |
ansible.builtin.git
| Manage git repositories. |
The automation execution environment that is used in this course, ee-supported-rhel8, includes several collections for managing network devices.
This course uses modules from the following collections:
cisco.ios
cisco.nxos
junipernetworks.junos
arista.eos
paloalto.panos
To display a list of the collections and modules available in your current automation execution environment, run the ansible-navigator doc -l command.
[user@host ~]$ ansible-navigator doc -l
...output omitted...
ansible.builtin.copy Copy files to remote locations
...output omitted...
cisco.ios.ios_config Module to manage configuration sectio...
...output omitted...
cisco.nxos.nxos_command Run arbitrary command on Cisco NXOS d...
...output omitted...
junipernetworks.junos.junos_interfaces Junos Interfaces resource module
...output omitted...Search the output of this command by typing a slash (/) at the colon prompt followed by the keyword, and then pressing Enter.
For more details on network collections and connection types, visit the Ansible network platform options at https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html.
As an alternative to running the ansible-navigator collections command in interactive mode, you can use the ansible-navigator doc command to display detailed documentation for a module.module_name
If you specify the -m stdout option, formatted documentation is displayed to your terminal.
If you do not specify that option, leaving ansible-navigator in interactive mode, then you can scroll through the documentation in YAML format.
Module documentation includes a description of what the module is for, a list of the attributes that you can use to control the module in a task, examples of how to use the module, and other metadata.
You can also view a summary of all the options you can use with a module by running the ansible-navigator -s doc command:module_name
[user@host ~]$ ansible-navigator -s doc cisco.ios.ios_config
- name: Module to manage configuration sections.
ios_config:
after: # The ordered set of commands to append to the ...
backup: # This argument will cause the module to create...
backup_options: # This is a dict object containing configurable...
before: # The ordered set of commands to push on to the...
defaults: # This argument specifies whether or not to col...
...output omitted...This section investigates some YAML syntax elements that you might see in playbooks.
You can also use comments to aid readability. In YAML, everything to the right of the number sign (#) is a comment. If there is content to the left of the comment, precede the number sign with a space.
# This is a YAML comment
some data # This is also a YAML comment
Strings in YAML do not normally need to be put in quotation marks even if the string contains spaces.
this is a string
You must enclose strings in either double or single quotation marks if the string includes a colon character followed by a space.
Escape characters are not parsed in strings enclosed in single quotation marks. You must enclose strings in double quotation marks to parse escape characters such as the newline character (\n).
'Play 1: Configure SNMP settings'
"This is a private system\nUnauthorized use of this system is prohibited"
You can write multiline strings in either of two ways; using the vertical bar (|) character or the greater-than (>) character.
Use the vertical bar (|) character to denote that newline characters within the string are to be preserved.
banner_variable: | This system is restricted to authorized users. Unauthorized access is prohibited. If you are unauthorized, terminate access now.
A newline character is also added to the end of the string. Use (|-) if you do not want a newline character added to the end of the string.
Use the greater-than (>) character to indicate that newline characters are to be converted to spaces and that leading white spaces in the lines are to be removed. This method is often used to break long strings at space characters so that they can span multiple lines for better readability.
config_line: > description "This interface connects to interface1 on switch2 in the top of rack 10 in datacenter 4"
A newline character is still added to the end of the string. Use a greater-than symbol followed by a dash (>-) if you do not want a newline character added to the end of the string.
Dictionary key-value pairs are typically written as an indented block, as follows:
name: svcrole svcservice: httpd svcport: 80
Dictionary key-value pairs can also be written in an inline block format inside braces, as follows:
{name: svcrole, svcservice: httpd, svcport: 80}Avoid the inline block format because it is harder to read. However, this format is sometimes used with Ansible roles. When a playbook includes a list of roles, it is more common to use this syntax to make it easier to distinguish roles included in a play from the variables being passed to a role.
Lists are typically written with the normal single-dash syntax:
hosts:
- router1
- router2
- router3Lists can also be written in an inline format in square braces, as follows:
hosts: [router1, router2, router3]
You should avoid this syntax because it is usually harder to read.
Some playbooks might use an earlier shorthand method to define tasks by putting the key-value pairs for the module on the same line as the module name. For example, you might see this syntax:
tasks:
- name: Shorthand form
ansible.builtin.service: name=httpd enabled=true state=startedNormally you would write the same task as follows:
tasks:
- name: Normal form
ansible.builtin.service:
name: httpd
enabled: true
state: startedYou should generally avoid the shorthand form and use the normal form. Syntax highlighting tools in text editors such as VS Code can help you more effectively if you use the normal format than if you use the shorthand format.