ansible常用模块介绍

1. command modules

选项:

  • chdir 在运行命令之前,先切换到指定目录:

      [root@web1 ~]# ansible web -m command -a "ls -l chdir=/tmp"
      192.168.1.21 | SUCCESS | rc=0 >>
      total 168
      drwx------  2 root   root    4096 Sep 20 09:33 ansible_UaZm9Y
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      drwxr-xr-x  3 root   root    4096 Aug 12 21:09 pear
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-------  1 root   root   67800 Jul 27 21:35 yum_save_tx-2017-07-27-21-35n2gP71.yumtx
      -rw-rw-r--  1 zabbix zabbix 81445 Aug 12 14:42 zabbix_agentd.log
      -rw-rw-r--  1 zabbix zabbix     5 Aug 12 08:37 zabbix_agentd.pid
      
      192.168.1.22 | SUCCESS | rc=0 >>
      total 64
      drwx------  2 root   root    4096 Sep 20 09:33 ansible__iQSmn
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      srwxrwxrwx  1 mysql  mysql      0 Sep 20 08:38 mysql.sock
      drwxr-xr-x  3 root   root    4096 Aug 13 10:42 pear
      -rw-r--r--  1 root   root       0 Sep 20 09:30 test
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-rw-r--  1 zabbix zabbix 48406 Aug 12 14:41 zabbix_agentd.log
    
  • creates 指定文件(目录)名,如果文件存在,就不执行命令。

      [root@web1 ~]# ansible web -m command -a "ls -l /tmp creates=/tmp/test"
      192.168.1.21 | SUCCESS | rc=0 >>
      total 168
      drwx------  2 root   root    4096 Sep 20 09:37 ansible_PO0TDu
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      drwxr-xr-x  3 root   root    4096 Aug 12 21:09 pear
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-------  1 root   root   67800 Jul 27 21:35 yum_save_tx-2017-07-27-21-35n2gP71.yumtx
      -rw-rw-r--  1 zabbix zabbix 81445 Aug 12 14:42 zabbix_agentd.log
      -rw-rw-r--  1 zabbix zabbix     5 Aug 12 08:37 zabbix_agentd.pid
      
      192.168.1.22 | SUCCESS | rc=0 >>
      skipped, since /tmp/test exists
    
  • removes 后面指定一个文件(目录)名,如果指定的文件(目录)不存在,则不运行命令。

      [root@web1 ~]# ansible web -m command -a "ls -l /tmp removes=/tmp/test"
      192.168.1.21 | SUCCESS | rc=0 >>
      skipped, since /tmp/test does not exist
      
      192.168.1.22 | SUCCESS | rc=0 >>
      total 64
      drwx------  2 root   root    4096 Sep 20 09:38 ansible_PC7a8Y
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      srwxrwxrwx  1 mysql  mysql      0 Sep 20 08:38 mysql.sock
      drwxr-xr-x  3 root   root    4096 Aug 13 10:42 pear
      -rw-r--r--  1 root   root       0 Sep 20 09:30 test
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-rw-r--  1 zabbix zabbix 48406 Aug 12 14:41 zabbix_agentd.log
    

2. script modules

在远程主机上运行本地脚本

        [root@web1 shell.sh]# vim test.sh 
    #!/bin/bash
    echo "hello world!"
    ~     
    [root@web1 shell.sh]# ansible web -m script -a "test.sh"
    192.168.1.21 | SUCCESS => {
        "changed": true, 
        "rc": 0, 
        "stderr": "Shared connection to 192.168.1.21 closed.\r\n", 
        "stdout": "hello world!\r\n", 
        "stdout_lines": [
            "hello world!"
        ]
    }
    192.168.1.22 | SUCCESS => {
        "changed": true, 
        "rc": 0, 
        "stderr": "Shared connection to 192.168.1.22 closed.\r\n", 
        "stdout": "hello world!\r\n", 
        "stdout_lines": [
            "hello world!"
        ]
    }

creates和removes参数和command模块的这两个参数类似

[root@web1 shell.sh]# ansible web -m script -a "/root/shell.sh/test.sh creates=/tmp/test"
192.168.1.22 | SKIPPED
192.168.1.21 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.1.21 closed.\r\n", 
    "stdout": "hello world!\r\n", 
    "stdout_lines": [
        "hello world!"
    ]
}
[root@web1 shell.sh]# ansible web -m script -a "/root/shell.sh/test.sh removes=/tmp/test"
192.168.1.21 | SKIPPED
192.168.1.22 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.1.22 closed.\r\n", 
    "stdout": "hello world!\r\n", 
    "stdout_lines": [
        "hello world!"
    ]
}

3. shell modules

在远程节点上执行命令,也可以执行一个shell脚本,但是该脚本必须在远程节点上存在。

chdir 、creates、removes、command模块的参数一样。

[root@web1 shell.sh]# ansible web -m shell -a "echo $HOME"
192.168.1.21 | SUCCESS | rc=0 >>
/root

192.168.1.22 | SUCCESS | rc=0 >>
/root

[root@web1 shell.sh]# ansible web -m shell -a "echo $HOME removes=/tmp/test" 
192.168.1.21 | SUCCESS | rc=0 >>
skipped, since /tmp/test does not exist

192.168.1.22 | SUCCESS | rc=0 >>
/root

[root@web1 shell.sh]# ansible web -m shell -a "/root/shell.sh/test.sh  removes=/tmp/test" 
192.168.1.21 | SUCCESS | rc=0 >>
skipped, since /tmp/test does not exist
#执行失败是因为远程主机上,并没有这个脚本。
192.168.1.22 | FAILED | rc=127 >>
/bin/sh: /root/shell.sh/test.sh: No such file or directory

4.copy modules

复制本地文件到远程路径下。

  • src 本地文件的绝对路径,或者相对路径。如果是个路径会递归复制,路径如果是/结尾,只复制目录里面的内容,如果不是以/结尾,会复制目录本身和里面的内容。

  • dest 必选参数,为目标文件指定远程节点上的一个绝对路径,如果src是一个目录,那么该参数也必须指定一个目录。

  • backup 可选参数,如果源文件改变。就为目标文件创建一个备份文件,给备份文件添加一个时间戳信息,值为yes或者no,默认为no。

      [root@web1 shell.sh]# ansible web -m copy -a "src=test.sh dest=/root/"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "checksum": "f3f7435d0a20eb859ff4b97bfb67c594fa71cf8c", 
          "dest": "/root/test.sh", 
          "gid": 0, 
          "group": "root", 
          "md5sum": "e9f6c05023d61dba208370895b7ebf87", 
          "mode": "0644", 
          "owner": "root", 
          "size": 32, 
          "src": "/root/.ansible/tmp/ansible-tmp-1505874564.52-157402683765598/source", 
          "state": "file", 
          "uid": 0
      }
      192.168.1.22 | SUCCESS => {
          "changed": true, 
          "checksum": "f3f7435d0a20eb859ff4b97bfb67c594fa71cf8c", 
          "dest": "/root/test.sh", 
          "gid": 0, 
          "group": "root", 
          "md5sum": "e9f6c05023d61dba208370895b7ebf87", 
          "mode": "0644", 
          "owner": "root", 
          "size": 32, 
          "src": "/root/.ansible/tmp/ansible-tmp-1505874564.65-69782187734750/source", 
          "state": "file", 
          "uid": 0
      }
      #在为目标文件创建一个备份文件。
      [root@web1 shell.sh]# echo "hello" >>test.sh
      [root@web1 shell.sh]# ansible web -m copy -a "src=test.sh dest=/root/shell/ backup=yes"
      192.168.1.22 | SUCCESS => {
          "backup_file": "/root/shell/test.sh.12903.2017-09-20@10:46:50~", 
          "changed": true, 
          "checksum": "cb613f058ae5f2a3e326da2a3343cbfbdd14e62d", 
          "dest": "/root/shell/test.sh", 
          "gid": 0, 
          "group": "root", 
          "md5sum": "e68983f2b04c89ead4afb061ad1313b0", 
          "mode": "0644", 
          "owner": "root", 
          "size": 38, 
          "src": "/root/.ansible/tmp/ansible-tmp-1505875610.03-205491280550072/source", 
          "state": "file", 
          "uid": 0
      }
      192.168.1.21 | SUCCESS => {
          "backup_file": "/root/shell/test.sh.2627.2017-09-20@10:46:50~", 
          "changed": true, 
          "checksum": "cb613f058ae5f2a3e326da2a3343cbfbdd14e62d", 
          "dest": "/root/shell/test.sh", 
          "gid": 0, 
          "group": "root", 
          "md5sum": "e68983f2b04c89ead4afb061ad1313b0", 
          "mode": "0644", 
          "owner": "root", 
          "size": 38, 
          "src": "/root/.ansible/tmp/ansible-tmp-1505875610.11-210337191627097/source", 
          "state": "file", 
          "uid": 0
      }
    
  • directory_mode 当递归复制的时候,为所创建的目录设置权限。如果没有指定则使用系统默认的权限。该参数只影响新创建的目录,不会影响已经存在的目录。

      [root@web1 ~]# ansible web -m copy -a "src=/root/shell.sh/ dest=/root/shell.sh/ directory_mode=0777"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "dest": "/root/shell.sh/", 
          "src": "/root/shell.sh"
      }
      [root@localhost ~]# ll -d shell.sh
      drwxrwxrwx 2 root root 4096 Sep 20 14:33 shell.sh
    
  • force 该参数默认值为yes,当远程文件与本地文件内容不一致时,会替换远程文件。远程文件不存在时,会传输文件。

  • group 设置远程文件或者目录的所属组

  • mode 设置文件或者目录的权限

  • owner 设置文件或者目录的所有者

      [root@web1 ~]# ansible web -m copy -a "src=/root/shell.sh/ dest=/root/shell.sh/ group=jiajie"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "dest": "/root/shell.sh/", 
          "src": "/root/shell.sh"
      }
      [root@localhost shell.sh]# ll
      total 16
      -rw-r--r-- 1 root jiajie 3897 Sep 20 14:33 config_install_lampV2.sh
      -rw-r--r-- 1 root jiajie  139 Sep 20 14:33 ipvsadm.save
      -rw-r--r-- 1 root jiajie  577 Sep 20 14:33 ssh_scp.sh
      -rw-r--r-- 1 root jiajie   38 Sep 20 14:33 test.sh
      # ansible web -m copy -a "src=/root/shell.sh/ dest=/root/shell.sh/ group=jiajie mode=0755"
      192.168.1.21 | SUCCESS => {
      "changed": true, 
       "dest": "/root/shell.sh/", 
      "src": "/root/shell.sh"
      }
      [root@localhost shell.sh]# ll
      total 16
      -rwxr-xr-x 1 root jiajie 3897 Sep 20 14:33 config_install_lampV2.sh
      -rwxr-xr-x 1 root jiajie  139 Sep 20 14:33 ipvsadm.save
      -rwxr-xr-x 1 root jiajie  577 Sep 20 14:33 ssh_scp.sh
      -rwxr-xr-x 1 root jiajie   38 Sep 20 14:33 test.sh
      [root@web1 ~]# ansible web -m copy -a "src=/root/shell.sh/ dest=/root/shell.sh/ owner=jiajie group=jiajie mode=0755"
      [root@localhost shell.sh]# ll
      total 16
      -rwxr-xr-x 1 jiajie jiajie 3897 Sep 20 14:33 config_install_lampV2.sh
      -rwxr-xr-x 1 jiajie jiajie  139 Sep 20 14:33 ipvsadm.save
      -rwxr-xr-x 1 jiajie jiajie  577 Sep 20 14:33 ssh_scp.sh
      -rwxr-xr-x 1 jiajie jiajie   38 Sep 20 14:33 test.sh
    

5.fetch modules

将远程主机中的文件拷贝到本机中,和copy模块恰好相反。并且在保存的时候使用在主机名下的形式来进行保存。

  • dest 用来存放文件的目录。

  • src 指定拉取远程文件的名字,只能为文件,不能是目录。

  • fail_on_missing 如果设置为yes,当源文件不存在的时候,将会失败。

  • flat 允许覆盖默认行为从hostname/path到/file的,如果dest以/结尾,它将使用源文件的基础名称

  • validate_checksum 当文件fetch之后进行md5检查

      [root@web1 ~]# ansible web -m command -a 'ls -l /tmp'
      192.168.1.21 | SUCCESS | rc=0 >>
      total 168
      drwx------  2 root   root    4096 Sep 20 15:13 ansible_jDhFlL
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      drwxr-xr-x  3 root   root    4096 Aug 12 21:09 pear
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-------  1 root   root   67800 Jul 27 21:35 yum_save_tx-2017-07-27-21-35n2gP71.yumtx
      -rw-rw-r--  1 zabbix zabbix 81445 Aug 12 14:42 zabbix_agentd.log
      -rw-rw-r--  1 zabbix zabbix     5 Aug 12 08:37 zabbix_agentd.pid
    
      [root@web1 ~]# ansible web -m command -a 'ls -l /tmp'
      192.168.1.21 | SUCCESS | rc=0 >>
      total 168
      drwx------  2 root   root    4096 Sep 20 15:13 ansible_jDhFlL
      -rw-------. 1 root   root      95 Jul 26 04:15 crontab.O7izOx
      drwxr-xr-x  3 root   root    4096 Aug 12 21:09 pear
      -rw-------. 1 root   root       0 Jul 26 03:49 yum.log
      -rw-------  1 root   root   67800 Jul 27 21:35 yum_save_tx-2017-07-27-21-35n2gP71.yumtx
      -rw-rw-r--  1 zabbix zabbix 81445 Aug 12 14:42 zabbix_agentd.log
      -rw-rw-r--  1 zabbix zabbix     5 Aug 12 08:37 zabbix_agentd.pid
      
    
      [root@web1 ~]# ansible web -m fetch -a "dest=/root/test src=/tmp/yum.log"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
          "dest": "/root/test/192.168.1.21/tmp/yum.log", 
          "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
          "remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
          "remote_md5sum": null
      }
      [root@web1 ~]# tree test
      test
      └── 192.168.1.21
          └── tmp
              └── yum.log
      
      2 directories, 1 file
    

6.stat modules

检索文件或者文件系统的状态。

  • path 指明文件的路径

  • follow 无默认值。是否获取链接所指向源文件的信息。默认情况下,当path是个符号链接的时候,只获取符号链接本身的信。

      [root@web1 tmp]# ansible web -m stat -a "path=/tmp/yum.log"
      192.168.1.21 | SUCCESS => {
          "changed": false, 
          "stat": {
              "atime": 1505891687.684082, 
              "attr_flags": "e", 
              "attributes": [
                  "extents"
              ], 
              "block_size": 4096, 
              "blocks": 0, 
              "charset": "binary", 
              "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
              "ctime": 1501012146.7690001, 
              "dev": 64768, 
              "device_type": 0, 
              "executable": false, 
              "exists": true, 
              "gid": 0, 
              "gr_name": "root", 
              "inode": 391682, 
              "isblk": false, 
              "ischr": false, 
              "isdir": false, 
              "isfifo": false, 
              "isgid": false, 
              "islnk": false, 
              "isreg": true, 
              "issock": false, 
              "isuid": false, 
              "md5": "d41d8cd98f00b204e9800998ecf8427e", 
              "mimetype": "application/x-empty", 
              "mode": "0600", 
              "mtime": 1501012146.7690001, 
              "nlink": 1, 
              "path": "/tmp/yum.log", 
              "pw_name": "root", 
              "readable": true, 
              "rgrp": false, 
              "roth": false, 
              "rusr": true, 
              "size": 0, 
              "uid": 0, 
              "version": "18446744073615032431", 
              "wgrp": false, 
              "woth": false, 
              "writeable": true, 
              "wusr": true, 
              "xgrp": false, 
              "xoth": false, 
              "xusr": false
          }
      }
    

7. lineinfile modules

指定文件的行,使用正则的后向引用替换某一行内容

  • backup 默认为no,是否在修改之前为目标文件做一个备份

  • state 默认为present,指定的行是否存在

  • create 默认为no,当state=present时,指定该参数为yes表示当文件不存在时自动创建。默认情况下当文件不存在时返回错

  • dest 要操作的目标文件路径。

  • line 需要指定state=present,将新的一行插入文件或替换其中的某行内容。如果指定了backrefs=yes,则可以使用正则表达式的后向引用功能。

  • regexp 正则表达式, 若state=present,则为替换匹配到的行,只替换最后一次匹配到的行.若state=absent,会删除匹配到的行

  • backrefs 默认为no,是否使用正则表达式的后向引用。

  • insertafter 默认为EOF, state=present,将会在最后一次匹配到内容的后边插入新的指定内容。EOF表示在文件默认插入一个新行。 如果正则表达式没有匹配到任何内容则效果和使用EOF一样, 表示在文件默认加入新行。

  • insertbefore 默认是不启用该选项,需要state=present,在最后一次匹配到的行之前添加新行。BOF表示在文件开头新加一行, 如果正则表达式没有匹配到任何内容则在文件开头新加一行

      #追加行HOST=127.0.0.1
      [root@web1 tmp]# ansible web -m lineinfile -a "dest=/root/test.txt line=HOST=127.0.0.1"
      192.168.1.21 | SUCCESS => {
          "backup": "", 
          "changed": true, 
          "msg": "line added"
      }
      #将HOST=127.0.0.1替换成HOST=192.168.1.1
      [root@web1 tmp]# ansible web -m lineinfile -a "dest=/root/test.txt regexp=^HOST line=HOST=192.168.1.1"
      192.168.1.21 | SUCCESS => {
          "backup": "", 
          "changed": true, 
          "msg": "line replaced"
      }
      #删除HOST=192.168.1.1
      [root@web1 tmp]# ansible web -m lineinfile -a "dest=/root/test.txt  line=HOST=192.168.1.1 state=absent"
      192.168.1.21 | SUCCESS => {
          "backup": "", 
          "changed": true, 
          "found": 1, 
          "msg": "1 line(s) removed"
      }
      
      #在匹配到的HOST行后面加一行。如果没有匹配到就自动追加一行在最后
      [root@web1 tmp]# ansible web -m lineinfile -a "dest=/root/test.txt  line=web_nginx insertafter=^HOST"
      192.168.1.21 | SUCCESS => {
          "backup": "", 
          "changed": true, 
          "msg": "line added"
      }
    

8.template modules

将控制节点的模板文件做变量替换后,传到远程节点。

  • backup 默认为no,是否备份目标文件
  • dest 要操作的文件在远程节点上的路径
  • force 默认为yes,当目标文件与源文件内容不一样的时候,目标文件会被替换。若改为no,该文件只能不存在的时候被传输一次
  • src 模板文件的路径, 可以是绝对路径也可以是相对路径。

9.cron modules

管理cron.d和crontab计划任务

  • backup 默认不启用, 在修改之前是否将原来的计划任务备份。

  • cron_file 默认不启用, 如果指定, 将使用指定的文件代替用户的crontab.该文件应该都在cron.d目录下。

  • day 默认为*,日(1-31,,/2)

  • hour 默认为*,时 (0-23,,/2)

  • minute 默认为*,分(0-59,,/2)

  • month 默认为*,月(1-12,,/2)

  • weekday 默认为*,周(0-6,*)

  • job 计划任务要执行的命令

  • user 要管理哪个用户的计划任务

  • state 默认为present,当为absent时, 可以按照计划任务name删除指定条目

  • special_time 默认不启用。 可以指定某个特殊时间运行的任务。reboot重启的时候执行,yearly每年执行一次,annually每月执行一次,monthly每个月执行一次,weekly每周执行一次,daily每年执行一次,hourly每小时执行一次

      [root@web1 tmp]# ansible web -m cron -a "name='test crom' hour=3,5 job='ls -l >>/dev/null' user=jiajie"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "envs": [], 
          "jobs": [
              "test crom"
          ]
      }
      [root@localhost ~]# cat  /var/spool/cron/jiajie 
      #Ansible: test crom
      * 3,5 * * * ls -l >>/dev/null
      
      #删除计划任务
      [root@web1 tmp]# ansible web -m cron -a "name='test crom' user=jiajie state=absent"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "envs": [], 
          "jobs": []
      }
      #重启执行计划任务
      [root@web1 tmp]# ansible web -m cron -a "name='test crom' user=jiajie special_time=reboot job='ls -l'"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "envs": [], 
          "jobs": [
              "test crom"
          ]
      }
      [root@localhost tmp]# cat  /var/spool/cron/jiajie 
      #Ansible: test crom
      @reboot ls -l
    

10.service modules

远程管理服务模块,支持这几种服务模式: BSD init, OpenRC, SysV, Solaris SMF, systemd, upstart

  • enabled 服务是否开机启动

  • must_exist 默认为True,避免当某个服务不存在的时候, 模块执行终止。

  • name 服务名称。

  • runlevel 默认值是服务本身的默认设置。 该服务的运行级别。

  • state 对服务要执行的操作, started,stopped,restarted,reloaded

  • args 需要给命令提供的附加参数

      #开启防火墙
      [root@web1 tmp]# ansible web -m service -a "name=iptables state=started"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "name": "iptables", 
          "state": "started"
      }
      #设置开机自启动
      [root@web1 tmp]# ansible web -m service -a "name=iptables  enabled=yes"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "enabled": true, 
          "name": "iptables"
      }
    

11.setup modules

获取远程主机的facts信息。该模块会自动调用playbooks获取远程节点的信息

  • fact_path fact文件路径, 默认在/etc/ansible/facts.d, 利用该文件可以自定义本节点的facts信息, 默认是不存在的。

  • filter 过滤返回的facts信息

      [root@web1 tmp]# ansible web -m setup
      192.168.1.21 | SUCCESS => {
          "ansible_facts": {
              "ansible_all_ipv4_addresses": [
                  "192.168.1.21"
              ], 
              "ansible_all_ipv6_addresses": [
                  "fe80::20c:29ff:fe39:730e"
              ], 
              "ansible_apparmor": {
                  "status": "disabled"
              }, 
              "ansible_architecture": "x86_64", 
              "ansible_bios_date": "07/02/2015", 
              "ansible_bios_version": "6.00", 
              "ansible_cmdline": {
                  "KEYBOARDTYPE": "pc", 
          .....
    

12.yum modules

使用yum包管理器管理软件包

  • name 软件包的名称, 同时也可以指定包的版本,如name-1.0。当指定state=latest,该选项指定参数*,这表示要更新所有的软件包, 和运行命令yum -y update作用一致。该选项也可以指定一个rpm包的url链接,或者一个本地的rpm路径。如果需要指定多个软件包以','隔开即可。

  • state 指定对软件包的操作行为,删除或者安装。默认为present表示安装包。其他可以指定的值,present,latest都是安装包, absent表示卸载包。update_cache 在state=present或state=latest是否强制更新缓存。

      [root@web1 tmp]# ansible web -m yum -a "name=tree"
      192.168.1.21 | SUCCESS => {
          "changed": false, 
          "msg": "", 
          "rc": 0, 
          "results": [
              "tree-1.5.3-3.el6.x86_64 providing tree is already installed"
          ]
      }
      [root@web1 tmp]# ansible web -m yum -a "name=tree state=absent"
      192.168.1.21 | SUCCESS => {
          "changed": true, 
          "msg": "", 
          "rc": 0, 
          "results": [