CentOS7環境とは少し違うかな?と言う気がした。
CentOS7環境に対して過去にAnsibleをインストール・実装したことはあったのだけど、実はCentOS8に関してはAnsibleをインストールしたことはなかったので手順の確認を行いました。
- パッケージ管理ソフトウェアがdnfに変わっていること
- Python3が基本的に使用されること
ってのが気になったポイントですが、果たしてどんなもんかーと思って導入してみることに。
実施手順
前提環境の整備
サーバとして前提としているパッケージのインストールと既存パッケージのアップデートを行います。
dnf -y install bash-completion net-tools nfs-utils bind-utils rsync wget nc tcpdump sysstat lsof strace telnet psmisc zip unzip net-snmp net-snmp-libs
dnf -y update
EPELリポジトリの導入、pip, sshpassを導入します。
dnf -y install python3-pip epel-release sshpass
SELINUX無効化を目的としてコンフィグ設定を変更します。
vi /etc/selinux/config
内部LANで動かすことからFirewalldを停止します。自動起動抑止も行います。
systemctl stop firewalld
systemctl disable firewalld
我が家環境の内部サーバはNFSサーバを使ってるので自動NFSマウント設定を実装します。
vi /etc/fstab
mkdir /data
mount /data
監視にZABBIXを使ってるのでエージェントソフトをダウンロードするために、ZABBIXリポジトリの導入を行います。その上でエージェントを導入します。
rpm -Uvh https://repo.zabbix.com/zabbix/5.2/rhel/8/x86_64/zabbix-release-5.2-1.el8.noarch.rpm
dnf -y install zabbix-agent
vi /etc/zabbix/zabbix_agent.conf
エージェントの自動起動設定を有効にします。
systemctl enable zabbix-agent
一旦再起動します。
shutdown -r now
Ansible実行ユーザを作成します。加えてパスワード変更を行います。
useradd ansible
passwd ansible
実行ユーザがsudoできるよう、Wheelグループに実行ユーザを追加します。
gpasswd -a ansible wheel
これで前提環境がそろったので、ansible実行ユーザにスイッチします。
su - ansible
Ansibleの導入
pip3を使用してansibleパッケージを導入します。
pip3 install ansible --user
ansibleのバージョン確認を行います。
ansible --version
以下は出力結果ですが、2020年11月14日時点の最新バージョンは2.10.3のようです。また、使用するPythonのバージョンは3.6となっており、Python3前提で動作する設定になることが見て分かります。
また、pip3を通じてインストールした際に「–user」オプションスイッチをつけたことにより、ユーザのローカル領域にansibleがインストールされた状態になっています。
ansible 2.10.3
config file = None
configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/ansible/.local/lib/python3.6/site-packages/ansible
executable location = /home/ansible/.local/bin/ansible
python version = 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
SSH鍵セットを作成します。
ssh-keygen -t rsa
この鍵を使用して、ログインするLinuxサーバ上のAuthorized_Keysへの登録を行います。「-o StrictHostKeyChecking=no」を加えることで、署名チェックを回避することが出来るようです。
ssh-copy-id -o StrictHostKeyChecking=no -i /home/ansible/.ssh/id_rsa.pub root@<管理対象IP or hostname>
Windowsの遠隔操作を可能にするため、WinRM連携をするためのモジュールインストールを行います。
pip3 install pywinrm --user
これで一通りインストールするものとしてはそろったかな?という感じになります。
hosts、Playbooksの配置・作成等
hostsとplaybooksを配置するディレクトリを作ります。
mkdir ~/ansible-hosts
mkdir ~/ansible-playbook-libs
その上で ansible-hosts/servers-linux.hosts を作成しました。
[linux-servers]
192.168.100.133
192.168.100.143
192.168.100.144
192.168.100.155
192.168.100.168
192.168.100.169
192.168.220.202
でもって、 ansible-playbook-libs/server-setup.yml を作成したらこんな感じ。
---
- hosts: linux-servers
user: root
tasks:
- name: upadte exist packages
yum: name='*' state=latest
- name: install via yum
yum: name={{ item }} state=installed
with_items:
- bash-completion
- net-tools
- bind-utils
- rsync
- wget
- nc
- tcpdump
- sysstat
- lsof
- strace
- telnet
- psmisc
- zip
- unzip
- nfs-utils
- net-snmp
- net-snmp-libs
- name: (0) Stop Firewalld
service:
name: firewalld
enabled: no
- name: (1) Install selinux module
yum: name=libselinux-python state=installed
- name: (2) Disable selinux
selinux: state=disabled
register: selinux
- name: (3) get portnum SSHd
set_fact:
ssh_port: "{{ hostvars[inventory_hostname].ansible_port if 'ansible_port' in hostvars[inventory_hostname] else 22 }}"
when: selinux.reboot_required
- name: (4) Reboot
shell: "sleep 2 && reboot"
async: 1
poll: 0
when: selinux.reboot_required
- name: (5) wait for reboot complete
local_action: wait_for host={{ inventory_hostname }} port={{ ssh_port }} state=stopped
when: selinux.reboot_required
- name: (6) wait for machine startup
local_action: wait_for host={{ inventory_hostname }} port={{ ssh_port }} state=started
when: selinux.reboot_required
実行してみます。
ansible-playbook -i /home/ansible/ansible-hosts/servers-linux-20201114a.hosts server-setup.yml -vvvv
--------------------中略------------------------
PLAY RECAP **
192.168.100.133 : ok=6 changed=1 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
192.168.100.143 : ok=6 changed=0 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
192.168.100.144 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
192.168.100.155 : ok=4 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
192.168.100.168 : ok=4 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
192.168.100.169 : ok=4 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
192.168.220.202 : ok=6 changed=0 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
Failedになったのは、どうやらパッケージ管理ソフトの相違があったのが原因っぽいですね。いくらWrapper入れてもyumプラグインで対応できるというわけではどうやらなさそうです。
Windows版も便利そう
Windowsに対して設定自動化をする機能も思った以上に豊富なようで、割と簡単な流れでWindowsに対するアプローチも行えました。ただ、事前準備としてPowerShellの導入が必要そうです。(今回試した環境はWindows Server 2019だったので、殆ど考慮するポイントはないと思いますが・・)
Windowsに対しては先に以下のものを管理者権限を持ったPowerShellウィンドウ上で実行します。
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
$url変数を見れば分かるんですが、このスクリプトを実行するにはインターネットへの接続環境が必要なようです。これの入手が難しいときは、別途上記URLからPowerShellスクリプトファイルをダウンロードしてその場所を指定すれば良いのかなと思います。
結果として、以下の通り出力されてればWinRMが使えるようになってるっぽいです。他にもコマンド叩く必要はありそうだけど、取り敢えずこれだけの確認でちゃんとつながるはつながったス。
Self-signed SSL certificate generated; thumbprint: C65974F03E5C86BFC75DA7EF8FA9258744AEC5D6
wxf : http://schemas.xmlsoap.org/ws/2004/09/transfer
a : http://schemas.xmlsoap.org/ws/2004/08/addressing
w : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
lang : ja-JP
Address : http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
ReferenceParameters : ReferenceParameters
OK
hostsの設定
こんな風に定義をしました。Linuxとは異なり、別途varsにていくつかの変数を指定する必要があるようです。
[servers-windows]
Uriel ansible_host=192.168.120.202
[servers-windows:vars]
ansible_user=Administrator
ansible_password=********
ansible_port=5986
ansible_winrm_transport=ntlm
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
Playbookの作成
こんな風に構成しています。思った以上に多機能でした。
- hosts: windows-servers
tasks:
- win_user:
name: localadms
password: ********
state: present
groups:
- Administrators
- Users
- name: Install all security, critical, and rollup updates without a scheduled task
win_updates:
category_names:
- SecurityUpdates
1つ目はローカルユーザを構成するタスク、2つ目はセキュリティパッチを全て適用するタスクです。既に処理済みのものに動かしたので余り特筆すべきポイントはないんですが、どうやら走ってくれたようです。
$ ansible-playbook -i /home/ansible/ansible-hosts/servers-windows-20201114a.hosts win-server-setup.yml
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
PLAY [servers-windows] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************
ok: [192.168.120.202]
ok: [192.168.100.203]
TASK [win_user] ***********************************************************************************************************************************
fatal: [192.168.100.203]: FAILED! => {"changed": true, "msg": "Failed to remove Domain Users: Exception calling \"Remove\" with \"1\" argument(s): \"この操作をこの特殊グループに対して実行することはできません。\r\n\""}
ok: [192.168.120.202]
TASK [Install all security, critical, and rollup updates without a scheduled task] ****************************************************************
ok: [192.168.120.202]
PLAY RECAP ****************************************************************************************************************************************
192.168.100.203 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
192.168.120.202 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
特に興味を引いたのは2つ目ですが、実際にどういう挙動を示したかというと以下のような感じでした。
- Windows Updateの画面からは更新実施してるようには見えない
- しかし、プロセス一覧を見るとTrusted Installerプロセスが見えており、アップデート処理が行われて居るであろう事は読み取れた

- 全部無事に適用されたか?と言うとそうではなく、一部Windows Updateの処理と競合したようで、1つだけパッチがWindows Update経由じゃないとインストールできなくなっていた
- 試しにWindows Server 2012 R2のドメインコントローラに対してセキュリティアップデート処理を施したら以下のようになった。
fatal: [192.168.100.203]: FAILED! =>
{
"changed": true,
"failed_update_count": 1,
"filtered_updates": {},
"found_update_count": 2,
"installed_update_count": 1,
"msg": "Failed to install one or more updates",
"reboot_required": false,
"updates": {
"131c93ce-765a-4fe3-8cca-3c7674361a8c": {
"categories": [
"Microsoft SQL Server 2016",
"Security Updates"
],
"failed": true,
"failure_hresult_code": -2147023293,
"id": "131c93ce-765a-4fe3-8cca-3c7674361a8c",
"installed": false,
"kb": ["4505220"],
"title": "SQL Server 2016 Service Pack 2 GDR のセキュリティ更新プログラム (KB4505220)"
},
"362b5ee9-d309-4e86-a7b9-aae1c112254b": {
"categories": [
"Security Updates", "Windows Server 2012 R2"
],
"id": "362b5ee9-d309-4e86-a7b9-aae1c112254b",
"installed": true,
"kb": ["4566425"],
"title": "2020-07x64 ベース システム用 Windows Server 2012 R2 サービス スタック更新プログラム (KB4566425)"
}
}
}
その他、サービス状態やインストール処理に関するところを自動化させることが出来そうです。もう少しモジュールの詳細を掘ってみようかなーと考えています。
Comments are closed