Ansible 対象サーバーにパスワード認証接続してHello Worldの表示とlinux ユーザー作成してみた

# はじめに
Ansibleを今まで使用したことがなく勉強のため、Ansibleを動かしてみました
今回は初めてのため、対象サーバーにパスワード認証接続してHello Worldの表示させてみました。

Ansibleとは　
※以下の文章はchatGPTで検索しました。
Ansibleは、ITインフラストラクチャの自動化と構成管理を行うためのオープンソースのオーケストレーションツールです。Ansible は SSH や WinRM などのプロトコルを使用してリモートホストに接続し、管理対象のホスト上タスクを実行します。対象ホストにエージェントのインストールは不要であり、管理対象のホストに対して軽量な影響は与えません。


**参考にした資料**
Ansible入門　Udemyで学びました。
https://www.udemy.com/course/ansible-linux/learn/lecture/15003064#overview


## 構成
VirtualBoxでゲストマシンを2台構築しました。 OSはcentOS7です。

管理ホストにepelとansibleをインストールする。
対象ホストはパッケージ等のインストールは不要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/62820eba-4d2f-2e94-45be-75a73f300f37.png)

## 対象サーバーにパスワード認証接続してHello, Worldを表示してみた
### 管理ホストにSSH接続した
WSLを開き管理ホスト「192.168.0.100」にSSH接続した
```
$ ssh root@192.168.0.100
root@192.168.0.100's password:
Last login: Sat Jul  8 10:35:17 2023 from 192.168.0.24
```

### epelのリポジトリのインストール
現在のリポジトリリストを確認した
```
 yum repolist all
```
実行例　epelが既にリポジトリに登録されていることを確認した
```
[root@localhost ansible]# yum repolist all | grep epel
Failed to set locale, defaulting to C
 * epel: ftp.yz.yamagata-u.ac.jp
epel/x86_64                               Extra Packages for Ente enabled: 13753
epel-debuginfo/x86_64                     Extra Packages for Ente disabled
epel-source/x86_64                        Extra Packages for Ente disabled
epel-testing/x86_64                       Extra Packages for Ente disabled
epel-testing-debuginfo/x86_64             Extra Packages for Ente disabled
epel-testing-source/x86_64                Extra Packages for Ente disabled
```
### ansibleをインストールした
ansibleが入っていないことを確認した
```
# rpm -qa | grep ans
jansson-2.10-1.el7.x86_64
```
ansibleをインストールした
```
# yum install ansible --enablerepo=epel
```
ansibleが入っていることを確認するために、バージョンを確認した
```
# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.
```
### ansibleのhostsファイル設定した
ansibleのhostsファイル「/etc/ansible/hosts」は、ansibleをインストールしたら自動的に作成されます。
hostsファイルは対象サーバーに接続するためにログイン情報の設定が必要です。

今回はgroup1を追記してその直下に対象サーバー「192.168.0.32」にログインするためにユーザー名とパスワードを設定した
```
vi /etc/ansible/hosts
[group1]
192.168.0.32 ansible_user=root ansible_password=＜ログインパスワード>
```
設定が上手く反映されていることを確認した
```
[root@localhost ansible]# cat /etc/ansible/hosts | grep -v "#" | grep -v ^$
[group1]
192.168.0.32 ansible_user=root ansible_password=＜ログインパスワード>
```
### 対象サーバーに疎通確認した
ansibleコマンドを使用してpingを対象サーバーに対して実行しました。
以下の赤文字のエラーが出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/af0ae18b-7615-ac77-df36-dc7c5f3ac227.png)

以下のQiitaの記事の設定を参考にいたしました。
https://qiita.com/taka379sy/items/331a294d67e02e18d68d

ssh_connectionの直下のss_args = を追記
```
# cat /etc/ansible/ansible.cfg | grep -v "#" | grep -v "^$"
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
[root@localhost ansible]#
```
問題なくping疎通が通りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/f41f1ceb-b9c0-dd87-0e3b-4d0005ec3c2e.png)
### Hello World表示のみのサンプルのtest.ymlを作成した
#### Hello wordを表示させるymlファイルを作成した

hosts allの意味は「/etc/ansible/hosts 」に指定しているすべてのホストに対してecho コマンドが実行されます。今回は対象ホスト1台のみ設定しているため、そのホストのみコマンドが実行されます。
```
# cat test.yml
- name: Execute a command
  hosts: all
  tasks:
    - name: Run command
      command: echo "Hello, World!"
```
/etc/ansible配下のファイル構成を確認した
```
/etc/ansible
[root@localhost ansible]# ls -tlr
total 32
drwxr-xr-x. 2 root root     6 Jan 16  2022 roles
-rw-r--r--. 1 root root 19985 Jan 16  2022 ansible.cfg　※ansibleの設定ファイル
-rw-r--r--. 1 root root   109 Jul  8 09:49 test.yml　※コマンドの処理を定義する
-rw-r--r--. 1 root root  1084 Jul  8 09:50 hosts　　※接続する対象サーバーを定義する
```
#### test.ymlファイルの文法チェックをした
OKが1でその他はすべて0のため、文法チェックは問題なし。
```
#  ansible-playbook test.yml -k --check
```
実行例
```
[root@localhost ansible]# ansible-playbook test.yml -k --check
SSH password:

PLAY [Execute a command] **************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************
ok: [192.168.0.32]

TASK [Run command] ********************************************************************************************************************************************************************
skipping: [192.168.0.32]

PLAY RECAP ****************************************************************************************************************************************************************************
192.168.0.32               : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
```
#### test.ymlファイルを実行した
changedは変更があるときに0以上の値になります。
仮に同じ処理を複数回実行した際に、変更がない場合はchanged=0と表示されます。

```
# ansible-playbook test.yml
```
```
[root@localhost ansible]# ansible-playbook test.yml

PLAY [Execute a command] **************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************
ok: [192.168.0.32]

TASK [Run command] ********************************************************************************************************************************************************************
changed: [192.168.0.32]

PLAY RECAP ****************************************************************************************************************************************************************************
192.168.0.32               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

```
#### 対象ホストのログを確認した

対象ホスト「192.168.0.32」にSSH接続した
```
root@192.168.0.32's password:
Last login: Sat Jul  8 11:33:36 2023 from 192.168.0.100
[root@localhost ~]#
```
シスログ「/var/log/messages」を確認した
プレイブック実行の時間帯にHello worldがログに出力されていることを確認した
```
[root@localhost log]# tail -n 2 /var/log/messages
Jul  8 11:33:36 localhost ansible-command: Invoked with creates=None executable=None _uses_shell=False strip_empty_ends=True _raw_params=echo "Hello, World!" removes=None argv=None warn=True chdir=None stdin_add_newline=True stdin=None
Jul  8 11:34:37 localhost systemd-logind: Removed session 12.
[root@localhost log]#
```

## 対象サーバーにパスワード認証のlinuxユーザーを作成した
#### WSLを開き管理ホスト「192.168.0.100」にSSH接続した
```
$ ssh root@192.168.0.100
root@192.168.0.100's password:
Last login: Sat Jul  8 10:35:17 2023 from 192.168.0.24
```
#### linuxユーザーを作成するymlファイルを作成した
以下のフォルダ配下にユーザー作成のymlファイルを作成した
```
[root@server1 ansible]# pwd
/etc/ansible
[root@server1 ansible]# ls -tlr
total 40
drwxr-xr-x. 2 root root     6 Jan 16  2022 roles
-rw-r--r--. 1 root root   109 Jul  8 09:49 test.yml
-rw-r--r--. 1 root root  1083 Jul  8 10:29 hosts
-rw-r--r--. 1 root root 20127 Jul  9 18:26 ansible.cfg
-rw-r--r--. 1 root root   268 Jul  9 18:57 usercreat.yml　※作成した
```
ユーザ作成のymlファイルを作成した。
/etc/ansible/hostsファイルに指定しているすべてのホストに対してplaybook実行する設定にしました。

```
# vi usercreat.yml
```
```
---
- hosts: all
  become: yes
  tasks:
    - name: Create a Linux user
      user:
        name: test01
        password: "{{ 'newpassword' | password_hash('sha512') }}"
        createhome: yes
        home: /home/test01
        group: test
        shell: /bin/bash

```
ユーザーのパスワードはハッシュにする必要があります。
以下のサイトを参考にしました。
※chatGPTを使用してansibleのユーザー作成のコードを知りました。
https://qiita.com/sicksixrock66/items/474068167de9c8454319

#### ansibleの文法チェックしました。
```
[root@server1 ansible]# ansible-playbook usercreat.yml -k --check
SSH password:

PLAY [all] **********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.0.32]

TASK [Create a Linux user] ******************************************************************************************************************************************************************************************************************
changed: [192.168.0.32]

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.0.32               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
#### playbookを実行しました
```
[root@server1 ansible]# ansible-playbook usercreat.yml

PLAY [all] **********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.0.32]

TASK [Create a Linux user] ******************************************************************************************************************************************************************************************************************
changed: [192.168.0.32]

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.0.32               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
#### -vオプションを付けて実行したら詳細に表示されます。
ansibleのplaybookの処理を詳細に表示したい場合は-vオプションを付けてください
```
[root@localhost ansible]# ansible-playbook -v user.yml
Using /etc/ansible/ansible.cfg as config file

PLAY [all] *********************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************
ok: [192.168.0.30]

TASK [Create a Linux user] *****************************************************************************************************************
changed: [192.168.0.30] => {"changed": true, "comment": "", "create_home": true, "group": 1000, "home": "/home/test01", "name": "test01", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}

PLAY RECAP *********************************************************************************************************************************
192.168.0.30               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

```
#### WSLを開き対象ホスト「192.168.0.32」にSSH接続した
test01ユーザーが作成されていることを確認しました。
```
[root@localhost home]# ls -tlr /home
total 0
drwx------. 3 test   test 117 Jan  9 12:44 test
drwx------  2 test01 test  62 Jul  9 19:02 test01 ※test01ユーザーが作成された
[root@localhost home]#
[root@localhost home]# id test01
uid=1001(test01) gid=1000(test) groups=1000(test)
[root@localhost home]#
```
※パスワード例)newpasswordでログイン出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/11a4bde0-722d-78a2-9a42-29f956b1254b.png)


#### 補足情報
Ansibleは先頭にスペースを入れてhostとtaskの位置を揃える。
taskの定義より、スペースを一つ入れてnameを定義しないと文法チェックでエラーになります。
そのため、hostとtaskの定義する際は行頭のスペースの数に注意してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/dd7b8931-a33e-3b2e-ddf7-e9c92bccae8a.png)

以下の様に文法チェックコマンドを実行してエラーが出なければ問題なしです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/bde131b6-bbe6-05da-c606-d98802e05164.png)



# まとめ
複数のサーバーに対して同じコマンドを実行する際に
Ansibleを使用すると業務効率化出来ることが分かりました。

但し、管理ホストと対象ホストはSSH接続が出来る必要があります。
管理ホストから対象ホストへの接続する際にSSHのエラーではまりました。
今回は参考になるQiitaの記事の設定どおりで解決出来ましたが、実務ではセキュリティ的なものがあるため、設定ファイルを変更する場合は慎重にする必要があります。

管理ホストにはansibleがインストールする必要があります。
そのため、本番環境などansibleを入れられない環境の場合は、ansibleは利用できない可能性もあります。

今回対応してみてtest.ymlの構文チェックでつまずきやすくなかなか解決出来ませんでした。
ymlファイルの作成に慣れる必要があります。

ansibleは始めたばかりのため、これからもっとAnsibleに触れて知識を増やしていきたいです。