修正プログラムを適用するための Ansible Playbook を出力する


修正プログラムを適用するための Ansible Playbook を出力することができます。

前提条件

この機能を使用するためには、以下の条件を満たしている必要があります。

制限事項

Playbook による更新が可能なソフトウェアは次のとおりです。

  • エージェントが検出した Linux ディストリビューションが実装している rpm/deb バイナリパッケージ
  • エージェントが検出した Windows 未適用パッチ

反対に、Playbook による更新の対象とならないソフトウェアは以下のとおりです。

  • エージェントが検出したオープンソースソフトウェア (Apache Struts, Apache Tomcat, PHP 等)
  • 手動登録したソフトウェア
  • EPEL など追加のリポジトリからインストールした rpm/deb バイナリパッケージ
  • ソースからコンパイルしてインストールしたソフトウェア

Playbook を出力する (Amazon Linux/Red Hat Enterprise Linux/CentOS ホスト)

  • 全ての脆弱性を解消したい場合

    1. Playbook を出力したいホストの「ホスト詳細画面」を開きます。 ホスト詳細画面
    2. アクションボタンの「Playbook出力」ボタンをクリックします。 Playbook出力
    3. 「ダウンロード」ボタンをクリックします。
      Playbookダウンロード
    4. Playbook「vmplaybook-(ホスト名)-yml-(日時).yml」がダウンロードされます。
      - name: update rpm packages
        hosts: host2.example.com
       
        tasks:
          - name: yum update
            yum:
              name:
                - bash
                - bind-libs-lite
                - bind-license
                  (中略)
                - systemd
                - systemd-libs
                - systemd-sysv
                - unzip
              state: latest
            register: r_yum_update
            become: true
       
          - name: output yum update
            debug:
              var: r_yum_update
    5. Playbook の実行方法はこちらをご参照ください。
  • 特定の脆弱性を解消したい場合

    1. Playbook を出力したいホストの「ホスト詳細画面」を開きます。
    2. 解消したい脆弱性をチェックボックスで選択します。
    3. アクションボタンの「Playbook出力」ボタンをクリックします。
    4. 「ダウンロード」ボタンをクリックします。
    5. Playbook「vmplaybook-(ホスト名)-yml-(日時).yml」がダウンロードされます。
      - name: update rpm packages
        hosts: host2.example.com
       
        tasks:
          - name: yum update
            yum:
              name:
                - bind-libs-lite
                - bind-license
              state: latest
            register: r_yum_update
            become: true
       
          - name: output yum update
            debug:
              var: r_yum_update
    6. Playbook の実行方法はこちらをご参照ください。

Playbook を出力する (Ubuntu ホスト)

  • 全ての脆弱性を解消したい場合

    1. Playbook を出力したいホストの「ホスト詳細画面」を開きます。 ホスト詳細画面
    2. アクションボタンの「Playbook出力」ボタンをクリックします。 Playbook出力
    3. 「ダウンロード」ボタンをクリックします。
      Playbookダウンロード
    4. Playbook「vmplaybook-(ホスト名)-yml-(日時).yml」がダウンロードされます。
      - name: update deb packages
        hosts: host1.example.com
        tasks:
          - name: apt upgrade
            apt:
              name:
                - apport
                - apt
                  (中略)
                - vim
                - vim-common
                - vim-runtime
              state: latest
              update_cache: yes
              dpkg_options: 'force-confold'
            register: r_apt_upgrade
            become: true
          - name: output apt upgrade
            debug:
              var: r_apt_upgrade
    5. Playbook の実行方法はこちらをご参照ください。
  • 特定の脆弱性を解消したい場合

    1. Playbook を出力したいホストの「ホスト詳細画面」を開きます。
    2. 解消したい脆弱性をチェックボックスで選択します。
    3. アクションボタンの「Playbook出力」ボタンをクリックします。
    4. 「ダウンロード」ボタンをクリックします。
    5. Playbook「vmplaybook-(ホスト名)-yml-(日時).yml」がダウンロードされます。
      - name: update deb packages
        hosts: host1.example.com
        tasks:
          - name: apt upgrade
            apt:
              name:
                - file
                - libmagic1
              state: latest
              update_cache: yes
              dpkg_options: 'force-confold'
            register: r_apt_upgrade
            become: true
          - name: output apt upgrade
            debug:
              var: r_apt_upgrade
    6. Playbook の実行方法はこちらをご参照ください。

Playbook を出力する (Windows ホスト)

  1. Playbook を出力したいホストの「ホスト詳細画面」を開きます。
  2. アクションボタンの「Playbook出力」ボタンをクリックします。
  3. 「ダウンロード」ボタンをクリックします。
  4. Playbook「vmplaybook-(ホスト名)-yml-(日時).yml」がダウンロードされます。
    - name: Windows Updates
      hosts: WINSERVER2016T.example.com
     
      tasks:
        - name: windows updates
          win_updates:
            category_names:
              - SecurityUpdates
              - CriticalUpdates
              - UpdateRollups
              # - DefinitionUpdates
              # - DeveloperKits
              # - FeaturePacks
              # - ServicePacks
          register: r_win_update
     
        - name: output win update
          debug:
            var: r_win_update
  5. Playbook の実行方法はこちらをご参照ください。

Playbook を実行する

  1. Ansible コントロールノードにログインします。

  2. ダウンロードした Playbook を Ansible コントロールノード上にコピーします。

  3. インベントリファイルを作成し、ホストを追加します。
    (既にインベントリファイルにホストが記載されている場合は、次の手順にお進みください。)

    ここでは例として、linux_servers グループに host1.example.com (Ubuntu 18 LTS) と host2.example.com (CentOS 7 minimal) が、windows_servers グループに WINSERVER2016T.example.com (Windows Server 2016) がそれぞれ所属するものとしています。

    インベントリファイルの内容は、ご利用の環境に応じたものに適宜書き換えてください。

    $ vi hosts
    [linux_servers]
    host1.example.com          # Ubuntu サーバ
    host2.example.com          # CentOS サーバ
     
    [windows_servers]
    WINSERVER2016T.example.com # Windows サーバ
  4. Playbook を実行します。
    $ ansible-playbook -i hosts vmplaybook-(ホスト名)-yml-(日時).yml

    実行結果 - 例1 host1.example.com (Ubuntu 18 LTS)

    $ ansible-playbook -i hosts vmplaybook-host1-yml-yyyymmdd.yml 
    PLAY [update deb packages] *****************************************
    TASK [Gathering Facts] *********************************************
    ok: [host1.example.com]
    TASK [apt upgrade] *************************************************
    changed: [host1.example.com]
    TASK [output apt upgrade] ******************************************
    ok: [host1.example.com] => {
        "r_apt_upgrade": {
            "cache_update_time": 1593073428, 
            "cache_updated": true, 
            "changed": true, 
            "diff": {}, 
            "failed": false, 
            "stderr": "", 
            "stderr_lines": [],
            "stdout": "Reading package lists...(中略)"
            "stdout_lines": [
                "Reading package lists...", 
                "Building dependency tree...", 
                "Reading state information...", 
                "The following additional packages will be installed:", 
    	           (中略)
                "Processing triggers for ureadahead (0.100.0-21) ...", 
                "Processing triggers for libc-bin (2.27-3ubuntu1) ..."
            ]
        }
    }
    PLAY RECAP *********************************************************
    host1.example.com          : ok=3    changed=1    unreachable=0 ... 

    実行結果 - 例2 host2.example.com (CentOS 7 minimal)

    $ ansible-playbook -i hosts vmplaybook-host2-yml-yyyymmdd.yml 
    PLAY [update rpm packages] *****************************************
    TASK [Gathering Facts] *********************************************
    ok: [host2.example.com]
    TASK [yum update] **************************************************
    changed: [host2.example.com]
    TASK [output yum update] *******************************************
    ok: [host2.example.com] => {
        "r_yum_update": {
            "changed": true,
            "changes": {
                "installed": [],
                "updated": [
                    [
                        "libcurl",
                        "7.29.0-57.el7.x86_64 from base"
                    ],
                    [
                        "curl",
                        "7.29.0-57.el7.x86_64 from base"
                    ]
                ]
            },
            "failed": false,
            "msg": "",
            "obsoletes": {
                "iwl7265-firmware": {
                    "dist": "noarch",
                    "repo": "@base",
                    "version": "22.0.7.0-72.el7"
                }
            },
            "rc": 0,
            "results": [
                "All packages providing file are up to date",
                "All packages providing file-libs are up to date",
                "Loaded plugins: fastestmirror\nLoading mirror speeds fr
            ]
        }
    }
     
    PLAY RECAP *********************************************************
    host2.example.com          : ok=3    changed=1    unreachable=0 ... 

    実行結果 - 例3 WINSERVER2016T.example.com (Windows Server 2016)

    $ ansible-playbook -i hosts vmplaybook-WINSERVER2016T.yml
    PLAY [Windows Updates] *********************************************
    TASK [Gathering Facts] *********************************************
    ok: [WINSERVER2016T.example.com]
    TASK [windows updates] *********************************************
    changed: [WINSERVER2016T.example.com]
    TASK [output win update] *******************************************
    ok: [WINSERVER2016T.example.com] => {
       "r_win_update": {
           "changed": true,
           "failed": false,
           "failed_update_count": 0,
           "filtered_updates": {
               "c8078ab8-da79-4e71-8115-5155ae9f96b6": {
                   "categories": [
                       "Updates",
                       "Windows Server 2016"
                   ],
                   "filtered_reason": "category_names",
                   "id": "c8078ab8-da79-4e71-8115-5155ae9f96b6",
                   "installed": false,
                   "kb": [
                       "4494175"
                   ],
                   "title": "2020-01 x64 ベース システム用 Windows Server 2016 更新プログラム (KB4494175)"
               }
           },
           "found_update_count": 1,
           "installed_update_count": 1,
           "reboot_required": true,
           "updates": {
               "c51c3c33-556f-496c-8d18-3dd0359df167": {
                   "categories": [
                       "Security Updates",
                       "Windows Server 2016"
                   ],
                   "id": "c51c3c33-556f-496c-8d18-3dd0359df167",
                   "installed": true,
                   "kb": [
                       "4561616"
                   ],
                   "title": "2020-06 x64 ベース システム用 Windows Server 2016 の累積更新プログラム (KB4561616)"
               }
           }
       }
    PLAY RECAP *********************************************************
    WINSERVER2016T.example.com          : ok=3    changed=1    unreachable=0 ... 

トラブルシューティングとよくある質問

ERROR! couldn't resolve module/action 'win_updates'. が表示され、処理に失敗する (Windows ホスト)

Ansible 2.10 以降において ansible-base パッケージ (2.9 相当の追加モジュール無し) を使用している場合に生じます。

Playbook 実行失敗例

ERROR! couldn't resolve module/action 'win_updates'.
This often indicates a misspelling, missing collection, or incorrect module path.
 
The error appears to be in 'path/to/playbook.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
 
The offending line appears to be:
 
  tasks:
    - name: windows updates
      ^ here
 

以下の手順で ansible.windows コレクション をインストールしてください。

  1. Ansible コントロールノードにログインしてください。

  2. 次のコマンドを実行し、ansible.windows コレクションをインストールしてください。

    $ ansible-galaxy collection install ansible.windows

failed: E: Held packages were changed ... が出力され、処理に失敗する (Ubuntu ホスト)

ホールド (更新されないように指定) されているパッケージの更新を試行した場合に発生します。

確認のため、以下の手順を実行してください。

  1. パッケージ更新対象ホストにログインしてください。

  2. 次のコマンドを実行し、ホールドされているパッケージの一覧を表示してください。

    $ sudo apt-mark showhold

    例として、systemd パッケージがホールドされている場合は、次のように表示されます。

    $ sudo apt-mark showhold
    systemd
  3. 次に Playbook での更新対象パッケージを確認します。

    Ansible コントロールノードにログインし、実行した Playbook をエディタで開いてください。

    $ vi vmplaybook-(ホスト名)-yml-(日時).yml
    - name: update deb packages
      hosts: host1.example.com
      tasks:
        - name: apt upgrade
          apt:
            name:
              - file
              - libmagic1
              - systemd
            state: latest
            update_cache: yes
            dpkg_options: 'force-confold'
          register: r_apt_upgrade
          become: true
        - name: output apt upgrade
          debug:
            var: r_apt_upgrade

    この例では、systemd が更新対象パッケージに含まれていることがわかります。

この状態の解消には次の二つの方法があります。

  • パッケージ更新対象ホスト上で当該パッケージのホールドを解除する
  • Playbook の dpkg_options に allow-change-held-packages を追加し、強制的にパッケージを更新する。(非推奨)

まずひとつめの方法は次の手順となります。

  1. パッケージ更新対象ホストにログインしてください。

  2. 次のコマンドでパッケージのホールドを解除します。なお「(ホールドされたパッケージ)」は空白区切りで複数指定することができます。

    $ sudo apt-mark unhold (ホールドされたパッケージ)

    例として systemd パッケージをアンホールドする場合は次のようにします。

    $ sudo apt-mark unhold systemd
    systemd
  3. ホールドが解除されたかどうかを確認します。

    $ sudo apt-mark showhold

同様の操作は Ansible でも可能です。

  1. Ansilbe コントロールノードにログインしてください。

  2. 当該ホストのホスト変数やグループ変数にホールドの対象となるパッケージを packages_to_hold 変数に列挙します。

    $ vi host1.yml
    ---
    packages_to_hold:
      - systemd
      - linux-generic
      - linux-headers-generic
      - linux-image-generic
     
  3. パッケージのホールド解除には shell モジュールを使用します。先程列挙したリスト形式の packages_to_hold 変数の内容を、join を使用して連結し、 apt-mark unhold コマンドの引数として渡します。

    $ vi unhold_packages.yml
    ---
    - name: hold packages
      shell: "apt-mark unhold {{ packages_to_hold | join(' ') }}"
      become: true
      changed_when: false
     
  4. 再ホールドも同様に shell モジュールを使用します。

    $ vi hold_packages.yml
    ---
    - name: hold packages
      shell: "apt-mark hold {{ packages_to_hold | join(' ') }}"
      become: true
      changed_when: false
     

次は、dpkg_options に allow-change-held-packages を追加する方法です。

  1. Ansilbe コントロールノードにログインしてください。

  2. ダウンロードした Playbook をエディタで開いてください。

    $ vi vmplaybook-(ホスト名)-yml-(日時).yml
    - name: update deb packages
      hosts: host1.example.com
      tasks:
        - name: apt upgrade
          apt:
            name:
              - file
              - libmagic1
            state: latest
            update_cache: yes
            dpkg_options: 'force-confold'
          register: r_apt_upgrade
          become: true
        - name: output apt upgrade
          debug:
            var: r_apt_upgrade
  3. dpkg_options に allow-change-held-packages オプションを追加してください。

    - dpkg_options: 'force-confold'
    + dpkg_options: 'force-confold,allow-change-held-packages'
  4. その後、Playbook を実行してください。

    ただしこの方法は、ホールドされているパッケージも強制的に更新するため、システムに破壊的な変更を加える可能性があり、使用には注意が必要です。