ansible-playbook-流程控制

条件判断在 Ansible 任务中的使用频率非常高。有些任务使用带有幂等性检查的模块,比如 yum 和 apt 模块可以检测软件包是否已被
安装,而在这个过程中我们不用做太多的人工干预

when

案例:
有一款软件版本号为 4.6.1,现在有一个任务需要通过判断软件的版本号来确定要不要执行接下来的任务,如果主版本号为 4 就执行任
务,其他版本则不执行。
使用点号”.”进行软件版本号分割,取第一个主版本号对比

1
2
3
- name: 当软件版本号为4时进行操作
[task here]
when: soft_version.splilt('.')[0] == '4'

变量注册器register

大部分情况下,我们使用注册器用来接收 shell 命令的返回结果,结果中包含标准输出(stdout)和错误输出(stderr)。使用下面一段代
码即可调用注册器来获取 shell 命令的返回结果。

1
2
- shell: my_command_here
register: my_command_result

命令结果获取完成之后,可以使用注册变量的 stdout 方法来读取标准输出的内容:my_command_result.stdout; 使用 stderr 方法来
读取标准输入的内容: my_command_result.stderr。

1
2
3
4
- command: my-app --status
register: myapp_result
- command: do-something-to-my-app
when: "'ready' in myapp_result.stdout"

changed_when

对于 Ansible 来说,其很难判断一个命令的运行是否符合符合我们的实际预期,尤其是当我们使用 command 模块和 shell 模块时, 如果
不使用 changed_when 语句, Ansible 将永远返回 changed。大部分模块都能正确返回运行结果是否对目标主机产生影响,我们依然可
以使用 changed_when 语句来对返回信息进行重写,根据任务返回结果来判定任务的运行结果是否真正符合我们预期。

1
2
3
4
- name: Install dependencies via Composer.
command: "/usr/local/bin/composer global require phpunit/phpunit --prefer-dist"
register: composer
changed_ when: "'Nothing to install or update' not in composer. stdout"

由此我们可以看出,当 PHP Composer 安装或升级了某些软件的时候,也就是其运行结果中不包含”Nothing to install or update”字段
的时候,Ansible 才会返回运行状态为 changed,这更符合我们的需要。

failed_when

有一些命令会将自己的运行结果写入标准错误输出 stderr 中,而不是通常的标准输出 stdout 中, 这时可以使用 failed_when 来对结
果进行判断, 从而告诉 Ansible 真正的运行结果到底是成功还是失败。
在下面的例子中,我们将通过判断 Jenkins CLI 命令的错误输出来判定命令是否真的运行失败:

1
2
3
4
- name: 通过 CLI 导入 Jenkins 任务
shell: > java -jar /opt/jenkins-cli.jar -s http://localhost:8080/create-job "My Job" < /usr/local/my-job.xml
register: import failed_when: "import.stderr and 'already exists' not in import.stderr"
-

ignore_ errors

我们不应过度依赖 ignore_errors,因为它会隐藏所有的报错信息,而应该把精力集中在寻找报错的原因上面, 这样才能从根本上解决
问题。