Ansible 简明教程
Ansible - Introduction
Ansible 是简单开源的 IT 引擎,它自动执行应用程序部署、内部服务编排、云供应和许多其他 IT 工具。
Ansible is simple open source IT engine which automates application deployment, intra service orchestration, cloud provisioning and many other IT tools.
Ansible 易于部署,因为它不使用任何代理或自定义安全基础架构。
Ansible is easy to deploy because it does not use any agents or custom security infrastructure.
Ansible 使用 playbook 来描述自动化作业,而 playbook 使用非常简单的语言,即 YAML (它是一种人类可读的数据序列化语言,通常用于配置文件,但可用于数据存储的许多应用程序中),非常容易让人理解、阅读和编写。因此,好处还在于,即使 IT 基础设施支持人员也可以阅读和理解 playbook,并在需要时对其进行调试(YAML - 以人类可读的格式)。
Ansible uses playbook to describe automation jobs, and playbook uses very simple language i.e. YAML (It’s a human-readable data serialization language & is commonly used for configuration files, but could be used in many applications where data is being stored)which is very easy for humans to understand, read and write. Hence the advantage is that even the IT infrastructure support guys can read and understand the playbook and debug if needed (YAML – It is in human readable form).
Ansible 设计用于多层部署。Ansible 不会一次管理一个系统,而是通过描述所有系统之间的相互关联来建模 IT 基础架构。Ansible 完全不含代理,这意味着 Ansible 通过 ssh(默认情况下)连接你的节点来工作。但是,如果你想要其他连接方法,如 Kerberos,Ansible 会向你提供该选项。
Ansible is designed for multi-tier deployment. Ansible does not manage one system at time, it models IT infrastructure by describing all of your systems are interrelated. Ansible is completely agentless which means Ansible works by connecting your nodes through ssh(by default). But if you want other method for connection like Kerberos, Ansible gives that option to you.
在连接到你的节点后,Ansible 会推送被称为“Ansible 模块”的小程序。Ansible 在你的节点上运行该模块,并在完成后将其删除。Ansible 在简单文本文件中(这些是主机文件)管理你的清单。Ansible 使用主机文件,其中可以对主机进行分组,并可在 playbook 中控制对特定组的操作。
After connecting to your nodes, Ansible pushes small programs called as “Ansible Modules”. Ansible runs that modules on your nodes and removes them when finished. Ansible manages your inventory in simple text files (These are the hosts file). Ansible uses the hosts file where one can group the hosts and can control the actions on a specific group in the playbooks.
Sample Hosts File
以下是主机文件的内容 -
This is the content of hosts file −
#File name: hosts
#Description: Inventory file for your application. Defines machine type abc
node to deploy specific artifacts
# Defines machine type def node to upload
metadata.
[abc-node]
#server1 ansible_host = <target machine for DU deployment> ansible_user = <Ansible
user> ansible_connection = ssh
server1 ansible_host = <your host name> ansible_user = <your unix user>
ansible_connection = ssh
[def-node]
#server2 ansible_host = <target machine for artifact upload>
ansible_user = <Ansible user> ansible_connection = ssh
server2 ansible_host = <host> ansible_user = <user> ansible_connection = ssh
What is Configuration Management
根据 Ansible 的配置管理,它通过保留记录和更新描述企业硬件和软件的详细信息来维护产品性能配置。
Configuration management in terms of Ansible means that it maintains configuration of the product performance by keeping a record and updating detailed information which describes an enterprise’s hardware and software.
此类信息通常包括已应用于已安装软件包的确切版本和更新,以及硬件设备的位置和网络地址。例如,如果你想在你的企业中所有机器上安装 WebLogic/WebSphere 服务器的新版本,对你来说手动更新所有机器是不现实的。
Such information typically includes the exact versions and updates that have been applied to installed software packages and the locations and network addresses of hardware devices. For e.g. If you want to install the new version of WebLogic/WebSphere server on all of the machines present in your enterprise, it is not feasible for you to manually go and update each and every machine.
你可以通过以最简单的方式编写的 Ansible playbook 和清单,一次性在所有机器上安装 WebLogic/WebSphere。你要做的就是将你的节点的 IP 地址列在清单中,然后编写 playbook 以安装 WebLogic/WebSphere。从你的控制机器运行 playbook,它将安装在你的所有节点上。
You can install WebLogic/WebSphere in one go on all of your machines with Ansible playbooks and inventory written in the most simple way. All you have to do is list out the IP addresses of your nodes in the inventory and write a playbook to install WebLogic/WebSphere. Run the playbook from your control machine & it will be installed on all your nodes.
How Ansible Works?
下图显示了 Ansible 的工作原理。
The picture given below shows the working of Ansible.
Ansible works 通过连接到你的节点,并向其推送名为“ Ansible 模块”的小程序。然后 Ansible 执行这些模块(默认情况下通过 SSH),并在完成后将其删除。你的模块库可以驻留在任何机器上,并且不需要服务器、守护程序或数据库。
Ansible works by connecting to your nodes and pushing out small programs, called "Ansible modules" to them. Ansible then executes these modules (over SSH by default), and removes them when finished. Your library of modules can reside on any machine, and there are no servers, daemons, or databases required.

上图中的管理节点是控制节点(管理节点),它控制整个 playbook 的执行。这是你运行安装的节点。清单文件提供了需要运行 Ansible 模块的主机列表,而管理节点执行 SSH 连接并在主机机器上执行小模块并安装产品/软件。
The management node in the above picture is the controlling node (managing node) which controls the entire execution of the playbook. It’s the node from which you are running the installation. The inventory file provides the list of hosts where the Ansible modules needs to be run and the management node does a SSH connection and executes the small modules on the hosts machine and installs the product/software.
Ansible 的 Beauty 是它在安装好模块后会将其删除,因此它有效地连接到主机,执行指令,如果成功安装了在主机机器上执行的代码,则将该代码删除。
Beauty of Ansible is that it removes the modules once those are installed so effectively it connects to host machine , executes the instructions and if it’s successfully installed removes the code which was copied on the host machine which was executed.
Ansible - Environment Setup
在本章中,我们将了解 Ansible 的环境设置。
In this chapter, we will learn about the environment setup of Ansible.
Installation Process
说到部署,主要有两种类型的机器:
Mainly, there are two types of machines when we talk about deployment −
-
Control machine − Machine from where we can manage other machines.
-
Remote machine − Machines which are handled/controlled by control machine.
一台控制机器可处理多台远程机器。因此,要管理远程机器,我们必须在控制机器上安装 Ansible。
There can be multiple remote machines which are handled by one control machine. So, for managing remote machines we have to install Ansible on control machine.
Control Machine Requirements
已安装 Python 2(版本 2.6 或 2.7)或 Python 3(版本 3.5 及更高版本)即可从任何机器上运行 Ansible。
Ansible can be run from any machine with Python 2 (versions 2.6 or 2.7) or Python 3 (versions 3.5 and higher) installed.
Note − Windows 不支持控制机器。
Note − Windows does not support control machine.
默认情况下,Ansible 使用 ssh 来管理远程机器。
By default, Ansible uses ssh to manage remote machine.
Ansible 不会添加任何数据库。它不需要任何守护进程来启动或使它持续运行。在管理远程机器时,Ansible does not 会在远程机器上安装或运行任何软件。因此,在迁移到新版本时无需考虑如何升级该软件。
Ansible does not add any database. It does not require any daemons to start or keep it running. While managing remote machines, Ansible does not leave any software installed or running on them. Hence, there is no question of how to upgrade it when moving to a new version.
可通过不同的方式在具有上述要求的控制机器上安装 Ansible。你可以通过 Apt、yum、pkg、pip、OpenCSW、pacman 等安装最新版本。
Ansible can be installed on control machine which have above mentioned requirements in different ways. You can install the latest release through Apt, yum, pkg, pip, OpenCSW, pacman, etc.
Installation through Apt on Ubuntu Machine
要安装 Ansible,需要在机器上配置 PPA。为此,需运行以下代码行:
For installing Ansible you have to configure PPA on your machine. For this, you have to run the following line of code −
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update
$ sudo apt-get install ansible
运行上述代码行后,即可通过 Ansible 管理远程机器。只需运行 Ansible–version 即可查看版本,并检查 Ansible 是否已正确安装。
After running the above line of code, you are ready to manage remote machines through Ansible. Just run Ansible–version to check the version and just to check whether Ansible was installed properly or not.
Ansible - YAML Basics
Ansible 使用 YAML 语法来表示 Ansible 剧本。本章节将概述 YAML。与 XML 和 JSON 等其他数据格式相比,Ansible 使用 YAML 是因为它非常容易让人理解、阅读和编写。
Ansible uses YAML syntax for expressing Ansible playbooks. This chapter provides an overview of YAML. Ansible uses YAML because it is very easy for humans to understand, read and write when compared to other data formats like XML and JSON.
每个 YAML 文件都可以选择以 “---” 开头和以 “…” 结尾。
Every YAML file optionally starts with “---” and ends with “…”.
Understanding YAML
在本节中,我们将会了解 YAML 数据的各种表示方式。
In this section, we will learn the different ways in which the YAML data is represented.
key-value pair
YAML 使用简单的键值对来表示数据。字典采用键值对的形式表示。
YAML uses simple key-value pair to represent the data. The dictionary is represented in key: value pair.
Note - : 和值之间应该有空格。
Note − There should be space between : and value.
Representing List
我们还可以在 YAML 中表示列表。列表的每个元素(成员)都应该写在单独的行中,并且缩进方式相同,以 “- “ (- 和空格)开头。
We can also represent List in YAML. Every element(member) of list should be written in a new line with same indentation starting with “- “ (- and space).
List inside Dictionaries
我们可以在字典内使用列表,即键的值是一个列表。
We can use list inside dictionaries, i.e., value of key is list.
Example
---
james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
…
Example
---
- james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
- robert:
name: robert richardson
rollNo: 53
div: B
sex: male
likes:
- biology
- chemistry
…
YAML 使用 “|” 在显示多行时包含换行符,使用 “>” 在显示多行时抑制换行符。因此,我们可以读取和编辑长行。在这两种情况下,都将忽略缩进。
YAML uses “|” to include newlines while showing multiple lines and “>” to suppress newlines while showing multiple lines. Due to this we can read and edit large lines. In both the cases intendentation will be ignored.
我们还可以在 YAML 中表示 Boolean (真/假)值。其中, boolean 值不区分大小写。
We can also represent Boolean (True/false) values in YAML. where boolean values can be case insensitive.
Example
---
- james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
result:
maths: 87
chemistry: 45
biology: 56
physics: 70
english: 80
passed: TRUE
messageIncludeNewLines: |
Congratulation!!
You passed with 79%
messageExcludeNewLines: >
Congratulation!!
You passed with 79%
Ansible - Ad hoc Commands
临时命令是命令,可以单独运行以执行快速功能。不必在以后执行这些命令。
Ad hoc commands are commands which can be run individually to perform quick functions. These commands need not be performed later.
例如,您必须重新启动所有公司服务器。为此,您将从“ /usr/bin/ansible ”运行临时命令。
For example, you have to reboot all your company servers. For this, you will run the Adhoc commands from ‘/usr/bin/ansible’.
临时命令不用于配置管理和部署,因为这些命令是一次性使用的。
These ad-hoc commands are not used for configuration management and deployment, because these commands are of one time usage.
ansible-playbook 用于配置管理和部署。
ansible-playbook is used for configuration management and deployment.
Parallelism and Shell Commands
一次同时在 12 个并行进程中重启公司服务器。为此,我们需要为连接设置 SSHagent。
Reboot your company server in 12 parallel forks at time. For this, we need to set up SSHagent for connection.
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
要在 12 个并行进程中为“abc”组中的所有公司服务器运行重启 −
To run reboot for all your company servers in a group, 'abc', in 12 parallel forks −
$ Ansible abc -a "/sbin/reboot" -f 12
默认情况下,Ansible 将从当前用户帐户运行上述临时命令表单。如果您想要更改此行为,则必须在临时命令中传递用户名,如下所示 −
By default, Ansible will run the above Ad-hoc commands form current user account. If you want to change this behavior, you will have to pass the username in Ad-hoc commands as follows −
$ Ansible abc -a "/sbin/reboot" -f 12 -u username
File Transfer
您可以使用临时命令在多台机器上并行执行 SCP (安全复制协议)大量文件。
You can use the Ad-hoc commands for doing SCP (Secure Copy Protocol) lots of files in parallel on multiple machines.
Transferring file to many servers/machines
$ Ansible abc -m copy -a "src = /etc/yum.conf dest = /tmp/yum.conf"
Managing Packages
临时命令可用于 yum 和 apt。下面是一些使用 yum 的临时命令。
The Ad-hoc commands are available for yum and apt. Following are some Ad-hoc commands using yum.
以下命令检查 yum 包是否已安装,但不会更新它。
The following command checks if yum package is installed or not, but does not update it.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = present"
以下命令检查包未安装。
The following command check the package is not installed.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = absent"
以下命令检查已安装的软件包是否是最新版本。
The following command checks the latest version of package is installed.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = latest"
Ansible - Playbooks
在本篇中,我们将了解 Ansible 中的剧本。
In this chapter, we will learn about Playbooks in Ansible.
剧本是编写 Ansible 代码的文件。剧本以 YAML 格式编写。YAML 代表 Yet Another Markup Language(另一种标记语言)。 Playbooks 是 Ansible 的核心功能之一,它告诉 Ansible 要执行什么操作。它们对于 Ansible 而言就像一个待办事项列表,其中包含任务列表。
Playbooks are the files where Ansible code is written. Playbooks are written in YAML format. YAML stands for Yet Another Markup Language. Playbooks are one of the core features of Ansible and tell Ansible what to execute. They are like a to-do list for Ansible that contains a list of tasks.
剧本包含用户想要在特定机器上执行的步骤。剧本按顺序运行。剧本是 Ansible 所有用例的构建块。
Playbooks contain the steps which the user wants to execute on a particular machine. Playbooks are run sequentially. Playbooks are the building blocks for all the use cases of Ansible.
Playbook Structure
每个剧本都是其中一个或多个剧目的集合。剧本使用剧目进行构建。剧本中可以包含多个剧目。
Each playbook is an aggregation of one or more plays in it. Playbooks are structured using Plays. There can be more than one play inside a playbook.
剧目的功能是对针对特定主机定义的一组指令进行映射。
The function of a play is to map a set of instructions defined against a particular host.
YAML 是一种严格类型化的语言;因此,在编写 YAML 文件时需要格外小心。有不同的 YAML 编辑器,但我们更喜欢使用简单的编辑器,如记事本。只需打开记事本,复制并粘贴以下 yaml,将语言更改为 YAML(语言 → YAML)。
YAML is a strict typed language; so, extra care needs to be taken while writing the YAML files. There are different YAML editors but we will prefer to use a simple editor like notepad. Just open notepad and copy and paste the below yaml and change the language to YAML (Language → YAML).
YAML 以 ---(3 个连字符)开头
A YAML starts with --- (3 hyphens)
Create a Playbook
让我们从编写一个示例 YAML 文件开始。我们将逐步了解 yaml 文件中编写的每个部分。
Let us start by writing a sample YAML file. We will walk through each section written in a yaml file.
---
name: install and configure DB
hosts: testServer
become: yes
vars:
oracle_db_port_value : 1521
tasks:
-name: Install the Oracle DB
yum: <code to install the DB>
-name: Ensure the installed service is enabled and running
service:
name: <your service name>
上面是一个示例剧本,我们尝试介绍剧本的基本语法。将上面的内容保存到一个文件 test.yml 。YAML 语法需要遵循正确的缩进,在编写语法时需要小心。
The above is a sample Playbook where we are trying to cover the basic syntax of a playbook. Save the above content in a file as test.yml. A YAML syntax needs to follow the correct indentation and one needs to be a little careful while writing the syntax.
The Different YAML Tags
现在,让我们浏览不同的 YAML 标签。下面描述了不同的标签:
Let us now go through the different YAML tags. The different tags are described below −
name
此标签指定 Ansible 剧本的名称。它指定该剧本的作用。可以给剧本指定任何合乎逻辑的名称。
This tag specifies the name of the Ansible playbook. As in what this playbook will be doing. Any logical name can be given to the playbook.
hosts
此标签指定我们想要对之运行任务的主机或主机组的列表。hosts 字段/标签是必填项。它会告知 Ansible 应在哪些主机上运行所列任务。可以在同一台机器或远程机器上运行任务。可以将任务运行在多台机器上,因此 hosts 标签也可以包含一组主机条目。
This tag specifies the lists of hosts or host group against which we want to run the task. The hosts field/tag is mandatory. It tells Ansible on which hosts to run the listed tasks. The tasks can be run on the same machine or on a remote machine. One can run the tasks on multiple machines and hence hosts tag can have a group of hosts’ entry as well.
vars
Vars 标签允许你定义剧本中可用的变量。用法类似于任何编程语言中的变量。
Vars tag lets you define the variables which you can use in your playbook. Usage is similar to variables in any programming language.
tasks
所有剧本都应该包含任务或待执行的任务列表。任务是需要执行的一系列操作。tasks 字段包含任务的名称。该名称用作用户的帮助文本。它不是必填项,但有助于调试剧本。每个任务在内部链接到称为模块的代码块。应该执行的模块以及要执行的模块所需的论证。
All playbooks should contain tasks or a list of tasks to be executed. Tasks are a list of actions one needs to perform. A tasks field contains the name of the task. This works as the help text for the user. It is not mandatory but proves useful in debugging the playbook. Each task internally links to a piece of code called a module. A module that should be executed, and arguments that are required for the module you want to execute.
Ansible - Roles
角色为完全独立或相互依赖的变量、任务、文件、模板和模块集提供了一个框架。
Roles provide a framework for fully independent, or interdependent collections of variables, tasks, files, templates, and modules.
在 Ansible 中,角色是将剧本分成多个文件的主要机制。这简化了编写 complex playbooks ,并使其更容易重用。通过分解剧本,您可以将剧本合理分解为可重用的组件。
In Ansible, the role is the primary mechanism for breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse. The breaking of playbook allows you to logically break the playbook into reusable components.
每个角色基本上仅限于特定功能或期望的输出,所有必要的步骤都在该角色本身或者在依赖关系中列出的其他角色中提供该结果。
Each role is basically limited to a particular functionality or desired output, with all the necessary steps to provide that result either within that role itself or in other roles listed as dependencies.
角色不是剧本。角色是小功能,可以独立使用,但必须在剧本中使用。无法直接执行角色。角色没有明确的设置,用来说明角色将应用于哪个主机。
Roles are not playbooks. Roles are small functionality which can be independently used but have to be used within playbooks. There is no way to directly execute a role. Roles have no explicit setting for which host the role will apply to.
顶级剧本是桥梁,将清单文件中的主机与应该应用于这些主机的角色联系起来。
Top-level playbooks are the bridge holding the hosts from your inventory file to roles that should be applied to those hosts.
Creating a New Role
角色的目录结构对于创建新角色至关重要。
The directory structure for roles is essential to create a new role.
Role Structure
角色在文件系统上具有结构化的布局。默认结构可以更改,但现在我们坚持默认设置。
Roles have a structured layout on the file system. The default structure can be changed but for now let us stick to defaults.
每个角色本身都是一个目录树。角色名称是 /roles 目录内的目录名称。
Each role is a directory tree in itself. The role name is the directory name within the /roles directory.
$ ansible-galaxy -h
Usage
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
Options
-
-h, --help − Show this help message and exit.
-
-v, --verbose − Verbose mode (-vvv for more, -vvvv to enable connection debugging)
-
--version − Show program’s version number and exit.
Creating a Role Directory
以上命令创建了角色目录。
The above command has created the role directories.
$ ansible-galaxy init vivekrole
ERROR! The API server (https://galaxy.ansible.com/api/) is not responding, please try again later.
$ ansible-galaxy init --force --offline vivekrole
- vivekrole was created successfully
$ tree vivekrole/
vivekrole/
├── defaults
│ └── main.yml
├── files ├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md ├── tasks
│ └── main.yml
├── templates ├── tests │ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
并非所有目录都将在示例中使用,我们将在示例中展示其中一些目录的使用。
Not all the directories will be used in the example and we will show the use of some of them in the example.
Utilizing Roles in Playbook
这是我们为演示目的编写的剧本的代码。此代码属于剧本 vivek_orchestrate.yml。我们定义了主机: tomcat-node ,并调用了两个角色 - install-tomcat 和 start-tomcat 。
This is the code of the playbook we have written for demo purpose. This code is of the playbook vivek_orchestrate.yml. We have defined the hosts: tomcat-node and called the two roles – install-tomcat and start-tomcat.
问题陈述是,我们有一场战争,我们需要通过 Ansible 部署到一台机器上。
The problem statement is that we have a war which we need to deploy on a machine via Ansible.
---
- hosts: tomcat-node
roles:
- {role: install-tomcat}
- {role: start-tomcat}
从我们运行剧本的目录结构的内容。
Contents of our directory structure from where we are running the playbook.

$ ls
ansible.cfg hosts roles vivek_orchestrate.retry vivek_orchestrate.yml

每个目录下都有一个任务目录,其中包含一个 main.yml。install-tomcat 的 main.yml 内容为:
There is a tasks directory under each directory and it contains a main.yml. The main.yml contents of install-tomcat are −
---
#Install vivek artifacts
-
block:
- name: Install Tomcat artifacts
action: >
yum name = "demo-tomcat-1" state = present
register: Output
always:
- debug:
msg:
- "Install Tomcat artifacts task ended with message: {{Output}}"
- "Installed Tomcat artifacts - {{Output.changed}}"
start tomcat 的 main.yml 的内容为:
The contents of main.yml of the start tomcat are −
#Start Tomcat
-
block:
- name: Start Tomcat
command: <path of tomcat>/bin/startup.sh"
register: output
become: true
always:
- debug:
msg:
- "Start Tomcat task ended with message: {{output}}"
- "Tomcat started - {{output.changed}}"
将剧本分解为角色的优点是,任何想要使用 Install tomcat 功能的人都可以调用 Install Tomcat 角色。
The advantage of breaking the playbook into roles is that anyone who wants to use the Install tomcat feature can call the Install Tomcat role.
Breaking a Playbook into a Role
如果没有角色,则各个角色的 main.yaml 的内容可以复制到剧本 yml 文件中。但要具有模块化,创建了角色。
If not for the roles, the content of the main.yml of the respective role can be copied in the playbook yml file. But to have modularity, roles were created.
任何可作为可重用函数重复使用的逻辑实体,该实体可以移动到角色。上文给出了示例
Any logical entity which can be reused as a reusable function, that entity can be moved to role. The example for this is shown above
运行了运行剧本的命令。
Ran the command to run the playbook.
-vvv option for verbose output – verbose output
$ cd vivek-playbook/
这是运行剧本的命令
This is the command to run the playbook
$ sudo ansible-playbook -i hosts vivek_orchestrate.yml –vvv
-----------------------------------------------------------------
-----------------------------------------------------------------------
Output
生成的输出在屏幕上可见,如下所示:
The generated output is as seen on the screen −
使用 /users/demo/vivek-playbook/ansible.cfg 作为配置文件。
Using /users/demo/vivek-playbook/ansible.cfg as config file.
PLAYBOOK: vivek_orchestrate.yml *********************************************************
***********************************************************
1 plays in vivek_orchestrate.yml
PLAY [tomcat-node] **********************************************************************
******** *************************************************
TASK [Gathering Facts] *************************************************
****************************** *********************************************
Tuesday 21 November 2017 13:02:05 +0530 (0:00:00.056) 0:00:00.056 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/system/setup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249525.88-259535494116870 `" &&
echo ansible-tmp-1511249525.88-259535494116870="`
echo /root/.ansible/tmp/ansibletmp-1511249525.88-259535494116870 `" ) && sleep 0'
<localhost> PUT /tmp/tmpPEPrkd TO
/root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/
/root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/setup.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/" > /dev/null 2>&1 && sleep 0'
ok: [server1]
META: ran handlers
TASK [install-tomcat : Install Tomcat artifacts] ***********************************
***************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:07 +0530 (0:00:01.515) 0:00:01.572 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/packaging/os/yum.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249527.34-40247177825302 `" && echo
ansibletmp-1511249527.34-40247177825302="` echo
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302 `" ) && sleep 0'
<localhost> PUT /tmp/tmpu83chg TO
/root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/
/root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/yum.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/" > /dev/null 2>
&1 && sleep 0'
changed: [server1] => {
"changed": true,
"invocation": {
"module_args": {
"conf_file": null,
"disable_gpg_check": false,
"disablerepo": null,
"enablerepo": null,
"exclude": null,
"install_repoquery": true,
"installroot": "/",
"list": null,
"name": ["demo-tomcat-1"],
"skip_broken": false,
"state": "present",
"update_cache": false,
"validate_certs": true
}
},
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: product-id,
search-disabled-repos,
subscriptionmanager\nThis system is not registered to Red Hat Subscription Management.
You can use subscription-manager to register.\nResolving Dependencies\n-->
Running transaction check\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\n--> Finished Dependency
Resolution\n\nDependencies Resolved\n
\n================================================================================\n
Package Arch Version Repository
Size\n==================================================================\nInstalling:\n
demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 M\n\nTransaction
Summary\n==================================================================\nInstall 1
Package\n\nTotal download size: 7.1 M\nInstalled size: 7.9 M\nDownloading
packages:\nRunning transaction
check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing :
demotomcat-1-SNAPSHOT-1.noarch 1/1 \n Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \n\nInstalled:\n
demo-tomcat-1.noarch 0:SNAPSHOT-1 \n\nComplete!\n"
]
}
TASK [install-tomcat : debug] **********************************************************
***************************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11
Tuesday 21 November 2017 13:02:13 +0530 (0:00:06.757) 0:00:08.329 ******
ok: [server1] => {
"changed": false,
"msg": [
"Install Tomcat artifacts task ended with message: {
u'msg': u'', u'changed': True, u'results':
[u'Loaded plugins: product-id,
search-disabledrepos,
subscription-manager\\nThis system is not registered to Red Hat Subscription Management.
You can use subscription-manager to register.\\nResolving Dependencies\\n-->
Running transaction check\\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\\n-->
Finished Dependency Resolution\\n
\\nDependencies
Resolved\\n\\n==================================================================\\n
Package Arch Version Repository
Size\\n========================================================================
=====\\nInstalling:\\n demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 M\\n\\nTransaction
Summary\\n=========================================================\\nInstall 1
Package\\n\\nTotal download size: 7.1 M\\nInstalled size: 7.9 M\\nDownloading
packages:\\nRunning
transaction check\\nRunning transaction test\\nTransaction test succeeded\\nRunning
transaction\\n
Installing : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \\n Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch
1/1 \\n\\nInstalled:\\n demo-tomcat-1.noarch 0:SNAPSHOT-1 \\n\\nComplete!\\n'], u'rc': 0
}",
"Installed Tomcat artifacts - True"
]
}
TASK [install-tomcat : Clean DEMO environment] ****************************************
************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19
Tuesday 21 November 2017 13:02:13 +0530 (0:00:00.057) 0:00:08.387 ******
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/files/file.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.13-128345805983963 `" && echo
ansible-tmp-1511249534.13-128345805983963="` echo
/root/.ansible/tmp/ansibletmp-1511249534.13-128345805983963 `" ) && sleep 0'
<localhost> PUT /tmp/tmp0aXel7 TO
/root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/
/root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/file.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"diff": {
"after": {
"path": "/users/demo/DEMO",
"state": "absent"
},
"before": {
"path": "/users/demo/DEMO",
"state": "directory"
}
},
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": "/users/demo/DEMO",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "absent",
"unsafe_writes": null,
"validate": null
}
},
"path": "/users/demo/DEMO",
"state": "absent"
}
TASK [install-tomcat : debug] ********************************************************
*************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.257) 0:00:08.645 ******
ok: [server1] => {
"changed": false,
"msg": [
"Clean DEMO environment task ended with message:{u'diff': {u'after': {u'path':
u'/users/demo/DEMO', u'state': u'absent'},
u'before': {u'path': u'/users/demo/DEMO', u'state': u'directory'}}, u'state': u'absent',
u'changed': True, u'path': u'/users/demo/DEMO'}",
"check value :True"
]
}
TASK [install-tomcat : Copy Tomcat to user home] *************************************
********************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.055) 0:00:08.701 ******
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.43-41077200718443 `" && echo
ansibletmp-1511249534.43-41077200718443="` echo
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443 `" ) && sleep 0'
<localhost> PUT /tmp/tmp25deWs TO
/root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/
/root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.43-41077200718443/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [
"cp",
"-r",
"/opt/ansible/tomcat/demo",
"/users/demo/DEMO/"
],
"delta": "0:00:00.017923",
"end": "2017-11-21 13:02:14.547633",
"invocation": {
"module_args": {
"_raw_params": "cp -r /opt/ansible/tomcat/demo /users/demo/DEMO/",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.529710",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
TASK [install-tomcat : debug] ********************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.260) 0:00:08.961 ******
ok: [server1] => {
"changed": false,
"msg": "Copy Tomcat to user home task ended with message {
'stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.547633', u'stdout':
u'', u'cmd': [u'cp', u'-r', u'/opt/ansible/tomcat/demo', u'/users/demo/DEMO/'], u'rc': 0,
u'start': u'2017-11-21 13:02:14.529710', u'stderr': u'', u'delta': u'0:00:00.017923',
'stdout_lines': []}"
}
TASK [start-tomcat : Start Tomcat] **************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.044) 0:00:09.006 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.63-46501211251197 `" && echo
ansibletmp-1511249534.63-46501211251197="` echo
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197 `" ) && sleep 0'
<localhost> PUT /tmp/tmp9f06MQ TO
/root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/
/root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.63-46501211251197/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [ "/users/demo/DEMO/bin/startup.sh" ],
"delta": "0:00:00.020024",
"end": "2017-11-21 13:02:14.741649",
"invocation": {
"module_args": {
"_raw_params": "/users/demo/DEMO/bin/startup.sh",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.721625",
"stderr": "",
"stderr_lines": [],
"stdout": "Tomcat started.",
"stdout_lines": [ "Tomcat started." ]
}
TASK [start-tomcat : debug] *************************************************
**********************************************************************
task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.150) 0:00:09.156 ******
ok: [server1] => {
"changed": false,
"msg": [
"Start Tomcat task ended with message: {'
stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.741649', u'stdout':
u'Tomcat started.', u'cmd': [u'/users/demo/DEMO/bin/startup.sh'], u'rc': 0, u'start':
u'2017-11-21 13:02:14.721625', u'stderr': u'', u'delta': u'0:00:00.020024',
'stdout_lines': [u'Tomcat started.']}",
"Tomcat started - True"
]
}
META: ran handlers
META: ran handlers
PLAY RECAP *******************************************************************************
*********************************************************
server1 : ok = 9 changed = 4 unreachable = 0 failed = 0
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.042) 0:00:09.198 ******
===============================================================================
install-tomcat : Install Tomcat artifacts ------------------------------- 6.76s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5 --------------
Gathering Facts --------------------------------------------------------- 1.52s
------------------------------------------------------------------------------
install-tomcat : Copy Tomcat to user home ------------------------------- 0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37 -------------
install-tomcat : Clean DEMO environment --------------------------------- 0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19 -------------
start-tomcat : Start Tomcat --------------------------------------------- 0.15s
/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5 ----------------
install-tomcat : debug -------------------------------------------------- 0.06s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11 -------------
install-tomcat : debug -------------------------------------------------- 0.06s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29 -------------
install-tomcat : debug -------------------------------------------------- 0.04s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47 -------------
start-tomcat : debug ---------------------------------------------------- 0.04s
/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10 ---------------
点击以下 URL,您将访问如下图所示的页面 - * [role="bare"] [role="bare"]http://10.76.0.134:11677/HelloWorld/HelloWorld*
Hit the following URL and you will be directed to a page as shown below − * [role="bare"]http://10.76.0.134:11677/HelloWorld/HelloWorld*

刚部署的 war 仅具有显示“Hello World”的服务。详细输出显示每个任务所花费的时间,因为在 ansible.cfg 文件中添加了条目 -
The deployed war just has a servlet which displays “Hello World”. The detailed output shows the time taken by each and every task because of the entry added in ansible.cfg file −
[defaults]
callback_whitelist = profile_tasks
Ansible - Variables
剧本中的变量 very similar 用于使用任何编程语言中的变量。它可以帮助您使用和向变量分配值,并在剧本的任何位置使用该值。可以在变量值周围放置条件,并相应地在剧本中使用它们。
Variable in playbooks are very similar to using variables in any programming language. It helps you to use and assign a value to a variable and use that anywhere in the playbook. One can put conditions around the value of the variables and accordingly use them in the playbook.
Example
- hosts : <your hosts>
vars:
tomcat_port : 8080
在上面的示例中,我们定义了一个变量名称 tomcat_port ,并为该变量分配值 8080,可以在剧本中所需位置使用该变量。
In the above example, we have defined a variable name tomcat_port and assigned the value 8080 to that variable and can use that in your playbook wherever needed.
现在参考上面分享的示例。以下代码来自其中一个角色(install-tomcat):
Now taking a reference from the example shared. The following code is from one of the roles (install-tomcat) −
block:
- name: Install Tomcat artifacts
action: >
yum name = "demo-tomcat-1" state = present
register: Output
always:
- debug:
msg:
- "Install Tomcat artifacts task ended with message: {{Output}}"
- "Installed Tomcat artifacts - {{Output.changed}}"
此处,输出是使用的变量。
Here, the output is the variable used.
让我们了解一下上述代码中使用的所有关键字——
Let us walk through all the keywords used in the above code −
-
block − Ansible syntax to execute a given block.
-
name − Relevant name of the block - this is used in logging and helps in debugging that which all blocks were successfully executed.
-
action − The code next to action tag is the task to be executed. The action again is a Ansible keyword used in yaml.
-
register − The output of the action is registered using the register keyword and Output is the variable name which holds the action output.
-
always − Again a Ansible keyword , it states that below will always be executed.
-
msg − Displays the message.
Usage of variable - {{Output}} -→
这会读取变量 Output 的值。与在 msg 选项卡中使用的方式类似,它也会打印 output 变量的值。
This will read the value of variable Output. Also as it is used in the msg tab, it will print the value of the output variable.
此外,你也可以使用变量的子属性。例如,像在检查 {{Output.changed}} 是否会使输出发生更改并相应使用它一样。
Additionally, you can use the sub properties of the variable as well. Like in the case checking {{Output.changed}} whether the output got changed and accordingly use it.
Exception Handling in Playbooks
Ansible 中的异常处理与任何编程语言中的异常处理类似。下面展示了 playbook 中的异常处理示例。
Exception handling in Ansible is similar to exception handling in any programming language. An example of the exception handling in playbook is shown below.
tasks:
- name: Name of the task to be executed
block:
- debug: msg = 'Just a debug message , relevant for logging'
- command: <the command to execute>
rescue:
- debug: msg = 'There was an exception.. '
- command: <Rescue mechanism for the above exception occurred)
always:
- debug: msg = "this will execute in all scenarios. Always will get logged"
以下是异常处理的语法。
Following is the syntax for exception handling.
-
rescue and always are the keywords specific to exception handling.
-
Block is where the code is written (anything to be executed on the Unix machine).
-
If the command written inside the block feature fails, then the execution reaches rescue block and it gets executed. In case there is no error in the command under block feature, then rescue will not be executed.
-
Always gets executed in all cases.
-
So if we compare the same with java, then it is similar to try, catch and finally block.
-
Here, Block is similar to try block where you write the code to be executed and rescue is similar to catch block and always is similar to finally.
Loops
以下是演示如何在 Ansible 中使用循环的示例。
Below is the example to demonstrate the usage of Loops in Ansible.
任务是从一个目录复制所有 war 文件到 tomcat webapps 文件夹。
The tasks is to copy the set of all the war files from one directory to tomcat webapps folder.
在下面的示例中使用的多数命令之前已经涵盖过了。这里,我们关注循环的使用。
Most of the commands used in the example below are already covered before. Here, we will concentrate on the usage of loops.
最初,我们在“shell”命令中执行 ls *.war。所以,它会列出目录中的所有 war 文件。
Initially in the 'shell' command we have done ls *.war. So, it will list all the war files in the directory.
该命令的输出采用名为 output 的变量。
Output of that command is taken in a variable named output.
要进行循环,请使用“with_items”语法。
To loop, the 'with_items' syntax is being used.
with_items: "{{output.stdout_lines}}" -→ output.stdout_lines 为我们提供逐行输出,然后我们使用 Ansible 的 with_items 命令进行循环。
with_items: "{{output.stdout_lines}}" -→ output.stdout_lines gives us the line by line output and then we loop on the output with the with_items command of Ansible.
附加示例输出,只为让人们理解我们如何在 with_items 命令中使用 stdout_lines。
Attaching the example output just to make one understand how we used the stdout_lines in the with_items command.
---
#Tsting
- hosts: tomcat-node
tasks:
- name: Install Apache
shell: "ls *.war"
register: output
args:
chdir: /opt/ansible/tomcat/demo/webapps
- file:
src: '/opt/ansible/tomcat/demo/webapps/{{ item }}'
dest: '/users/demo/vivek/{{ item }}'
state: link
with_items: "{{output.stdout_lines}}"

Blocks
该 playbook 整体上被分解成块。要执行的最小的步骤编写在块中。以块编写特定说明有助于分离功能,并在需要时通过异常处理来处理它。
The playbook in totality is broken into blocks. The smallest piece of steps to execute is written in block. Writing the specific instruction in blocks helps to segregate functionality and handle it with exception handling if needed.
变量使用、异常处理和循环中的块的示例如上所述。
Example of blocks is covered in variable usage,exception handling and loops above.
Conditionals
条件是根据条件运行具体步骤的地方。
Conditionals are used where one needs to run a specific step based on a condition.
---
#Tsting
- hosts: all
vars:
test1: "Hello Vivek"
tasks:
- name: Testing Ansible variable
debug:
msg: "Equals"
when: test1 == "Hello Vivek"
本例中,由于 test1 变量等于 when 条件中所述,因此将打印 Equals。在所有编程语言中, when 可用于逻辑 OR 和逻辑 AND 条件。
In this case, Equals will be printed as the test1 variable is equal as mentioned in the when condition. when can be used with a logical OR and logical AND condition as in all the programming languages.

只需将 test1 变量的值从 Hello Vivek 更改为 Hello World,即可看到输出。
Just change the value of test1 variable from Hello Vivek to say Hello World and see the output.

Ansible - Advanced Execution
在本节中,我们将了解 Ansible 中的高级执行是什么。
In this chapter, we will learn what is advanced execution with Ansible.
How to Limit Execution by Tasks
这是一个非常重要的执行策略,只需执行一个执行,而不需要整个剧本。 For example ,假设您只想要阻止一个服务器(如果出现生产问题),那么在应用补丁后,您只想要启动服务器。
This is a very important execution strategy where one needs to execute only one execution and not the entire playbook. For example, suppose you only want to stop a server (in case a production issue comes) and then post applying a patch you would like to only start the server.
这里在原始剧本中,中止和启动是同一剧本中不同角色的一部分,但可以使用标签来处理它。我们可以为不同的角色(反过来会有不同的任务)提供不同的标签,因此基于执行者提供的标签,将只执行指定的该角色/任务。所以对于上面提供示例,我们可以添加诸如以下之类的标签 -
Here in original playbook stop and start were a part of different roles in the same playbook but this can be handled with the usage of tags. We can provide different tags to different roles (which in turn will have tasks) and hence based on the tags provided by the executor only that specified role/task gets executed. So for the above example provided, we can add tags like the following −
- {role: start-tomcat, tags: ['install']}}
以下命令有助于使用标签 −
The following command helps in using tags −
ansible-playbook -i hosts <your yaml> --tags "install" -vvv
使用以上命令,只将调用 start-tomcat 角色。所提供的标签是区分大小写的。确保向命令传递完全匹配。
With the above command, only the start-tomcat role will be called. The tag provided is case-sensitive. Ensure exact match is being passed to the command.
How to Limit Execution by Hosts
有两种方法来实现特定主机上指定步骤的执行。对于特定角色,可以定义主机的 - 指定该特定角色应该运行在哪个特定主机上。
There are two ways to achieve the execution of specific steps on specific hosts. For a specific role, one defines the hosts - as to which specific hosts that specific role should be run.
Example
- hosts: <A>
environment: "{{your env}}"
pre_tasks:
- debug: msg = "Started deployment.
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} "
roles:
- {role: <your role>, tags: ['<respective tag>']}
post_tasks:
- debug: msg = "Completed deployment.
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}"
- hosts: <B>
pre_tasks:
- debug: msg = "started....
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} "
roles:
- {role: <your role>, tags: ['<respective tag>']}
post_tasks:
- debug: msg = "Completed the task..
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}"
根据上述示例,根据所提供的,将只调用相应角色。现在,我的主机 A 和 B 在主机(库存文件)中定义。
As per the above example, depending on the hosts provided, the respective roles will only be called. Now my hosts A and B are defined in the hosts (inventory file).
Alternate Solution
一个不同的解决方案可能是使用变量定义剧本的主机,然后通过 --extra-vars 传递一个特定主机地址 −
A different solution might be defining the playbook’s hosts using a variable, then passing in a specific host address via --extra-vars −
# file: user.yml (playbook)
---
- hosts: '{{ target }}'
user: ...
playbook contd….
Running the Playbook
ansible-playbook user.yml --extra-vars "target = "<your host variable>"
如果未定义 {{ target }},该剧本将不执行任何操作。如果需要,还可以传递来自主机文件中的一个组。如果没有提供额外变量,这不造成危害。
If {{ target }} isn’t defined, the playbook does nothing. A group from the hosts file can also be passed through if need be. This does not harm if the extra vars is not provided.
Ansible - Troubleshooting
用于调试 Ansible 剧本的最常用策略是使用下面提供的模块 −
The most common strategies for debugging Ansible playbooks are using the modules given below −
Debug and Register
这两个是 Ansible 中可用的模块。为了调试目的,我们需要谨慎地使用这两个模块。示例演示如下。
These two are the modules available in Ansible. For debugging purpose, we need to use the two modules judiciously. Examples are demonstrated below.
Use Verbosity
使用 Ansible 命令,可以提供详细级别。你可以使用详细级别一 (-v) 或二 (-vv) 运行命令。
With the Ansible command, one can provide the verbosity level. You can run the commands with verbosity level one (-v) or two (-vv).
Important Points
在本节中,我们将介绍几个示例来理解几个概念。
In this section, we will go through a few examples to understand a few concepts.
如果你没有引用以变量开头的参数。例如,
If you are not quoting an argument that starts with a variable. For example,
vars:
age_path: {{vivek.name}}/demo/
{{vivek.name}}
这将引发错误。
This will throw an error.
Solution
vars:
age_path: "{{vivek.name}}/demo/" – marked in yellow is the fix.
How to use register -> Copy this code into a yml file say test.yml and run it
---
#Tsting
- hosts: tomcat-node
tasks:
- shell: /usr/bin/uptime
register: myvar
- name: Just debugging usage
debug: var = myvar
当我通过命令 Ansible-playbook -i hosts test.yml 运行此代码时,我将得到如下所示的输出。
When I run this code via the command Ansible-playbook -i hosts test.yml, I get the output as shown below.
如果你看到 yaml,我们会将命令的输出注册到变量中 – myvar ,然后只打印输出。
If you see the yaml , we have registered the output of a command into a variable – myvar and just printed the output.
标记为黄色的文本告诉我们变量 – myvar 的属性,可用于进一步的流程控制。通过这种方式,我们可以找出特定变量公开的属性。下面的调试命令对此有所帮助。
The text marked yellow, tells us about property of the variable –myvar that can be used for further flow control. This way we can find out about the properties that are exposed of a particular variable. The following debug command helps in this.
$ ansible-playbook -i hosts test.yml
PLAY [tomcat-node] ***************************************************************
**************** ****************************************************************
*************** ******************************
TASK [Gathering Facts] *****************************************************************
************** *****************************************************************
************** **************************
Monday 05 February 2018 17:33:14 +0530 (0:00:00.051) 0:00:00.051 *******
ok: [server1]
TASK [command] ******************************************************************
************* ******************************************************************
************* **********************************
Monday 05 February 2018 17:33:16 +0530 (0:00:01.697) 0:00:01.748 *******
changed: [server1]
TASK [Just debugging usage] ******************************************************************
************* ******************************************************************
************* *********************
Monday 05 February 2018 17:33:16 +0530 (0:00:00.226) 0:00:01.974 *******
ok: [server1] => {
"myvar": {
"changed": true,
"cmd": "/usr/bin/uptime",
"delta": "0:00:00.011306",
"end": "2018-02-05 17:33:16.424647",
"rc": 0,
"start": "2018-02-05 17:33:16.413341",
"stderr": "",
"stderr_lines": [],
"stdout": " 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14",
"stdout_lines": [
" 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14"
]
}
}
PLAY RECAP ****************************************************************************
**********************************************************************************
**************************************
server1 : ok = 3 changed = 1 unreachable = 0 failed = 0
Common Playbook Issues
在本节中,我们将了解几个常见的剧本问题。问题为 −
In this section, we will learn about the a few common playbook issues. The issues are −
-
Quoting
-
Indentation
剧本以 yaml 格式编写,上面两个是最常见的 yaml/剧本问题。
Playbook is written in yaml format and the above two are the most common issues in yaml/playbook.
Yaml 不支持基于制表符的缩进,而是支持基于空格的缩进,因此需要小心处理。
Yaml does not support tab based indentation and supports space based indentation, so one needs to be careful about the same.
Note −完成 yaml 编写后,打开此网站 ( https://editor.swagger.io/ ),并将你的 yaml 复制粘贴到左侧,以确保 yaml 正确编译。这只是一个提示。
Note − once you are done with writing the yaml , open this site(https://editor.swagger.io/) and copy paste your yaml on the left hand side to ensure that the yaml compiles properly. This is just a tip.
Swagger 将错误归类为警告和错误。
Swagger qualifies errors in warning as well as error.