Ansible勉強メモ(CentOS7セットアップ #1)

Ansible 勉強メモ (CentOS7セットアップ #1)
========================================


はじめに
------------
Ansible。世間の波からずいぶん遅ればせながら、ちょっと触ってみました。
CentOS 7 の初期設定を行うものを調べつつ作ってみたので、内容を記載したいと思います。

有識者の方、コメントなどあれば頂けますと嬉しいです。


Ansible って？
------------------
リモートサーバに ssh を利用してコマンドを発行する、自動化ツールの一種という理解でいます。
Chef, Puppet の仲間のように書かれることが多いようですが、エージェントレスなのがいいですね。

対象ホスト側にエージェントやパッケージを入れなくてよいので、環境を汚さず
また ssh 経由なので、人間が手でサーバの設定をするのと経路は近しいように思うので、感覚的にわかり良いような気がしました。

流れとしては

* Ansible サーバを立てる
* 構築対象サーバと ssh 疎通させる
* 構築内容を Ansible サーバ上に設定ファイルとして作成する
* 設定ファイルの内容を Ansible サーバ上で実行する
* Ansible が 構築対象サーバへ ssh 接続を繰り返し設定ファイルの内容の操作を順次行う

というような感じのようです。



Ansible サーバを立てる
--------------------------
構築対象サーバとは別に、CentOS7 のサーバを立て、そこへ Ansible をインストールしてみます。
実際は、踏み台サーバの様な位置づけの場所に設定するかと思いますが
今回はPCの中の仮想環境に CentOS7 をインストールし、そこへ構築していきます。

[Ansibleサーバ環境]

``` 
OS           : CentOS Linux release 7.3.1611 (Core)
(SELinux, Firewalld はとりあえず停止・無効化)
``` 
epel リポジトリに ansible があるので、epel リポジトリを追加して、yum インストールします。

[epel インストール]

```
yum install epel-release

sed -i "s/enabled=1/enabled=0/g" /etc/yum.repos.d/epel.repo
```

[ansible インストール]

```
yum install ansible --enablerepo=epel

ansible --version
- - - - - 
ansible 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
- - - - - 
```

入りました。



構築対象サーバと ssh 疎通させる
-----------------------------------
構築対象のサーバとは ssh を利用して通信させます。
今回はサーバ間で root ユーザが鍵認証で ssh できるようにしておきましょう。

まずは構築対象となるサーバを用意します。
今回は ESXi 上に "CentOS-7-x86_64-DVD-1503-01.iso" メディアをインストールした
CentOS7 サーバを対象とします。

[構築対象サーバ環境]

``` 
OS                 : CentOS7
IP                 : 10.210.104.24
DNS                : 8.8.8.8
``` 


Ansible サーバで ssh 鍵を生成し、鍵一式を対象サーバへ送り
ノンパスで ssh 接続できるようにします。

``` 
ssh-keygen

mv /root/.ssh/{id_rsa.pub,authorized_keys}

scp -r /root/.ssh root@10.210.104.24:/root/

※ 纏めて scp した後 id_rsa は構築対象サーバから削除しておきます。
``` 

これで、Ansible サーバから構築対象サーバへ接続できるようになりました。



構築内容を Ansible サーバ上に設定ファイルとして作成する (作成する設定ファイルについて)
------------------------------------------------------------------------------------------
ここから Ansible サーバ上で、設定ファイルを作成していきます。
まずはどのようなファイルが必要か、ざっと確認したいと思います。

インストール直後のディレクトリは、以下のようになっています。

[ディレクトリツリー]

```
/etc/ansible/
        |------ ansible.cfg      ## Ansible 自体の設定ファイル
        |------ hosts            ## Ansible で管理するリモートホストの一覧
        '------ roles/           ## Ansible に実行させる yaml 形式の設定ファイル置き場(インストール直後は空)
```

ここから最終的に、以下のようにファイルを作っていきたいと思います。

```
/etc/ansible/
        |------ ansible.cfg
        |------ hosts_org        ## デフォルトのものは保持しておく
        |------ hosts
        '------ roles/
                   |------ files/                              ## 構築対象のリモートホストに配置したいファイルを置く場所
                   |         |------ chrony.conf 
                   |         |------ ifcfg-eth0 
                   |         '------ syslog
                   |------ handlers/                           ## 構築中特定の状態になった時に呼び出される処理の設定ファイル
                   |         |------ reboot_os.yaml
                   |         |------ reload_chrony_config.yaml
                   |         |------ reload_postfix_config.yaml
                   |         |------ reload_chrony_config.yaml
                   |         |------ reload_rsyslog_config.yaml
                   |         '------ reload_sshd_config.yaml
                   |------ setup_CentOS7.yaml                  ## 実行する設定ファイル (playbook) の大本となるファイル
                   '------ tasks/                              ## 実行する処理を大本のファイルから切り出したもの
                             |------ disable_unnecessary_daemons.yaml
                             |------ enable_necessary_daemons.yaml
                             |------ disable_ipv6.yaml
                             |------ disable_selinux.yaml
                             |------ install_and_setup_chrony.yaml
                             |------ install_and_setup_epel.yaml
                             |------ install_utill_packages.yaml
                             |------ setup_eth0_interface.yaml
                             |------ setup_kdump.yaml
                             |------ setup_logrotate.yaml
                             |------ setup_postfix.yaml
                             |------ setup_rsyslog.yaml
                             |------ setup_sshd.yaml
                             '------ setup_unix_users.yaml
```



構築内容を Ansible サーバ上に設定ファイルとして作成する (ちょっと寄り道)
----------------------------------------------------------------------------
まず Ansible サーバ自身に設定変更を行うような設定ファイルを書いて、ファイル書式や実行の流れを確認したいと思います。
( リモートホストだけではなく Ansible サーバ自身の設定変更もできます。と言っても "ssh root@localhost" と同義ですが。)

localhost への ssh は、鍵ファイル作成段階でノンパスになっていますので、Ansible の設定から始めます。
まずは、 /etc/ansible/hosts に管理対象のホストを書きます。( 本項目では localhost )

``` 
## デフォルトのファイルを保持
cp -av /etc/ansible/hosts{,_org}

## デフォルトの記載を消して空にする
:> /etc/ansible/hosts

## 空っぽのファイルに新しく記入( とりあえず "localhost" と書いておけば今回は動きます )
vi /etc/ansible/hosts
-追記 - - 
loaclhost
- - - - - 
``` 

ansible コマンド経由で localhost へ接続できるか確認

```
## ping モジュールを使って、localhost へ疎通確認
ansible -m ping localhost
```
```
## SUCCESS と出ればとりあえず OK
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

これで管理対象として localhost が設定されました。

次に実際に実行する処理内容の設定ファイルを作りますが、このファイルは playbook と言うそうです。
Chef で言うところの cookbook にあたるようですね。

実際にファイルを作る前に、何をやるのか決めましょう。
今回は、以下のことを localhost に行いたいと思います。

* hostname を "ansible_test001.localdomain" に変更する。
* firawalld を 停止し、自動起動も off にする。
* /etc/hosts に ipv6 の設定 ":1" の行があったらその行を削除する。

playbook の書式は以下のようになります。


![無題001.png](https://qiita-image-store.s3.amazonaws.com/0/164294/2b536427-5df5-11c2-c0b9-5bf0671c4890.png)




先ほど決めた "やること" に合うように、設定内容を検討します。

> * hostname を "ansible_test001.localdomain" に変更する。

サーバの hostname を設定するモジュール "hostname" を使い
"name" パラメータに今回設定したい "ansible_test001.localdomain" を渡します。
また、タスクの名前は "Change hostname" とします。

``` 
    - name: Change hostname
      hostname: name=ansible_test001.localdomain

``` 

> * firawalld を 停止し、自動起動も off にする。

サーバのサービスを制御するモジュール "servicec" を使い
"name" パラメータへ制御したいサービス名 "firewalld" を渡し
サービスは止まっていてほしいので "state" は "stopped"、また、起動時には停止していてほしいので "enabled" に "no" を設定します。
また、タスクの名前は "Turn off firewalld service" とします。

``` 
    - name: Turn off firewalld service
      service: name=firewalld state=stopped enabled=no
``` 


> * /etc/hosts に ipv6 の設定 ":1" の行があったらその行をコメントアウトする。

書き換える前にファイルのバックアップを取りたいので "shell" モジュールを使い
cp コマンドをそのまま実行します。

``` 
    - name: Keep default /etc/hosts
      shell: cp -a /etc/hosts{,_org}
``` 

そのあとで、該当行の削除を行います。
ファイルの書き換えを行うモジュール "replace" を使い
編集したいファイルパスを "dest" に渡し、マッチさせる正規表現を "regexp" に渡します。
マッチした部分は "replace" に渡された文字列に置き換わります。

``` 
    - name: CommentOut IPv6 row at /etc/hosts
      replace: dest=/etc/hosts regexp='^::1' replace='#::1'
``` 

[参考] 
* [hostname - Manage hostname.](http://docs.ansible.com/ansible/hostname_module.html)
* [service - Manage services.](http://docs.ansible.com/ansible/service_module.html)
* [shell - Execute commands in nodes.](http://docs.ansible.com/ansible/shell_module.html)
* [replace - Replace all instances of a particular string in a ...](http://docs.ansible.com/ansible/replace_module.html)

では、上の内容で playbook を /etc/ansible/role の下に作ります。

```
vi /etc/ansible/roles/setup_localhost.yaml
```

[setup_localhost.yaml]

```
---
- hosts: localhost
  tasks:
    - name: Change hostname
      hostname: name=ansible_test001.localdomain

    - name: Turn off firewalld service
      service: name=firewalld state=stopped enabled=no

    - name: Keep default /etc/hosts
      shell: cp -a /etc/hosts{,_org}

    - name: CommentOut IPv6 row at /etc/hosts
      replace: dest=/etc/hosts regexp='^::1' replace='#::1'
```

これをコマンドラインから実行してみましょう。

```
ansible-playbook /etc/ansible/roles/setup_localhost.yaml
```

```
PLAY [localhost] ***************************************************************

PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [Change hostname] *********************************************************
changed: [localhost]

TASK [Turn off firewalld service] **********************************************
ok: [localhost]

TASK [Keep default /etc/hosts] *************************************************
changed: [localhost]

TASK [CommentOut IPv6 row at /etc/hosts] *******************************************
changed: [localhost]

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

上のような結果になりました。設定した処理の結果部分は

``` 
TASK [Change hostname] *********************************************************
changed: [localhost]

TASK [Turn off firewalld service] **********************************************
ok: [localhost]

TASK [Keep default /etc/hosts] *************************************************
changed: [localhost]

TASK [CommentOut IPv6 row at /etc/hosts] *******************************************
changed: [localhost]
``` 

↑です。 "changed:" は設定した TASK を実行し、サーバに変更が行われた事を示します。
"ok:" は設定した TASK の状態に、すでになっている場合に出力されるようです。

firewalld を無効するタスク "Turn off firewalld service" が "ok:" になっています。
そういえば、この Ansible サーバでは firewalld は停止済みでした。

一度ログアウトして ssh し直し、設定内容を確認すると

``` 
[root@ansible_test001 ~]# hostname
ansible_test001.localdomain

[root@ansible_test001 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

[root@ansible_test001 ~]# systemctl list-unit-files | grep "firewalld"
firewalld.service                             disabled

[root@ansible_test001 ~]# diff /etc/hosts{,_org}
2c2
<
---
> ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
``` 

設定どおり、変更が行われた様子です。
それでは、次はリモートホスト用の playbook を検討してみます。