Cocoon-Engine

甘党インフラエンジニアの技術ブログ

Chocolat Chocolat Chocolat Chocolat

IT技術とスイーツに興味がある方、ちょっと見ていきませんか?

Windows 11 + VMWare WorkStation Pro で Ansible 検証環境構築

個人で ansible の動作確認をしたい方のために、Windows 11 の VMWare WorkStation Pro で Ansible 検証環境を構築する方法を紹介します。

前提

Ansible の検証環境を用意したい!と思ったものの、クラウドだとお金かかるし、
Docker でもいろいろ制限があって無理で、、、で苦労しました。
WSLだとローカル環境に対してしか検証できないし…とか。
(実際やり方はあるかもしれないけど、、)

そこで、個人利用に限って無償で使える VMWare WorkStation Pro を使用することにしました。
VMWare WorkStation Pro のインストール方法は多くの方が記事を上げてくださっていたので参考にさせていただきました。

VMWare WorkStation Pro 環境構築

VMWare 側の用意は WorkStation Pro をインストールした後に OS の iso ファイルをダウンロードするだけです。

今回はホスト名 Rocky-[123] として VM を3台作成しています。
OS は Rocky9.4 の DVD ISO を公式からダウンロードして入れました。
https://rockylinux.org/ja/download

OS側の初期インストールについても一般的な手順と変わりないので、VMのスペックだけ記載してあとは省略します。

メモリ 2GB
CPU数 2
ディスク 20GB
パッケージ 最小限のインストール

作成した VM は SSH 用の追加設定等は不要で、インスタンス作成時に割り当てられる IP にホスト OS から SSH 接続できるようです。

ただし、root のリモートログインはデフォルトで禁止されているので、必要に応じて /etc/ssh/sshd_config にて PermitRootLogin を yes に変更してください。

 

環境の構成図は以下のイメージです。

 

Ansible 環境構築

Ansible 実行ユーザ作成(コントロールノード)

まず,コントロールノードに Ansible 実行ユーザ(ansible)を作成します。
sudo 可能にするため、wheel グループをつけて、パスワードも設定します。

# useradd -G wheel ansible
# passwd ansible

後ほどターゲットノード側にも同じく ansible ユーザを作成するため、鍵認証用の公開鍵と秘密鍵を作っておきます。

[ansible@Rocky-1 ~]$ ls -la
合計 16
drwx------. 2 ansible ansible  83  9月 28 15:52 .
drwxr-xr-x. 4 root    root     33  9月 28 15:49 ..
-rw-------. 1 ansible ansible  22  9月 28 15:52 .bash_history
-rw-r--r--. 1 ansible ansible  18  4月 30 20:28 .bash_logout
-rw-r--r--. 1 ansible ansible 141  4月 30 20:28 .bash_profile
-rw-r--r--. 1 ansible ansible 492  4月 30 20:28 .bashrc
[ansible@Rocky-1 ~]$
[ansible@Rocky-1 ~]$ mkdir .ssh
[ansible@Rocky-1 ~]$ chmod 700 .ssh/
[ansible@Rocky-1 ~]$
[ansible@Rocky-1 ~]$ cd .ssh/
[ansible@Rocky-1 .ssh]$
[ansible@Rocky-1 .ssh]$ pwd
/home/ansible/.ssh
[ansible@Rocky-1 .ssh]$
[ansible@Rocky-1 .ssh]$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansible/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ansible/.ssh/id_rsa
Your public key has been saved in /home/ansible/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:mmjVmMjSwm4NxzuMaN01HmGhL6WKg00QN5mVhX29GvE ansible@Rocky-1
The key's randomart image is:
+---[RSA 4096]----+
|. o+.=.. .       |
| oo.o o + .      |
|.    . = o .     |
| o + .=+o E      |
|  * *o+=So       |
|.=oOo++o+        |
|o+=oB.o.         |
|.... .           |
|                 |
+----[SHA256]-----+
[ansible@Rocky-1 .ssh]$
[ansible@Rocky-1 .ssh]$ cp id_rsa.pub authorized_keys
[ansible@Rocky-1 .ssh]$ chmod 600 authorized_keys
[ansible@Rocky-1 .ssh]$ ls -la
合計 12
drwx------. 2 ansible ansible   61  9月 28 15:58 .
drwx------. 3 ansible ansible   95  9月 28 15:54 ..
-rw-------. 1 ansible ansible  741  9月 28 15:58 authorized_keys
-rw-------. 1 ansible ansible 3434  9月 28 15:56 id_rsa
-rw-r--r--. 1 ansible ansible  741  9月 28 15:56 id_rsa.pub
[ansible@Rocky-1 .ssh]$

 

Ansible インストール

パッケージ版でも良いですが、今回は Rocky-1 のホストをコントロールノードとして、python の venv 環境でのインストールにします。
python3 系が必要ですが、Rocky 9.4 はデフォルトで 3.9.18 が入っていたので問題なしです。

[ansible@Rocky-1 ~]$ python -V
Python 3.9.18
[ansible@Rocky-1 ~]$
[ansible@Rocky-1 ~]$ python -m venv myvenv
[ansible@Rocky-1 ~]$ source myvenv/bin/activate
(myvenv) [ansible@Rocky-1 ~]$

最新版を入れるので、pip をアップグレードしてから ansible をインストールします。

(myvenv) [ansible@Rocky-1 ~]$ pip install --upgrade pip
Requirement already satisfied: pip in ./myvenv/lib/python3.9/site-packages (21.2.3)
Collecting pip
  Downloading pip-24.2-py3-none-any.whl (1.8 MB)
     |████████████████████████████████| 1.8 MB 5.3 MB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 21.2.3
    Uninstalling pip-21.2.3:
      Successfully uninstalled pip-21.2.3
Successfully installed pip-24.2
(myvenv) [ansible@Rocky-1 ~]$
(myvenv) [ansible@Rocky-1 ~]$ pip install ansible-core
Collecting ansible-core
  Downloading ansible_core-2.15.12-py3-none-any.whl.metadata (7.0 kB)
Collecting jinja2>=3.0.0 (from ansible-core)
  Downloading jinja2-3.1.4-py3-none-any.whl.metadata (2.6 kB)
Collecting PyYAML>=5.1 (from ansible-core)
  Downloading PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.1 kB)
Collecting cryptography (from ansible-core)
  Downloading cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl.metadata (5.4 kB)
Collecting packaging (from ansible-core)
  Downloading packaging-24.1-py3-none-any.whl.metadata (3.2 kB)
Collecting resolvelib<1.1.0,>=0.5.3 (from ansible-core)
  Downloading resolvelib-1.0.1-py2.py3-none-any.whl.metadata (4.0 kB)
Collecting importlib-resources<5.1,>=5.0 (from ansible-core)
  Downloading importlib_resources-5.0.7-py3-none-any.whl.metadata (2.8 kB)
Collecting MarkupSafe>=2.0 (from jinja2>=3.0.0->ansible-core)
  Downloading MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.0 kB)
Collecting cffi>=1.12 (from cryptography->ansible-core)
  Downloading cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.5 kB)
Collecting pycparser (from cffi>=1.12->cryptography->ansible-core)
  Downloading pycparser-2.22-py3-none-any.whl.metadata (943 bytes)
Downloading ansible_core-2.15.12-py3-none-any.whl (2.3 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.3/2.3 MB 9.6 MB/s eta 0:00:00
Downloading importlib_resources-5.0.7-py3-none-any.whl (24 kB)
Downloading jinja2-3.1.4-py3-none-any.whl (133 kB)
Downloading PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (737 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 737.4/737.4 kB 9.8 MB/s eta 0:00:00
Downloading resolvelib-1.0.1-py2.py3-none-any.whl (17 kB)
Downloading cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl (4.0 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.0/4.0 MB 9.6 MB/s eta 0:00:00
Downloading packaging-24.1-py3-none-any.whl (53 kB)
Downloading cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (445 kB)
Downloading MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Downloading pycparser-2.22-py3-none-any.whl (117 kB)
Installing collected packages: resolvelib, PyYAML, pycparser, packaging, MarkupSafe, importlib-resources, jinja2, cffi, cryptography, ansible-core
Successfully installed MarkupSafe-2.1.5 PyYAML-6.0.2 ansible-core-2.15.12 cffi-1.17.1 cryptography-43.0.1 importlib-resources-5.0.7 jinja2-3.1.4 packaging-24.1 pycparser-2.22 resolvelib-1.0.1
(myvenv) [ansible@Rocky-1 ~]$
(myvenv) [ansible@Rocky-1 ~]$ ansible --version
ansible [core 2.15.12]
  config file = None
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ansible/myvenv/lib64/python3.9/site-packages/ansible
  ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/ansible/myvenv/bin/ansible
  python version = 3.9.18 (main, Jan 24 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/home/ansible/myvenv/bin/python)
  jinja version = 3.1.4
  libyaml = True
(myvenv) [ansible@Rocky-1 ~]$

sshpass も必要なのでここであわせてインストールしておきます。

# dnf install sshpass

インベントリファイル作成

RockyServers のグループに Rocky-[123] を所属させます。

[RockyServers]
Rocky-1 ansible_host=192.168.168.131
Rocky-2 ansible_host=192.168.168.132
Rocky-3 ansible_host=192.168.168.133

ansible.cfg 編集

ここがちょっと注意です。

今回、ansible 実行ユーザである ansible ユーザはコントロールノード側(Rocky-1)のみ手動で作成していますが、ターゲットノード側には存在していません。

ターゲットノードでの ansible ユーザの作成も playbook で実施したいため、 一番最初のみ root ユーザで playbook を実行させ、ansible ユーザ作成後に実行ユーザを ansible ユーザに変更する必要があります。
また、警告メッセージやフィンガープリントの確認は出ないようにしています。

[defaults]
remote_user = root
ask_pass = True
gathering = explicit
host_key_checking = False
inventory = /home/ansible/ansible/inventory
interpreter_python = /usr/bin/python3
deprecation_warnings = False

ansible 実行ユーザ作成(ターゲットノード)

ansible を実行するための共通ユーザが各サーバにすでに作成済みの場合は ssh-copy-id で鍵を配置してあげれば良いですが、今回はコントロールノードにしか存在していないため、ターゲットノード側への ansible ユーザ作成も playbook で実行します。

まず、authorized_key のモジュールを使用するので、ansible.posix の追加インストールが必要です。

$ ansible-galaxy collection download ansible.posix
$ cd collections
$ ansible-galaxy collection install -r requirements.yml

playbook は以下。

---
- hosts: RockyServers, !Rocky-1
  tasks:
  - name: Create user
    become: yes
    user:
      name: ansible
      state: present
      append: yes
      groups: wheel
      password: "{{ 'q1w2e3r4' | password_hash('sha512', 'salt') }}"
      update_password: on_create
    register: user_add

  - name: mkdir .ssh
    file:
      path: /home/ansible/.ssh
      state: directory
      owner: ansible
      group: ansible
      mode: '0700'

  - name: add authorized keys
    ansible.posix.authorized_key:
      user: ansible
      state: present
      key: "{{ lookup('file', '/home/ansible/ansible/ansible_user/ansible.pub') }}"

  - name: passwd setting
    shell:
      "chage -d 0 {{ user_add.name }}"
    when: user_add is changed

Rocky-1 = コントロールノードは作成済みのため実行対象から除外しています。

パスワードに関しては通常 Vault を使用して設定すると思いますが、今回は諸事情でホストごとにパスワードを変えるので、ユーザー作成時に有効期限を設定することで初回ログイン時のパスワード変更を強制しています。

また、公開鍵はコントロールノードの /home/ansible/ansible/ansible_user/ansible.pub に配置しています。

 

構文チェック後に、playbook を実行します。

$ ansible-playbook playbook.yml --syntax-check
$ ansible-playbook playbook.yml --check --ask-pass
$ ansible-playbook playbook.yml --ask-pass

 

ansible ユーザかつ鍵認証で接続するように変更

playbook の実行が成功し、各ホストに ansible ユーザが作成されたら ansible.cfg を修正します。

[defaults]
remote_user = ansible
ask_pass = False
gathering = explicit
host_key_checking = False
inventory = /home/ansible/ansible/inventory
private_key_file = /home/ansible/.ssh/id_rsa
interpreter_python = /usr/bin/python3
deprecation_warnings = False

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = true

以降の実行は ansible ユーザによる sudo で行われるようになります。

(おまけ) 複数台に鍵認証で接続するとき

ホストの台数分パスワードを聞かれるのは面倒なので、エージェントに鍵を読ませておくと楽です。

$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa

気に入ったらぜひ共有してください。

TOP