0.はじめに
Windows2012ServerR2へAnsibleからMSUファイルを利用してKBをインストールするサンプルのAnsible playbookです。
Chefでも似たようなことはできると思います。
本投稿は前回の投稿のアップデート版です。
patchディレクトリ配下にあるMSUファイルをlsコマンドで動的に取得し、MSUファイル分ループしてインストールする形へアップデートしたもの(blockのloopをwith_itmes * include , jinja2 filter regex_replace をなどを駆使)
なお、前回には無い、blook処理とKBインストール前後でKBのインストールチェックを追加していますが
再起動をしないと反映されないKBの場合?は、
インストール後のチェックコマンド部分(win_patch_child.yml
の17~20行目、)をコメントアウトするか、
インストール後のチェックについては別のプレイブックで実施、またはServerspec等で確認をお願いします。
以下は前回より変更ありません。
rawモジュールなどを使った泥臭いやり方ですが、Windows関連の事例が少ないのであくまで参考までに。
実際にはserviceの上げ下げやreboot、上位のLB制御なども必要だと思いますがシンプルにKBのインストールのみを記載しています。
また、インストールについてはDISMではなくpkgmgrを使用しています。
1.大まかな流れ
Ansibleサーバ側で
0. 事前にプレイブック実行ディレクトリにpatchディレクトリ作成と配下に対象のmsuファイルを手動/自動でダウンロードしておく
win_patch.yml
1. ls コマンドでpatchディレクトリ配下のファイル名を動的に取得し、playbookのlsコマンド結果変数へ格納
2. lsコマンド結果変数で存在するファイル分、動的にループ(with_items
)し、拡張子がMSUファイルの場合のみ、KBファイルのインストールを行うプレイブック**win_patch_child.yml
**を呼出す(include
) 、取得したMSUファイル名をregex_replace
により正規表現で動的に加工し、KB番号など変数としてセット
以下Ansible ServerからターゲットのWindowsへ
win_patch_child.yml
1. msuファイルをコピーするためのディレクトリを作成
2. msuファイルをコピー
3. msuファイルを圧縮解凍
4. pkgmgrでサイレントインストール
2.playbook等
---
- hosts: win
# Don't gather hosts facts for performance
gather_facts: no
# Setting the task
tasks:
- name: "Get Win pacth name"
shell: ls patch
delegate_to: localhost
register: command_result
- name: "Install Win patch"
include: win_patch_child.yml kb_msu={{ item }}
with_items: "{{ command_result.stdout_lines }}"
when: "'.msu' in item"
vars:
kb_src_dr: "patch"
kb_dest_dr: "c:/work/"
kb_src: "{{ kb_src_dr }}/{{ kb_msu }}"
kb_dest: "{{ kb_dest_dr }}/{{ kb_msu }}"
kb_xml: "{{ kb_msu | regex_replace('.msu','.xml') }}"
kb_no: "{{ kb_msu | regex_replace('^.*-KB(\\d*)-.*msu$','\\1') }}"
check_command: "wmic qfe | findstr {{ kb_no }}"
# When I use wusa/pkgmagr as follows vars.
decompression_command: "wusa {{kb_dest}} /extract:{{ kb_dest_dr }}"
install_command: "pkgmgr /n:{{ kb_dest_dr }}{{ kb_xml }} /quiet /norestart"
uninstall_command: "wusa /uninstall /kb:{{ kb_no }} /quiet /norestart"
# When you use expand/Dism, you comment out a line of wusa/pkgmagr, and please use a variable as follows.
# kb_cab: "{{ kb_msu | regex_replace('.msu','.cab') }}"
# decompression_command: "expand -f:{{kb_cab}} {{ kb_dest_dr }}{{ kb_msu }} {{ kb_dest_dr }}KB{{ kb_no }}"
# install_command: "Dism /Online /Add-Package /PackagePath:{{ kb_dest_dr }}KB{{ kb_no }} /quiet /norestart"
# uninstall_command: "wusa /uninstall /kb:{{ kb_no }} /quiet /norestart"
---
- name: Check KB
raw: "{{ check_command }}"
register: command1_result
failed_when: command1_result.rc not in [ 0 , 1 ]
- block:
- debug: msg="Block START ----------------------"
- name: create directory
win_file: path={{ kb_dest_dr }} state=directory
- name: copy the file
win_copy: src={{ kb_src }} dest={{ kb_dest }} mode=0755
- name: decompression the msu file
raw: "{{ decompression_command }}"
- name: install KB
raw: "{{ install_command }}"
- name: Check KB
raw: "{{ check_command }}"
register: command2_result
failed_when: "'KB{{ kb_no }}' not in command2_result.stdout"
- debug: msg="Block END ------------------------"
when: "'KB{{ kb_no }}' not in command1_result.stdout"
rescue:
- debug: msg="Rescue START ---------------------"
- debug: msg="install {{ kb_no }} is error"
- name: uninstall KB
raw: "{{ uninstall_command }}"
- debug: msg="Rescue END -----------------------"
always:
- debug: msg="Always START ---------------------"
- debug: msg="before '{{ check_command }}' {{ command1_result.stdout_lines }}"
when: command1_result is defined
- debug: msg="after '{{ check_command }}' {{ command2_result.stdout_lines }}"
when: command2_result is defined
- debug: msg="Always END -----------------------"
- debug: msg="Because KB{{ kb_no }} had been already installed, I skipped installation.
This is result of the check command '{{ check_command }}'
{{ command1_result.stdout_lines }}"
when: "'KB{{ kb_no }}' in command1_result.stdout"
インベントリファイル hosts
[win]
win0[1:2]
[win:vars]
ansible_ssh_user=ansible
ansible_ssh_pass=ansibleansible
ansible_ssh_port=5985
ansible_connection=winrm
3.その他
patchディレクトリ配下
patch/
- Windows8.1-KB3079904-x64.msu
- Windows8.1-KB3140735-x64.msu
- openssl-1.0.1e-48.el6_8.1.x86_64.rpm
ansible --version
# ansible --version
ansible 2.2.0 (devel 394430a61e) last updated 2016/06/28 13:25:07 (GMT +900)
lib/ansible/modules/core: (detached HEAD 3c6f2c2db1) last updated 2016/06/28 13:25:30 (GMT +900)
lib/ansible/modules/extras: (detached HEAD 1c36665545) last updated 2016/06/28 13:25:37 (GMT +900)
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides