当前位置: 代码迷 >> 综合 >> ansible-在被管理节点上创建文件或目录
  详细解决方案

ansible-在被管理节点上创建文件或目录

热度:64   发布时间:2023-11-30 17:29:39.0

文章目录

  • 1.修改文件并将其复制到主机
    • 1.1 描述文件模块
    • 1.2 files模块的自动化示例
    • 1.2.1 确保受管主机上存在文件
    • 1.2.2 修改文件属性
    • 1.2.3 使SELinux文件上下文更改具有持久性
  • 2. 使用jinja2模板部署自定义文件
    • 2.1 jinja2简介
    • 2.2 构建jinja2模板
    • 2.3 部署jinja2模板
    • 2.4 管理模板文件
    • 2.5 控制结构
    • 2.5.2 使用条件句
    • 2.5.3 变量过滤器
    • 2.5.4 变量测试

1.修改文件并将其复制到主机

1.1 描述文件模块

Files模块库包含的模块允许用户完成与Linux文件管理相关的大多数任务,如创建、复制、编辑和修改文件的权限和其他属性。下表提供了常用文件管理模块的列表:

模块名称 模块说明
blockinfile 插入、更新或删除由可自定义标记线包围的多行文本块
copy 将文件从本地或远程计算机复制到受管主机上的某个位置。 类似于file模块,copy模块还可以设置文件属性,包括SELinux上下文件。
fetch ①此模块的作用和copy模块类似,但以相反方式工作。②此模块用于从远程计算机获取文件到控制节点,并将它们存储在按主机名组织的文件树中。
file ①设置权限、所有权、SELinux上下文以及常规文件、符号链接、硬链接和目录的时间戳等属性。②此模块还可以创建或删除常规文件、符号链接、硬链接和目录。③其他多个与文件相关的模块支持与file模块相同的属性设置选项,包括copy模块。
lineinfile ①确保特定行位于某文件中,或使用反向引用正则表达式来替换现有行。②此模块主要在用户想要更改文件的某一行时使用。
stat 检索文件的状态信息,类似于Linux中的stat命令。
synchronize ①围绕rsync命令的一个打包程序,可加快和简化常见任务。②synchronize模块无法提供对rsync命令的完整功能的访问权限,但确实最常见的调用更容易实施。③用户可能仍需通过run command模块直接调用rsync命令。

模块用法:

?blockinfile控制主机:
[root@king playbook]# >123.yml  //清空文件内容 
[root@king playbook]# vim 123.yml
---
- hosts: alltasks:- name: 编辑文件,将文本块添加到现有文件blockinfile:path: /root/long.txt  //此文件必须是在受管主机上存在block: |   //如果更改block只能在原内容之后追加更改,不然会覆盖原本内容(|管道符表示换行)192.168.120.129192.168.120.1310.0.0.0owner: lisi
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ***********************************************************************************TASK [Gathering Facts] ***********************************************************************
ok: [192.168.120.130]TASK [write content] *************************************************************************
changed: [192.168.120.130]
....
[root@king playbook]# ansible all -m command -a 'cat /root/long.txt'
192.168.120.130 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK //begin和end开头和结尾注释表示为由ansible添加内容
192.168.120.129
192.168.120.131
0.0.0.0
# END ANSIBLE MANAGED BLOCK
?copy---
- hosts: alltasks:- name: 拷贝文件从控制主机到受控主机copy:     src: files/cat.shdest: /root
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ***********************************************************************************TASK [Gathering Facts] ***********************************************************************
ok: [192.168.120.130]TASK [write content] *************************************************************************
changed: [192.168.120.130]PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# ansible all -m command -a 'ls /root'
192.168.120.130 | CHANGED | rc=0 >>
anaconda-ks.cfg
cat.sh
long.txt
?fetch[root@king playbook]# rm -f files/cat.sh
[root@king playbook]# ls files/
[root@king playbook]# vim 123.yml
---
- hosts: alltasks:- name: 从受控主机上拷贝文件到控制主机上(反向拷贝文件)fetch:    src: /root/cat.sh    //源-受控主机dest: files/         //目的-控制主机
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ***********************************************************************************TASK [Gathering Facts] ***********************************************************************
ok: [192.168.120.130]TASK [write content] *************************************************************************
changed: [192.168.120.130]PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# cd files/
[root@king files]# tree
.
└── 192.168.120.130     //(拷贝过来自动创建)以便于管理和查看是从哪个受控主机上拷贝文件└── root└── cat.sh2 directories, 1 file
?file[root@king playbook]# vim 123.yml ---
- hosts: alltasks:- name: 删除受控主机上的文件file:path: /root/cat.shstate: absent  //删除文件
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ***********************************************************************************TASK [Gathering Facts] ***********************************************************************
ok: [192.168.120.130]TASK [write content] *************************************************************************
changed: [192.168.120.130]PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'ls '
192.168.120.130 | CHANGED | rc=0 >>
anaconda-ks.cfg
long.txt
?lineinfile---
- hosts: alltasks:- name: 查找改内容,如果此内容不在则追加添加到文件中lineinfile:path: /root/long.txtline: 'Add this line to the file'state: present
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [查找改内容,如果此内容不在则添加到文件中] *******************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# ansible all -m command -a 'cat long.txt'
192.168.120.130 | CHANGED | rc=0 >>
# BEGIN ANSIBLE MANAGED BLOCK
192.168.120.129
192.168.120.131
0.0.0.0
# END ANSIBLE MANAGED BLOCK
Add this line to the file
?stat
检查文件状态和原来状态是否一样,如果文件内容改变,状态也随之改变---
- hosts: alltasks:- name: 检索受管主机上的文件md5状态stat:path: /root/long.txtchecksum_algorithm: md5register: result- debug:var: result
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [检索受管主机上的文件状态] ***************************************************************************
ok: [192.168.120.130]TASK [debug] **********************************************************************************
ok: [192.168.120.130] => {
    "result": {
    "changed": false,"failed": false,"stat": {
    "atime": 1636708198.4719384,"attr_flags": "","attributes": [],"block_size": 4096,"blocks": 8,"charset": "us-ascii","checksum": "88ea8a188f5c271b5d23251e3e5e5646",.........
?synchronize
synchronize模块是一个围绕rsync工具的打包程序,它简化了playbook中的常见文件管理任务。
**rsync工具必须同时安装在本机和远程主机上**。默认情况下,在使用synchronize模块时,
“本地主机”是同步任务所源自的主机(通常是控制节点),而“目标主机”是synchronize连接到的主机。控制主机上:
[root@king ~]# yum -y install rsync
[root@king ~]# ansible all -m yum -a 'name=rsync state=present'
192.168.120.130 | CHANGED => {
    "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"},"changed": true,"changes": {
    "installed": ["rsync"]},
.........
]
[root@king ~]# ls
-  anaconda-ks.cfg  Game  playbook  somefile
[root@king ~]# cd playbook/
[root@king playbook]# vim 123.yml ---
- hosts: alltasks:- name: 同步控制节点和受管主机之间的文件synchronize:src: /root/somefile    //源--控制主机dest: /tmp            //目的--受控主机
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [同步控制节点和受管主机之间的文件] ***********************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'ls /tmp'
192.168.120.130 | CHANGED | rc=0 >>  已同步目录
somefile
[root@king playbook]# ls /root
-  anaconda-ks.cfg  Game  playbook  somefile

1.2 files模块的自动化示例

在受管主机上创建、复制、编辑和删除文件是用户可以使用Files模块库中的模块实施的常见任务。
以下示例显示了可以使用这些模块自动执行常见文件管理任务的方式。

1.2.1 确保受管主机上存在文件

使用file模块处理受管主机上的文件。其工作方式与touch命令类似,如果不存在则创建一个空文件,如果存在,则更新其修改时间。在本例中,除了处理文件之外,Ansible还确保将文件的所有者、组
(用户和组必须已存在)和权限设置为特定值。

---
- hosts: alltasks:- name: write contentfile:path: /tmp/aaaowner: lisigroup: lisimode: 0744state: touch
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [write content] **************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'ls -l /tmp'
192.168.120.130 | CHANGED | rc=0 >>
total 36
-rwxr--r-- 2 lisi lisi     6 Nov  9 15:54 aaa修改目录的权限后查看创建时间更新没:
[root@king playbook]# vim 123.yml 
[root@king playbook]# ansible-playbook 123.yml
........
[root@king playbook]# ansible all -m command -a 'ls -l /tmp'
192.168.120.130 | CHANGED | rc=0 >>
total 36
-rwxr--rw- 2 lisi lisi     6 Nov  9 15:56 aaa

1.2.2 修改文件属性

使用file模块还可以确保新的或现有的文件具有正确的权限和SELinux类型。

例如,以下文件保留了相对于用户主目录的默认SELinux上下文,这不是所需的上下文。

[root@localhost ~]# ls -Z aaa
- rwxr--rw- lisi lisi unconfined_u:object_r:user_home_t:s0 aaa

以下任务确保了aaa文件的SELinux上下文件类型属性是所需的samba_share_t类型。此行为与Linux中的chcon命令类似。

控制主机:
---
- hosts: alltasks:- name: write contentfile:path: /root/aaasetype: samba_share_t
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [write content] **************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0受控主机:
[root@CAT ~]# ls -Z aaa
- rwxr--rw- lisi lisi unconfined_u:object_r:samba_share_t:s0 aaa

文件属性参数在多个文件管理模块中可用。运行ansible-doc file和ansible-doc copy命令以获取其他信息。

1.2.3 使SELinux文件上下文更改具有持久性

设置文件上下文时,file模块的行为与chcon类似。通过运行restorecon,可能会意外地撤消使用该模块所做的更改。使用file设置上下文后,用户可以使用system模块集合中的sefcontext来更新SELinux策略,如semanage fcontext。

---
- hosts: alltasks:- name: write contentsefcontext:target: /root/anaconda.cfgsetype: samba_share_tstate: present

[root@CAT ~]# ls -Z anaconda-ks.cfg
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
注意:sefcontext模块更新SELinux策略中目标的默认上下文,但不更改现有文件的上下文。

2. 使用jinja2模板部署自定义文件

2.1 jinja2简介

jinja2模板是功能强大的工具,可用于自定义要在受管主机上部署的配置文件。创建了适用于配置文件的jinja2模板后,它可以通过template模板部署到受管主机上,该模块支持将控制节点中的本地文件转移到受管主机。

若要使用template模块,请使用下列语法。与src键关联的值指定来源jinja2模板,而与dest键关联的值指定要在目标主机上创建的文件。


[root@king files]# vim hosts.j2 {
    # 使用jinja2模板部署自定义文件 #}     //注释(自定义解释)
{
    {
     ansible_facts ['all_ipv4_addresses'] }} {
    {
     ansible_facts ['date_time']['date'] }} //变量内容

2.2 构建jinja2模板

jinja2模板由多个元素组成:数据、变量和表达式。在呈现jinja2模板时,这些变量和表达式被替换为对应的值。模板中使用的变量可以在playbook的vars部分中指定。可以将受管主机的事实用作模板中的变量。

请记住,可以使用ansible system_hostname -i inventory_file -m setup命令来获取与受管主机相关的事实。

下例演示了如何使用变量及Ansible从受管主机检索的事实创建/etc/ssh/sshd_config的模板。当执行相关的playbook时,任何事实都将被替换为所配置的受管主机中对应的值。

注意:包含jinja2模板的文件不需要有任何特定的文件扩展名(如.j2)。但是,提供此类文件扩展名会让你更容易记住它是模板文件。

# {
    {
     ansible_managed }}
# DO NOT MAKE LOCAL MODIFICATIONS TO THIS FILE AS THEY WILL BE LOSTPort {
    {
     ssh_port }}
ListenAddress {
    {
     ansible_facts['default_ipv4']['address'] }}HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_keySyslogFacility AUTHPRIVPermitRootLogin {
    {
     root_allowed }}
AllowGroups {
    {
     groups_allowed }}AuthorizedKeyFile /etc/.rht_authorized_keys .ssh/authorized_keysPasswordAuthentication {
    {
     passwords_allowed }}ChallengeResponseAuthentication noGSSAPIAuthentication yes
GSSAPICleanupCredentials noUsePAM yesX11Forwarding yes
UsePrivilegeSeparation sandboxAcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERSSubsystem sftp /usr/libexec/openssh/sftp-server

2.3 部署jinja2模板

jinja2模板是功能强大的工具,可用于自定义要在受管主机上部署的配置文件。创建了适用于配置文件的jinja2模板后,它可以通过template模板部署到受管主机上,该模块支持将控制节点中的本地文件转移到受管主机。

若要使用template模块,请使用下列语法。与src键关联的值指定来源jinja2模板,而与dest键关联的值指定要在目标主机上创建的文件。

[root@king files]# vim hosts.j2 {
    # 使用jinja2模板部署自定义文件 #}     //注释(自定义解释)
{
    {
     ansible_facts ['all_ipv4_addresses'] }} {
    {
     ansible_facts ['date_time']['date'] }} //变量内容
{
    {
     ansible_facts ['architecture'] }} {
    {
     ansible_facts ['bios_date'] }}[root@king files]# cd ..
[root@king playbook]# vim 123.yml ---
- hosts: alltasks:- name: 使用jinja2模板部署自定义文件template:src: files/hosts.j2dest: /etc/hosts
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [使用jinja2模板部署自定义文件] **********************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /etc/hosts'
192.168.120.130 | CHANGED | rc=0 >>
['192.168.120.130'] 2021-11-09
x86_64 07/22/2020

template模块还允许指定已部署文件的所有者、组、权限和SELINUX上下文,就像file模块一样。它也可以取用validate选项运行任意命令(如visudo -c),在将文件复制到位之前检查该文件的语法是否正确。
有关更多详细信息↓

ansible-doc template

2.4 管理模板文件

为避免系统管理员修改Ansible部署的文件,最好在模板顶部包含注释,以指示不应手动编辑该文件。

可使用ansible_managed指令中设置的"Ansible managed"字符串来执行此操作。这不是正常变量,但可以在模板中用作一个变量。ansible_managed指令在ansible.cfg文件中设置:

[root@king playbook]# vim /etc/ansible/ansible.cfg //文件默认就是此设置,可以进行更改
#ansible_managed = Ansible managed
如:
ansible_managed = ansible管理输出内容 //可自定义修改
[root@king playbook]# ansible all -m command -a 'cat /etc/hosts' //执行过后结果
192.168.120.130 | CHANGED | rc=0 >>
#ansible管理内容输出
['192.168.120.130'] 2021-11-12
x86_64 07/22/2020

要将ansible_managed字符串包含在jinja2模板内,请使用下列语法:

[root@king playbook]# vim files//hosts.j2 #{
    {
     ansible_managed }}
{
    # 使用jinja2模板部署自定义文件 #}
{
    {
     ansible_facts ['all_ipv4_addresses'] }} {
    {
     ansible_facts ['date_time'] ['date'] }}
{
    {
     ansible_facts ['architecture'] }} {
    {
     ansible_facts ['bios_date'] }}
[root@king playbook]# vim 123.yml 
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [使用jinja2模板部署自定义文件] **********************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /etc/hosts'
192.168.120.130 | CHANGED | rc=0 >>
#Ansible managed
['192.168.120.130'] 2021-11-12
x86_64 07/22/2020

2.5 控制结构

用户可以在模板文件中使用jinja2控制结构,以减少重复输入,为play中的每个主机动态输入条目,或者有条件地将文本插入到文件中。

2.5.1 使用循环
jinja2使用for语句来提供循环功能。在下例中,user变量替换为users变量中包含的所有值,一行一个值。(for:表示开始;endfor:表示结束)

[root@king playbook]# vim files/user.j2{
    % for user in users %}  //针对用户组变量里的用户{
    {
     user }}            //循环里面用户
{
    % endfor %}              //结束
[root@king playbook]# vim 123.yml 
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>jimkimbobjerry

以下示例模板使用for语句逐一运行users变量中的所有值,将myuser替换为各个值,但值为rbob时除外。

[root@king playbook]# vim files/user.j2 
//不打印用户bob其它的都逐一打印并以用户序号1、2、3打印在受控主机文件里
{
    % for myuser in users if not myuser == "bob" %}
User number {
    {
     loop.index }} - {
    {
     myuser }}
{
    % endfor %}
[root@king playbook]# vim 123.yml 
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
User number 1 - jim
User number 2 - kim
User number 3 - jerry

loop.index变量扩展至循环当前所处的索引号。它在循环第一次执行时值为1,每一次迭代递增1。

再如,此模板也使用了for语句,并且假定使用的清单文件中已定义了myhosts变量。此变量将包含要管理的主机的列表。使用下列for语句时,文件中将列出清单myhosts组内的所有主机。(存在多台主机使用)

{
    % for myhost in groups['myhosts'] %}
{
    {
     myhost }}
{
    % endfor %}

举一个更实际的例子,用户可以使用该模板从主机事实动态生成/etc/hosts文件。假设playbook如下:

- name: /etc/hosts is up to datehosts: allgather_facts: yestasks:- name: Deploy /etc/hoststemplate:src: templates/hosts.j2dest: /etc/hosts

下述几行templates/hosts.j2模板从all组中的所有主机构造文件。(由于变量名称的长度,模板的中间行非常长。)它迭代组中的每个主机以获得/tmp/user文件的两个事实。

[root@king playbook]# vim files/user.j2
{
    % for host in groups['all'] %}
{
    {
     ansible_facts ['all_ipv4_addresses'] }}     {
    {
     ansible_facts ['hostname'] }}
{
    % endfor %}
[root@king playbook]# vim 123.yml 
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
['192.168.120.130']     CAT

2.5.2 使用条件句

jinja2使用if语句来提供条件控制。如果满足某些条件,这允许用户在已部署的文件中放置一行。

在以下示例中,仅当finished变量的值为True时,才可将result变量的值放入已部署的文件。
如果是False,就不会把值放入部署的文件中-值空。

[root@king playbook]# vim files/user.j2 {
    % if True %}{
    {
     ansible_managed }}
{
    % endif %}
[root@king playbook]# vim 123.yml
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>ansible管理内容输出
{
    % if False %}{
    {
     ansible_managed }}
{
    % endif %}
[root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>//不会输入,为空值

注意,在Ansible模板中我们可以使用jinja2循环和条件,但不能在Ansible Playbook中使用。

2.5.3 变量过滤器

jinja2提供了过滤器,更改模板表达式的输出格式(例如,输出到果JSON)。有适用于YAML和JSON等语言的过滤器。to_json过滤器使用JSON格式化表达式输出,to_yaml过滤器则使用YAML格式化表达式输出。

[root@king playbook]# vim files/user.j2 
{
    {
     ansible_facts ['python'] | to_json }}[root@king playbook]# vim 123.yml
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
{
    "executable": "/usr/bin/python", "version": {
    "micro": 5, "major": 2, "releaselevel": "final", "serial": 0, "minor": 7}, "type": "CPython", "has_sslcontext": true, "version_info": [2, 7, 5, "final", 0]}

也有其他过滤器,如to_nice_jsonto_nice_yaml过滤器,它们将表达式输出格式化为JSON或YAML等人类可读格式。

[root@king playbook]# vim files/user.j2 {
    {
     ansible_facts ['python'] | to_nice_json }}
{
    {
     ansible_facts ['python'] | to_nice_yaml }}[root@king playbook]# vim 123.yml
[root@king playbook]# ansible-playbook 123.yml PLAY [all] ************************************************************************************TASK [Gathering Facts] ************************************************************************
ok: [192.168.120.130]TASK [for user] *******************************************************************************
changed: [192.168.120.130]PLAY RECAP ************************************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
{
    "executable": "/usr/bin/python","has_sslcontext": true,"type": "CPython","version": {
    "major": 2,"micro": 5,"minor": 7,"releaselevel": "final","serial": 0},"version_info": [2,7,5,"final",0]
}
executable: /usr/bin/python
has_sslcontext: true
type: CPython
version:major: 2micro: 5minor: 7releaselevel: finalserial: 0
version_info:
- 2
- 7
- 5
- final
- 0

from_json和from_yaml过滤器相应要求JSON或YAML格式的字符串,并对它们进行解析。

[root@king playbook]# vim files/user.j2 {
    {
     '{ "name": "lisi"}' | from_json }}
.....
[root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
{
    'name': 'lisi'}可多个格式进行解析:
[root@king playbook]# vim files/user.j2 {
    {
     '{ "name": "lisi", "age": 10}' | from_json | to_nice_yaml }}[root@king playbook]# ansible all -m command -a 'cat /tmp/user'
192.168.120.130 | CHANGED | rc=0 >>
age: 10
name: lisi

2.5.4 变量测试

在Ansible Playbook中与when子句一同使用的表达式是jinja2表达式。用于测试返回值的内置Ansible测试包括failed、changed、successded和skipped。以下任务演示了如何在条件表达式内使用测试。

tasks:
...output omitted...- debug: msg="the execution was aborted"when: returnvalue is failed