アドホックコマンド

アドホックコマンドを実行して Ansible がどのように動作するのか学習します。 Ansible はansibleコマンドを使用してアドホックコマンドを実行します。ansibleコマンドはプレイブックを作成しなくても管理対象ホストでタスクを実行します。複数の管理対象ホストにアドホックコマンドを実行するときはとても便利なコマンドです。


インベントリの作成

インベントリの基本

ansibleコマンドを使用するには Ansible サーバー上に管理対象ホストの一覧を定義したインベントリファイルが必要です。「検証用ホストの作成」で作成した管理対象ノードのインベントリです。インベントリファイル名は hosts.yml です。

---
all:
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node1_key
    node2:
      ansible_host: 192.168.1.162
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node2_key
    node3:
      ansible_host: 192.168.1.163
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node3_key

ansibleコマンドのインベントリに関係するオプションです。

-i, --inventory, --inventory-file
 インベントリファイルを指定します。
--list-hosts インベントリ内で実行対象になる管理対象ホストを確認します。

「ホストパターン」を使用してインベントリ内で実行対象にする管理対象ホストを指定します。もっとも基本的なホストパターンは管理対象ホスト名です。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml --list-hosts
  hosts (1):
    node1
[vagrant@ansible ~]$

ホストパターンに all を指定するとインベントリ内のすべての管理対象ホストが対象になります。

[vagrant@ansible ~]$ ansible all -i hosts.yml --list-hosts
  hosts (3):
    node1
    node3
    node2
[vagrant@ansible ~]$

次のホストパターンも可能です。

[vagrant@ansible ~]$ ansible node1,node3 -i hosts.yml --list-hosts
  hosts (
      2):
    node1
    node3
[vagrant@ansible ~]$
[vagrant@ansible ~]$ ansible node* -i hosts.yml --list-hosts
  hosts (3):
    node1
    node3
    node2
[vagrant@ansible ~]$

管理対象ノードのグループ化

インベントリ内の管理対象ホストでグループを作成できます。今回は管理対象ホスト node2 と node3 で web グループを作成しました。

---
all:
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node1_key
  children:
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_user: vagrant
          ansible_ssh_private_key_file: ~/.ssh/node2_key
        node3:
          ansible_host: 192.168.1.163
          ansible_user: vagrant
          ansible_ssh_private_key_file: ~/.ssh/node3_key

これはこのようにも書けます。

---
all:
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node1_key
    node2:
      ansible_host: 192.168.1.162
      ansible_user: vagrant
      ansible_ssh_private_key_file: ~/.ssh/node2_key
    node3:
        ansible_host: 192.168.1.163
        ansible_user: vagrant
        ansible_ssh_private_key_file: ~/.ssh/node3_key
  children:
    web:
      hosts:
        node2:
        node3:

グループ名はホストパターンに使用できます。

[vagrant@ansible ~]$ ansible web -i hosts.yml --list-hosts
  hosts (2):
    node3
    node2
[vagrant@ansible ~]$

グループと管理対象ホスト名の組み合わせも可能です。

[vagrant@ansible ~]$ ansible web,node1 -i hosts.yml --list-hosts
  hosts (3):
    node3
    node2
    node1
[vagrant@ansible ~]$

インベントリ内の共通項目をまとめる

インベントリを記述するとき、共通部分をまとめることができます。今回はすべての管理対象ノードに ansible_user: vagrant が含まれているので、次のように書き直すことができます。

---
all:
  vars:
    ansible_user: vagrant
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_ssh_private_key_file: ~/.ssh/node1_key
    node2:
      ansible_host: 192.168.1.162
      ansible_ssh_private_key_file: ~/.ssh/node2_key
    node3:
        ansible_host: 192.168.1.163
        ansible_ssh_private_key_file: ~/.ssh/node3_key
  children:
    web:
      hosts:
        node2:
        node3:

インベントリのチェック

ansible-inventoryコマンドを使用して、インベントリをチェックできます。主なオプションです。

--graph グループとグループに含まれる管理対象ノードをツリー形式で表示します。
--list 管理対象ノードごとに、どの様に定義されているかをリスト形式に表示します。
--yaml --list形式と併用し、結果を YAML 形式に表示します。

--graphオプションの実行結果です。先頭に @ が付いているのがグループです。

[vagrant@ansible ~]$ ansible-inventory -i hosts.yml --graph
@all:
  |--@ungrouped:
  |  |--node1
  |--@web:
  |  |--node2
  |  |--node3
[vagrant@ansible ~]$

--listオプションの実行結果です。

[vagrant@ansible ~]$ ansible-inventory -i hosts.yml --list
{
    "_meta": {
        "hostvars": {
            "node1": {
                "ansible_host": "192.168.1.161",
                "ansible_ssh_private_key_file": "~/.ssh/node1_key",
                "ansible_user": "vagrant"
            },
            "node2": {
                "ansible_host": "192.168.1.162",
                "ansible_ssh_private_key_file": "~/.ssh/node2_key",
                "ansible_user": "vagrant"
            },
            "node3": {
                "ansible_host": "192.168.1.163",
                "ansible_ssh_private_key_file": "~/.ssh/node3_key",
                "ansible_user": "vagrant"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "web"
        ]
    },
    "ungrouped": {
        "hosts": [
            "node1"
        ]
    },
    "web": {
        "hosts": [
            "node2",
            "node3"
        ]
    }
}
[vagrant@ansible ~]$

--yamlオプションの実行結果です。

all:
  children:
    ungrouped:
      hosts:
        node1:
          ansible_host: 192.168.1.161
          ansible_ssh_private_key_file: ~/.ssh/node1_key
          ansible_user: vagrant
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
          ansible_user: vagrant
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key
          ansible_user: vagrant
[vagrant@ansible ~]$

インベントリのデフォルトグループ

インベントリは必ず 2 つのデフォルトグループを含みます。

all
すべての管理対象ホストが含まれるグループです。
ungrouped
all 以外にどのグループにも属さない管理対象ホストが属すグループです。

すべてのグループの親グループにあたるのが all グループです。明示的に定義するグループは子( children )グループになります。


Ansible の設定ファイル

Ansible は ini 形式の設定ファイルで動作をカスタマイズできます。設定ファイルは複数の場所(ディレクトリ)に書けます。 Ansible が設定ファイルを検索する順序です。

  1. 環境変数ANSIBLE_CONFIGに設定されているパス(ファイル)
  2. カレントディレクトリのansible.cfgファイル
  3. ホームディレクトリの.ansible.cfgファイル
  4. /etc/ansible/ansible.cfgファイル

Ansible は上記順序で設定ファイルを検索し、最初に見つけた設定ファイルを使用します。「検証用ホストの作成」で作成した Ansible サーバ-の設定ファイルは/etc/ansible/ansible.cfgファイルです。ほかのファイルは存在しません。


管理対象ホストへ ping モジュールを実行

Ansible のpingモジュールを使用して管理対象ホストへ ping を実行します。pingモジュールはネットワークで疎通確認に使用する ping コマンドと動作が異なります。管理対象ホストへ ping モジュールの実行が成功した場合、 Ansible がその管理対象ホスト上でコマンドを正しく実行できることを確認できたことになります。

ちなみに

モジュールは特定の処理をするためのプログラムです。ansibleコマンドは-aオプションでモジュールに引数を渡します。

ansibleコマンドは-mオプションで実行するモジュールを指定します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m ping
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
[vagrant@ansible ~]$

モジュールのリストとヘルプを表示

Ansible で用意されているモジュールのリストを表示します。

[vagrant@ansible ~]$ ansible-doc -l

ちなみに

  • 表示の終了→Qキー
  • 表示内容のスクロール→PgUpキー /PgDnキー

特定のモジュールを検索するときはgrepコマンドで絞り込みます。

[vagrant@ansible ~]$ ansible-doc -l | grep -i ping
win_ping                                                      A windows version of the classic ping module
postgresql_ping                                               Check remote PostgreSQL server availability
lambda_event                                                  Creates, updates or deletes AWS Lambda function event mappings
net_ping                                                      Tests reachability using ping from a network device
ping                                                          Try to connect to host, verify a usable python and return `pong' on success
fortios_system_switch_interface                               Configure software switch interfaces by grouping physical and WiFi interfaces in Fortinet'...
ibm_sa_vol_map                                                Handles volume mapping on IBM Spectrum Accelerate Family storage systems
selogin                                                       Manages linux user to SELinux user mapping
pingdom                                                       Pause/unpause Pingdom alerts
fortios_firewall_shaping_profile                              Configure shaping profiles in Fortinet's FortiOS and FortiGate
nxos_igmp_snooping                                            Manages IGMP snooping global configuration
sefcontext                                                    Manages SELinux file context mapping definitions
fortios_system_geoip_override                                 Configure geographical location mapping for IP address(es) to override mappings from Forti...
fortios_firewall_shaping_policy                               Configure shaping policies in Fortinet's FortiOS and FortiGate
pn_igmp_snooping                                              CLI command to modify igmp-snooping
nxos_ping                                                     Tests reachability using ping from Nexus switch
junos_ping                                                    Tests reachability using ping from devices running Juniper JUNOS
fortios_switch_controller_igmp_snooping                       Configure FortiSwitch IGMP snooping global settings in Fortinet's FortiOS and FortiGate
icx_ping                                                      Tests reachability using ping from Ruckus ICX 7000 series switches
ios_ping                                                      Tests reachability using ping from Cisco IOS network devices
vyos_ping                                                     Tests reachability using ping from VyOS network devices
netapp_e_lun_mapping                                          NetApp E-Series create, delete, or modify lun mappings
[vagrant@ansible ~]$

特定のモジュールのヘルプや使用例を確認するときは次のようにします。

[vagrant@ansible ~]$ ansible-doc group
> GROUP    (/usr/lib/python2.7/site-packages/ansible/modules/system/group.py)

        Manage presence of groups on a host. For Windows targets, use the [win_group] module instead.

  * This module is maintained by The Ansible Core Team
OPTIONS (= is mandatory):

- gid
        Optional `GID' to set for the group.
        [Default: (null)]
        type: int

- local
        Forces the use of "local" command alternatives on platforms that implement it.
        This is useful in environments that use centralized authentication when you want to manipulate the local groups.
        (e.g. it uses `lgroupadd' instead of `groupadd').
        This requires that these commands exist on the targeted host, otherwise it will be a fatal error.
        [Default: False]
        type: bool
        version_added: 2.6

= name
        Name of the group to manage.

        type: str

- non_unique
        This option allows to change the group ID to a non-unique value. Requires `gid'.
        Not supported on macOS or BusyBox distributions.
        [Default: False]
        type: bool
        version_added: 2.8

- state
        Whether the group should be present or not on the remote host.
        (Choices: absent, present)[Default: present]
        type: str

- system
        If `yes', indicates that the group created is a system group.
        [Default: False]
        type: bool


SEE ALSO:
      * Module user
           The official documentation on the user module.
           https://docs.ansible.com/ansible/2.9/modules/user_module.html
      * Module win_group
           The official documentation on the win_group module.
           https://docs.ansible.com/ansible/2.9/modules/win_group_module.html


REQUIREMENTS:  groupadd, groupdel, groupmod

AUTHOR: Stephen Fromm (@sfromm)
        METADATA:
          status:
          - stableinterface
          supported_by: core


EXAMPLES:

- name: Ensure group "somegroup" exists
  group:
    name: somegroup
    state: present


[vagrant@ansible ~]$

ちなみに

必須オプションは OPTIONS の先頭が = になっています。


コマンドモジュール

commandモジュールを使用して、管理対象ホスト上で Linux コマンドを実行します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m command -a 'id'
node1 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[vagrant@ansible ~]$

commandモジュールは実行するコマンドを引数として受け取り、ホストパターンで指定した管理対象ホスト上で実行するモジュールです。ホストパターンに all を指定すると、すべての管理対象ホスト上でコマンドを実行します。

[vagrant@ansible ~]$ ansible all -i hosts.yml -m command -a 'id'
node2 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
node3 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
node1 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[vagrant@ansible ~]$

-oオプションを使用すると、実行結果を 1 行で表示します。

[vagrant@ansible ~]$ ansible all -i hosts.yml -m command -a 'id' -o
node3 | CHANGED | rc=0 | (stdout) uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
node2 | CHANGED | rc=0 | (stdout) uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
node1 | CHANGED | rc=0 | (stdout) uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[vagrant@ansible ~]$

オプション付きの Linux コマンドも実行できます。

[vagrant@ansible ~]$ ansible all -i hosts.yml -m command -a 'uname -r'
node3 | CHANGED | rc=0 >>
3.10.0-1062.18.1.el7.x86_64
node1 | CHANGED | rc=0 >>
3.10.0-1062.18.1.el7.x86_64
node2 | CHANGED | rc=0 >>
3.10.0-1062.18.1.el7.x86_64
[vagrant@ansible ~]$

ご用心

commandモジュールでパイプやリダイレクトなどは使用できません。パイプやリダイレクトなどを使用する場合はshellモジュールを使用します。


権限昇格

copyモジュールで管理対象ホスト node1 の/etc/motdファイルの内容を変更します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m copy -a 'content="Managed by Ansible\n" dest=/etc/motd'
node1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "msg": "Destination /etc not writable"
}
[vagrant@ansible ~]$

失敗しました。出力に "Destination /etc not writable" とあるので、/etc/motdファイルに書き込みできなかったようです。 node1 の/etc/motdファイルの状態を確認します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m command -a 'ls -l /etc/motd'
node1 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 Jun  7  2013 /etc/motd
[vagrant@ansible ~]$

インベントリからわかるように Ansible サーバーから node1 にログインするときのユーザーは vagrant です。しかし、/etc/motdファイルを書き換えることができるのは root だけです。このようなとき、Linux コマンドを実行するときは sudo を指定して権限昇格します。 Ansible では-bオプションを指定して、モジュールの実行時に権限昇格します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m copy -a 'content="Managed by Ansible\n" dest=/etc/motd' -b
node1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "md5sum": "65a4290ee5559756ad04e558b0e0c4e3",
    "mode": "0644",
    "owner": "root",
    "secontext": "system_u:object_r:etc_t:s0",
    "size": 19,
    "src": "/home/vagrant/.ansible/tmp/ansible-tmp-1587289994.14-173455693341419/source",
    "state": "file",
    "uid": 0
}
[vagrant@ansible ~]$

今度は実行が成功しました。動作確認のため node1 に接続し、/etc/motdファイルの内容を確認します。

[vagrant@ansible ~]$ ssh 192.168.1.161 -l vagrant -i ~/.ssh/node1_key
Last login: Sun Apr 19 18:54:13 2020 from 192.168.1.151
Managed by Ansible
[vagrant@node1 ~]$ cat /etc/motd
Managed by Ansible
[vagrant@node1 ~]$ logout
Connection to 192.168.1.161 closed.
[vagrant@ansible ~]$

ログイン時に/etc/motdファイルに設定した文字列が表示されているので、正しく変更されたことがわかります。/etc/motdファイルの内容も変更後の内容になっています。


べき等性

権限昇格」で実行した/etc/motdファイルを変更するアドホックコマンドをもう一度実行します。

[vagrant@ansible ~]$ ansible node1 -i hosts.yml -m copy -a 'content="Managed by Ansible\n" dest=/etc/motd' -b
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "checksum": "4458b979ede3c332f8f2128385df4ba305e58c27",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "path": "/etc/motd",
    "secontext": "system_u:object_r:etc_t:s0",
    "size": 19,
    "state": "file",
    "uid": 0
}
[vagrant@ansible ~]$

実行は成功しました。出力メッセージ内に "changed": false と表示されています。これは「アドホックコマンド(タスク)の実行は成功したが、管理対象ホストの状態は変更されなかった」ことを意味します。具体的には、Ansible が/etc/motdファイルの内容が変更したい(変更後の)内容と同じ状態だったので、ファイルの内容を変更しなかったということです。このように Ansible は管理対象ホストの状態をチェックし、変更が必要なら変更し、変更が不要なら変更しません。その結果、何度アドホックコマンドを実行しても、実行後の管理対象ホストの状態は常に同じになります。このように、何度コマンドを実行しても、実行後が常に同じ状態になることを「『べき等性(冪等性)』を保っている」と言います。これは構成管理ツールの大きな特徴であり、後述のプレイブックを使用した場合も当てはまります。


アドホックコマンドの演習

※ すべて管理対象ホスト node1 に対して実施してください。

  1. ソフトウェアパッケージを管理する yum を使用できるモジュールを見つけてください。

ヒント

ansible-docコマンドでモジュールの一覧を表示し、その中から grep コマンドで絞り込みます。

  1. 見つけたモジュールの EXAMPLES: を参考に、管理対象ホスト node1 に Apache の最新バージョンをインストールしてください。

ヒント

  • Apache = httpd
  • 最新バージョン = latest
  • パッケージ名とインストールするバージョンは-aオプションで指定します。
  • Linux の yum コマンドでパッケージをインストールするときは sudo の指定が必要です。
  1. べき等性を確認するため、もう一度 Apache の最新バージョンをインストールしてください。

注釈

「べき等性」とはどういうことかを思い出して Apache の最新版のインストールの 1 回目と 2 回目の実行結果を比較してください。

  1. 管理対象ホスト node1 に ssh 接続し、 yum コマンドを実行して Apache がインストールされていることを確認してください。確認後は node1 から logout してください。

ヒント

yum コマンドでインストール済みパッケージを確認する方法
yum list installed パッケージ名

解答

[vagrant@ansible ansible-files]$ ansible-doc -l | grep -i yum
yum                                                           Manages packages with the `yum' package manager                                           
yum_repository                                                Add or remove YUM repositories                                                            
[vagrant@ansible ansible-files]$ 
[vagrant@ansible ansible-files]$ ansible-doc yum
> YUM    (/usr/lib/python2.7/site-packages/ansible/modules/packaging/os/yum.py)

        Installs, upgrade, downgrades, removes, and lists packages and groups with the `yum' package manager. This module
        only works on Python 2. If you require Python 3 support see the [dnf] module.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

- allow_downgrade
        Specify if the named package and version is allowed to downgrade a maybe already installed higher version of that
        package. Note that setting allow_downgrade=True can make this module behave in a non-idempotent way. The task could
        end up with a set of packages that does not match the complete list of specified packages to install (because
        dependencies between the downgraded package and others can cause changes to the packages which were in the earlier
        transaction).
        [Default: no]
        type: bool
        version_added: 2.4

- autoremove
        If `yes', removes all "leaf" packages from the system that were originally installed as dependencies of user-
        installed packages but which are no longer required by any such package. Should be used alone or when state is
        `absent'
        NOTE: This feature requires yum >= 3.4.3 (RHEL/CentOS 7+)
        [Default: no]
        type: bool
        version_added: 2.7

- bugfix
        If set to `yes', and `state=latest' then only installs updates that have been marked bugfix related.
        [Default: no]
        version_added: 2.6

- conf_file
        The remote yum configuration file to use for the transaction.
        [Default: (null)]
        version_added: 0.6

- disable_excludes
        Disable the excludes defined in YUM config files.
        If set to `all', disables all excludes.
        If set to `main', disable excludes defined in [main] in yum.conf.
        If set to `repoid', disable excludes defined for given repo id.
        [Default: (null)]
        version_added: 2.7

- disable_gpg_check
        Whether to disable the GPG checking of signatures of packages being installed. Has an effect only if state is
        `present' or `latest'.
        [Default: no]
        type: bool
        version_added: 1.2

- disable_plugin
        `Plugin' name to disable for the install/update operation. The disabled plugins will not persist beyond the
        transaction.
        [Default: (null)]
        version_added: 2.5

- disablerepo
        `Repoid' of repositories to disable for the install/update operation. These repos will not persist beyond the
        transaction. When specifying multiple repos, separate them with a `","'.
        As of Ansible 2.7, this can alternatively be a list instead of `","' separated string
        [Default: (null)]
        version_added: 0.9

- download_dir
        Specifies an alternate directory to store packages.
        Has an effect only if `download_only' is specified.
        [Default: (null)]
        type: str
        version_added: 2.8

- download_only
        Only download the packages, do not install them.
        [Default: no]
        type: bool
        version_added: 2.7

- enable_plugin
        `Plugin' name to enable for the install/update operation. The enabled plugin will not persist beyond the transaction.
        [Default: (null)]
        version_added: 2.5

- enablerepo
        `Repoid' of repositories to enable for the install/update operation. These repos will not persist beyond the
        transaction. When specifying multiple repos, separate them with a `","'.
        As of Ansible 2.7, this can alternatively be a list instead of `","' separated string
        [Default: (null)]
        version_added: 0.9

- exclude
        Package name(s) to exclude when state=present, or latest
        [Default: (null)]
        version_added: 2.0

- install_weak_deps
        Will also install all packages linked by a weak dependency relation.
        NOTE: This feature requires yum >= 4 (RHEL/CentOS 8+)
        [Default: yes]
        type: bool
        version_added: 2.8

- installroot
        Specifies an alternative installroot, relative to which all packages will be installed.
        [Default: /]
        version_added: 2.3

- list
        Package name to run the equivalent of yum list --show-duplicates <package> against. In addition to listing packages,
        use can also list the following: `installed', `updates', `available' and `repos'.
        This parameter is mutually exclusive with `name'.
        [Default: (null)]

- lock_timeout
        Amount of time to wait for the yum lockfile to be freed.
        [Default: 30]
        type: int
        version_added: 2.8

- name
        A package name or package specifier with version, like `name-1.0'.
        If a previous version is specified, the task also needs to turn `allow_downgrade' on. See the `allow_downgrade'
        documentation for caveats with downgrading packages.
        When using state=latest, this can be `'*'' which means run `yum -y update'.
        You can also pass a url or a local path to a rpm file (using state=present). To operate on several packages this can
        accept a comma separated string of packages or (as of 2.0) a list of packages.
        (Aliases: pkg)[Default: (null)]

- releasever
        Specifies an alternative release from which all packages will be installed.
        [Default: (null)]
        version_added: 2.7

- security
        If set to `yes', and `state=latest' then only installs updates that have been marked security related.
        [Default: no]
        type: bool
        version_added: 2.4

- skip_broken
        Skip packages with broken dependencies(devsolve) and are causing problems.
        [Default: no]
        type: bool
        version_added: 2.3

- state
        Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package.
        `present' and `installed' will simply ensure that a desired package is installed.
        `latest' will update the specified package if it's not of the latest available version.
        `absent' and `removed' will remove the specified package.
        Default is `None', however in effect the default action is `present' unless the `autoremove' option is enabled for
        this module, then `absent' is inferred.
        (Choices: absent, installed, latest, present, removed)[Default: (null)]

- update_cache
        Force yum to check if cache is out of date and redownload if needed. Has an effect only if state is `present' or
        `latest'.
        (Aliases: expire-cache)[Default: no]
        type: bool
        version_added: 1.9

- update_only
        When using latest, only update installed packages. Do not install packages.
        Has an effect only if state is `latest'
        [Default: no]
        type: bool
        version_added: 2.5

- use_backend
        This module supports `yum' (as it always has), this is known as `yum3'/`YUM3'/`yum-deprecated' by upstream yum
        developers. As of Ansible 2.7+, this module also supports `YUM4', which is the "new yum" and it has an `dnf' backend.
        By default, this module will select the backend based on the `ansible_pkg_mgr' fact.
        (Choices: auto, yum, yum4, dnf)[Default: auto]
        version_added: 2.7

- validate_certs
        This only applies if using a https url as the source of the rpm. e.g. for localinstall. If set to `no', the SSL
        certificates will not be validated.
        This should only set to `no' used on personally controlled sites using self-signed certificates as it avoids
        verifying the source site.
        Prior to 2.1 the code worked as if this was set to `yes'.
        [Default: yes]
        type: bool
        version_added: 2.1


NOTES:
      * When used with a `loop:` each package will be processed individually, it is much more efficient to pass the
        list directly to the `name` option.
      * In versions prior to 1.9.2 this module installed and removed each package given to the yum module separately.
        This caused problems when packages specified by filename or url had to be installed or removed together. In
        1.9.2 this was fixed so that packages are installed in one yum transaction. However, if one of the packages
        adds a new yum repository that the other packages come from (such as epel-release) then that package needs to
        be installed in a separate task. This mimics yum's command line behaviour.
      * Yum itself has two types of groups.  "Package groups" are specified in the rpm itself while "environment
        groups" are specified in a separate file (usually by the distribution).  Unfortunately, this division becomes
        apparent to ansible users because ansible needs to operate on the group of packages in a single transaction and
        yum requires groups to be specified in different ways when used in that way.  Package groups are specified as
        "@development-tools" and environment groups are "@^gnome-desktop-environment". Use the "yum group list hidden
        ids" command to see which category of group the group you want to install falls into.
      * The yum module does not support clearing yum cache in an idempotent way, so it was decided not to implement it,
        the only method is to use command and call the yum command directly, namely "command: yum clean all"
        https://github.com/ansible/ansible/pull/31450#issuecomment-352889579


REQUIREMENTS:  yum

AUTHOR: Ansible Core Team, Seth Vidal (@skvidal), Eduard Snesarev (@verm666), Berend De Schouwer (@berenddeschouwer), Abhijeet Kasurde (@Akasurde), Adam Mill
        METADATA:
          status:
          - stableinterface
          supported_by: core
        

EXAMPLES:

- name: install the latest version of Apache
  yum:
    name: httpd
    state: latest

- name: ensure a list of packages installed
  yum:
    name: "{{ packages }}"
  vars:
    packages:
    - httpd
    - httpd-tools

- name: remove the Apache package
  yum:
    name: httpd
    state: absent

- name: install the latest version of Apache from the testing repo
  yum:
    name: httpd
    enablerepo: testing
    state: present

- name: install one specific version of Apache
  yum:
    name: httpd-2.2.29-1.4.amzn1
    state: present

- name: upgrade all packages
  yum:
    name: '*'
    state: latest

- name: upgrade all packages, excluding kernel & foo related packages
  yum:
    name: '*'
    state: latest
    exclude: kernel*,foo*

- name: install the nginx rpm from a remote repo
  yum:
    name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
    state: present

- name: install nginx rpm from a local file
  yum:
    name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
    state: present

- name: install the 'Development tools' package group
  yum:
    name: "@Development tools"
    state: present
[vagrant@ansible ansible-files]$ 
[vagrant@ansible ansible-files]$ ansible node1 -i hosts.yml -m yum -a 'name=httpd state=latest' -b
node1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "changes": {
        "installed": [
            "httpd"
        ], 
        "updated": []
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: ftp.yz.yamagata-u.ac.jp\n * extras: ftp.yz.yamagata-u.ac.jp\n * updates: ftp.yz.yamagata-u.ac.jp\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-93.el7.centos will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-93.el7.centos for package: httpd-2.4.6-93.el7.centos.x86_64\n--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-93.el7.centos.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-93.el7.centos.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-93.el7.centos.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-5.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-93.el7.centos will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package             Arch          Version                    Repository   Size\n================================================================================\nInstalling:\n httpd               x86_64        2.4.6-93.el7.centos        base        2.7 M\nInstalling for dependencies:\n apr                 x86_64        1.4.8-5.el7                base        103 k\n apr-util            x86_64        1.5.2-6.el7                base         92 k\n centos-logos        noarch        70.0.6-3.el7.centos        base         21 M\n httpd-tools         x86_64        2.4.6-93.el7.centos        base         92 k\n mailcap             noarch        2.1.41-2.el7               base         31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+5 Dependent packages)\n\nTotal download size: 24 M\nInstalled size: 32 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              9.5 MB/s |  24 MB  00:02     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : apr-1.4.8-5.el7.x86_64                                       1/6 \n  Installing : apr-util-1.5.2-6.el7.x86_64                                  2/6 \n  Installing : httpd-tools-2.4.6-93.el7.centos.x86_64                       3/6 \n  Installing : centos-logos-70.0.6-3.el7.centos.noarch                      4/6 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  5/6 \n  Installing : httpd-2.4.6-93.el7.centos.x86_64                             6/6 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  1/6 \n  Verifying  : apr-util-1.5.2-6.el7.x86_64                                  2/6 \n  Verifying  : httpd-2.4.6-93.el7.centos.x86_64                             3/6 \n  Verifying  : apr-1.4.8-5.el7.x86_64                                       4/6 \n  Verifying  : httpd-tools-2.4.6-93.el7.centos.x86_64                       5/6 \n  Verifying  : centos-logos-70.0.6-3.el7.centos.noarch                      6/6 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-93.el7.centos                                            \n\nDependency Installed:\n  apr.x86_64 0:1.4.8-5.el7                                                      \n  apr-util.x86_64 0:1.5.2-6.el7                                                 \n  centos-logos.noarch 0:70.0.6-3.el7.centos                                     \n  httpd-tools.x86_64 0:2.4.6-93.el7.centos                                      \n  mailcap.noarch 0:2.1.41-2.el7                                                 \n\nComplete!\n"
    ]
}
[vagrant@ansible ansible-files]$ 
[vagrant@ansible ansible-files]$ ansible node1 -i hosts.yml -m yum -a 'name=httpd state=latest' -b
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "changes": {
        "installed": [], 
        "updated": []
    }, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "All packages providing httpd are up to date", 
        ""
    ]
}
[vagrant@ansible ansible-files]$ 
[vagrant@ansible ansible-files]$ ssh 192.168.1.161 -l vagrant -i ~/.ssh/node1_key 
Last login: Sat May  9 17:16:05 2020 from 192.168.1.151
[vagrant@node1 ~]$ yum list installed httpd
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: mirrors.cat.net
 * extras: mirrors.cat.net
 * updates: mirrors.cat.net
Installed Packages
httpd.x86_64                                                            2.4.6-93.el7.centos                                                             @base
[vagrant@node1 ~]$ logout
Connection to 192.168.1.161 closed.
[vagrant@ansible ansible-files]$