Vagrant+CentOS7でAnsible環境


# 環境
ホストマシン: Windows10
Hypervisor: Vagrant(1.9.8) + Oracle virtualbox(5.1.26)
ゲストマシン: CentOS7.3

# セットアップ

```shell-session
2018/08/07 16:13:25|C:\Vagrant>mkdir CentOS7-Ansible
2018/08/07 16:13:42|C:\Vagrant>cd CentOS7-Ansible
2018/08/07 16:14:26|C:\Vagrant\CentOS7-Ansible>vagrant init centos/7
2018/08/07 16:16:46|C:\Vagrant\CentOS7-Ansible>vagrant up
2018/08/07 16:29:00|C:\Vagrant\CentOS7-Ansible>vagrant ssh
[vagrant@ircsocalld15d5c ~]$
[vagrant@ircsocalld15d5c ~]$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
[vagrant@ircsocalld15d5c ~]$ sudo vi /etc/ssh/sshd_config
[vagrant@ircsocalld15d5c ~]$
[vagrant@ircsocalld15d5c ~]$ sudo diff /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
49c49
< PermitRootLogin yes
---
> #PermitRootLogin yes
77c77
< PasswordAuthentication yes
---
> #PasswordAuthentication yes
[vagrant@ircsocalld15d5c ~]$
```

ここまでやったら、一度Vagrantfileを修正。以下を追記して、boxをリロード。

```shell-session
config.vm.network "forwarded_port", guest: 22, host: 2222
config.ssh.username = 'root'
config.ssh.password = 'vagrant'
config.ssh.insert_key = 'true'
```

```shell-session
2018/08/07 16:41:48|C:\Vagrant\CentOS7-Ansible>vagrant reload
```

これで通常のSSHクライアントで127.0.0.1:2222にアクセスすればログインできる。

## Ansibleのインストール
Ansibleをインストールし、もっとも簡単な例で試す。

```shell-session
[root@ircsocalld15d5c ~]# yum install ansible
# 接続先のホストを定義する。今回は自分自身のみを、webserversというグループとして登録。
[root@ircsocalld15d5c .ssh]# cp /etc/ansible/hosts /etc/ansible/hosts.orig
[root@ircsocalld15d5c .ssh]# vi /etc/ansible/hosts
[root@ircsocalld15d5c .ssh]# diff /etc/ansible/hosts /etc/ansible/hosts.orig
45d44
< [webservers]
< localhost

# 自分自身にコマンドを発行するため、自分の公開鍵を確認する。
# hostsに他のホストを登録した場合は、そのホスト上で以下を実行する。
[root@ircsocalld15d5c ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
a2:04:f6:1b:2a:04:bc:75:a3:2e:ae:7e:5b:0e:49:0b root@ircsocalld15d5c.corp.emc.com
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|.                |
|..o. o           |
|..ooo .          |
| E o+ . S        |
|. +oo+ .         |
|...=o.           |
|....+            |
|+o....           |
+-----------------+
[root@ircsocalld15d5c ~]#
[root@ircsocalld15d5c ~]# ls
anaconda-ks.cfg  original-ks.cfg
[root@ircsocalld15d5c ~]# cd .ssh
[root@ircsocalld15d5c .ssh]# ls
id_rsa  id_rsa.pub  known_hosts
[root@ircsocalld15d5c .ssh]# cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoyZwp/vfMH/ELvX+cG/WnK7pMvF

[root@ircsocalld15d5c .ssh]#

# 先で確認したSSHキーを認証済キーとして登録する
[root@ircsocalld15d5c .ssh]# cat id_rsa.pub > authorized_keys
[root@ircsocalld15d5c .ssh]# cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoyZwp/vfMH/ELvX+cG/WnK7pMvF

[root@ircsocalld15d5c .ssh]#

# ansibleを実行し、対象ホスト(ここではlocalhost)に疎通が取れることを確認する。
# -mは出来合いのモジュールを、-aで通常のコマンドを実行できる。
[root@ircsocalld15d5c .ssh]# ansible all -m ping
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ircsocalld15d5c .ssh]# ansible all -a "echo hello"
localhost | SUCCESS | rc=0 >>
hello

```

モジュールに関して詳しくは以下を参照。
https://docs.ansible.com/ansible/2.5/user_guide/modules.html


# Playbookの活用
https://docs.ansible.com/ansible/2.5/user_guide/playbooks.html

Playbookは1つ以上のplaysという構成要素を持つ。
playとは、ホストのグループに対して、何らかの役割と関連付けるためのもので、ここでいう役割はansibleの世界ではtaskと呼ばれる。基本的にはtaskとはansibleのmoduleを1つ以上呼び出すことに対応する。

taskごとに、それを実行するターゲットのサーバと、使用するユーザを指定する(hosts, remote_user)
以下は、素のCentOS7に、
1. httpdをインストール
2. httpdの状態確認
3. HTTPポートのファイアーウォールを開ける
4. firewalldのリスタート
を行うためのplaybook。

```yml:playbook_test1.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: Install httpd
      yum:
        name: httpd

    - name: Make sure Apache is running
      service:
        name: httpd
        state: started

    - name: Verify Firewall
      firewalld:
        service: http
        permanent: true
        state: enabled

    - name: Restart firewall
      service:
        name: firewalld
        state: restarted
```

最初に、実行するサーバを指定(hostsというパラメータにwebserversとしてい。これは/etc/ansible/hostsで定義)、
次にサーバ上でどのユーザを使うかを指定(remote_user)、
最後に、tasksの中で4つのタスク(モジュール)を実行している。
以下が実行結果。

```shell-session
[root@ircsconnoj14d1c ~]# ansible-playbook playbook_test1.yml

PLAY [webservers] *************************************************************************************************************************

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

TASK [Install httpd] **********************************************************************************************************************
changed: [localhost]

TASK [Make sure Apache is running] ********************************************************************************************************
changed: [localhost]

TASK [Verify Firewall] ********************************************************************************************************************
changed: [localhost]

TASK [Restart firewall] *******************************************************************************************************************
changed: [localhost]

PLAY RECAP ********************************************************************************************************************************
localhost                  : ok=5    changed=4    unreachable=0    failed=0

```

これはOracleVM上の仮想マシンなので、Vagrantファイルを編集して、外部からアクセスできるようにする。以下を追記してvagrant reload。
`config.vm.network "forwarded_port", guest: 80, host: 8080`

ホストマシンにて、http://127.0.0.1:8080 にアクセスすると、Apacheのページが表示される。表示されない場合は、httpのサービスが上がっていない場合があるので、もう一度Playbookを実行する。

```shell-session
[root@ircsconnoj14d1c ~]# ansible-playbook playbook_test1.yml

PLAY [webservers] ******************************************************************************************************************************************************

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

TASK [Install httpd] ***************************************************************************************************************************************************
ok: [localhost]

TASK [Make sure Apache is running] *************************************************************************************************************************************
changed: [localhost]

TASK [Verify Firewall] *************************************************************************************************************************************************
ok: [localhost]

TASK [Restart firewall] ************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP *************************************************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0

[root@ircsconnoj14d1c ~]#
[root@ircsconnoj14d1c ~]# ss -ant | grep 80
LISTEN     0      128         :::80                      :::*
```

先ほどの出力と比較すると、changedが2になっていることがわかる。これは最初のhttpdのインストールなどは一度だけしか実行されないため。このように、1つのPlaybookは、最終的なあるべき姿を定義しているため、複数回実行しても状態が変わらないというのが、Ansibleの冪等性(べきとうせい)という特徴です。
ちなみにもう一度実行すると、httpdはすでにstartedなので、changedは最後の1つだけになります。最後の1つはrestartedにするというものなので、必ず実行されます。