備忘録 Ansible rootユーザー以外で実行する（クライアントの実行rootユーザーの場合）

これまで、とりあえずAnsibleに慣れるために、rootユーザーで実行していたが、実際の運用でrootユーザーをゴリゴリつかうことはないため、以下のパターンで今回は検証してみる。

#1.　実行環境
##1. 実行ユーザーについて

- Ansibleサーバー
  サーバー名：brighton001
  実行ユーザー：ansible

- クライアント
  サーバー名：brighton002
  実行ユーザー：root

##2. ansible実行環境について
ansibleユーザー作成後、ansible環境を設定するが、ディレクトリ構成などは、以下の通りに作成する。

```
/home/ansible
         ├─ .ssh
         │     ├─ id_rsa.pub           このファイルの中身を、クライアントへコピー
         └─ playbooks
                  ├─ hosts             インベントリーファイル
                  ├─ files             copyモジュールなどでクライアントに配布するファイルを格納
                  │     └─ idex.html   テスト用ファイル
                  ├─ vars              変数ファイルを格納
                  │     └─ test1.yml   変数ファイル
                  └─ tasks             playbookを格納
                         └─ test1.yml  playbook
```


#2. ansibleユーザーの作成
Ansibleサーバー上で、ansibleユーザーを作成する。

##1.ansibleグループの作成
グループ名:ansible、GID:9010で作成する。

`# groupadd -g 9010 ansible`

実行後、グループが作成されたことを確認する。

```
# grep ansible /etc/group
ansible:x:9010:ansible
```


##2. ansibleユーザーの作成
ユーザー名:ansible、UID:9010、gecos:ansible userで作成する。

`# useradd -c "ansible user" -g ansible -G 9010 -u 9010 ansible`

実行後、ユーザーが作成されたことを確認する。

```
# grep ansible /etc/passwd
ansible:x:9010:9010:ansible user:/home/ansible:/bin/bash

```

##3. ssh公開鍵の設定
ansibleユーザーで実行する。

`$ ssh-keygen -t rsa`

```
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansible/.ssh/id_rsa): ←そのままEnter
Created directory '/home/ansible/.ssh'.
Enter passphrase (empty for no passphrase): ←そのままEnter
Enter same passphrase again: ←そのままEnter
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:
（省略）
```
##4.公開鍵をクライアントに送り込む
/home/ansible/.sshディレクトリにid_rsa.pubという公開鍵が出来ているので、それをクライアント側に送り込む。
今回、クライアントはrootユーザーで実行するので、/root/.sshディレクトリに送り込む。
そのとき、Ansibleサーバーのansibleユーザーということが分かるようにしておく。

` scp id_rsa.pub root@brighton002:/root/.ssh/id_rsa.pub_ansible_brighton001`

パスワード無しで実行するために、クライアント側のauthorized_keysファイルに送り込んだファイルの中身を追記しておく。

`$ ssh -l root brighton002 "cat /root/.ssh/id_rsa.pub_ansible_brighton001 >> /root/.ssh/authorized_keys"`


#3. Ansibleの環境設定
##1. 必要なディレクトリを作成

playbookを作成する上で、必要なディレクトリを作成する。

`$ mkdir playbooks`
`$ mkdir playbooks/vars`
`$ mkdir playbooks/files`
`$ mkdir playbooks/tasks`

##2. inventoryファイルの作成
inventoryファイルを作成する。
とりあえず、今回用のを作成する。


```
[web]
brighton002
```

#4. playbookなどなどを作成
##1. playbookの作成
tasksディレクトリに、playbookを作成する。

今回実行する内容は、以下の通りである
- Apacheのインストール
- Apacheを起動する
- Firewalldを起動する
- Firewalldに対してPort 80番を許可する
- index.htmlファイルをクライアントに送りこむ
- haldlersを設定し、以下の処理を組み込む
    - Firewalldに変更が有る場合、再起動
    - index.htmlに変更がある場合、再起動

実際に記述したplaybookは以下の通りです。

```test1.yml
- hosts: web
  remote_user: root
  vars_files:
   - ../vars/test1.yml
  tasks:
   - name: install apache
     yum: name="{{module}}"

   - name: appache start
     systemd: name=httpd state=started enabled=yes

   - name: firewalld start
     systemd: name=firewalld state=started enabled=yes

   - name: firewall-cmd allow port 80
     firewalld: port={{http_port}}/tcp permanent=true state=enabled
     notify: restart firewalld

   - name: copy index.html
     copy:
       src: "{{src_idx_html}}"
       dest: "{{dest_dir}}"
       mode: "{{mode}}"
     notify: restart apache

  handlers:
   - name: restart firewalld
     service: name=firewalld state=restarted

   - name: restart apache
     systemd: name=httpd state=restarted
```

- remote_userディレクティブ
　remote_user ディレクティブを設定することで、クライアントにログインすることが可能となる。
　※設定しなかった場合、Gathering Factsの段階で、Permission deniedのためログインできないというエラーが表示される

```
TASK [Gathering Facts] *********************************************************************************************************************
fatal: [brighton002]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true}
        to retry, use: --limit @/home/ansible/playbooks/tasks/test1.retry
```


- 変数の設定について
  変数を設定する場合、通常 "{{変数名}}"とおこなうが、firewalldタスクでポート番号を指定する場合、"{{http_port}}"とすると、firewalldがダブルクオーテーションつき"80"でポート番号を設定しようして、エラーとなった。なぜかはわかりませんでした。なので、""なしで変数設定しています。

```
TASK [firewall-cmd allow port 80] **********************************************************************************************************
fatal: [brighton002]: FAILED! => {"changed": false, "msg": "ERROR: Exception caught: org.fedoraproject.FirewallD1.Exception: INVALID_PORT: '\"80\"' is invalid port range Permanent operation"}
        to retry, use: --limit @/home/ansible/playbooks/tasks/test1.retry
```


##2. 変数ファイルの作成
varsディレクトリ内に、変数ファイルを作成する。

```
---
module: httpd
http_port: 80
src_idx_html: ../files/index.html
dest_dir: /var/www/html
mode: 0644
```

##3. index.htmlファイルを作成
確認用のindex.htmlファイルを作成する。

```
<h1>
 hello! this is an ansible test!!
</h1>
```

#5.playbookを実行する
##1. playbookの実行
作成したplaybookを実行する!
実行ディレクトリは、/home/ansible/playbooksとする。


`$ ansible-playbook -i hosts ./task/test1.yml`

- 実行結果

```
$ ansible-playbook -i hosts ./tasks/test1.yml

PLAY [web] *************************************************************************************

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

TASK [install apache] **************************************************************************
changed: [brighton002]

TASK [appache start] ***************************************************************************
changed: [brighton002]

TASK [firewalld start] *************************************************************************
changed: [brighton002]

TASK [firewall-cmd allow port 80] **************************************************************
changed: [brighton002]

TASK [copy index.html] *************************************************************************
changed: [brighton002]

RUNNING HANDLER [restart firewalld] ************************************************************
changed: [brighton002]

RUNNING HANDLER [restart apache] ***************************************************************
changed: [brighton002]

PLAY RECAP *************************************************************************************
brighton002                : ok=8    changed=7    unreachable=0    failed=0
```

問題無く成功した事が分かる。

##2. 実行結果の確認

- Apacheの導入確認

```
# rpm -qa | grep httpd
httpd-tools-2.4.6-67.el7.centos.6.x86_64
httpd-2.4.6-67.el7.centos.6.x86_64
```

- Apacheのプロセス確認

```
# ps -ef |grep http
root      6906     1  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    6907  6906  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    6908  6906  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    6909  6906  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    6910  6906  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    6911  6906  0 13:03 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      6925  5169  0 13:05 pts/1    00:00:00 grep --color=auto http
```

- index.htmlファイルの確認

```
# ls -l /var/www/html/index.html
-rw-r--r-- 1 root root 45 Jan 17 13:03 /var/www/html/index.html
# cat /var/www/html/index.html
<h1>
 hello! this is an ansible test!!
</h1>
```

- firewalldの確認

```
# firewall-cmd --list-ports
80/tcp
```

- httpdの起動状況
　現在起動していることと、自動起動の設定がされていることがわかる。　
　※ /usr/lib/systemd/system/httpd.service; enabled 　・・・　enabledのため、自動起動の設定

```
# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2018-01-17 13:11:49 JST; 1min 1s ago
```

- firewalldの起動状況
  現在起動していることと、自動起動の設定がされていることがわかる。　
　※ /usr/lib/systemd/system/firewalld.service; enabled 　・・・　enabledのため、自動起動の設定

```
# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-01-17 13:11:47 JST; 2min 25s ago
```

- 画面の確認
　テストしているネットワークからは、Webアクセスが出来ないため、サーバー上で、curlコマンドを実行し、確認

```
$ curl -l http://XXX.XXX.XXX.XXX
<h1>
 hello! this is an ansible test!!
</h1>
```

#6. 感想
クライアントがrootユーザーでの実行だったので、それほど苦労することなく行う事ができた。
実際自分のお客さんの場合、rootユーザーなのかそうでないのかは環境によるからなんとも言えない。。。
次は、クライアントもrootユーザーではないケースを想定したテストを行ってみたいと思う。