Ansible入門② プレイブックの基礎

前回はインストールからansibleコマンドとansible-playbookコマンドの実行まで書きました。
[Ansible入門① インストールからansible-playbookコマンドの実行](https://qiita.com/eizin/items/5c2999f53c0ea399c449)

#プレイブックの構成
プレイブックは、管理対象サーバーに対して実行したい処理の流れを記述します。
厳密にはプレイ(play)と呼ばれる処理の塊を、複数並べたものと言えます。
プレイには、ターゲットノードの特定(hosts)とタスクの定義(tasks)が必須です。
複雑な処理を実行するために、補助的要素として、
実行制御(handlers)と動的な値(vars)があります。
プレイは、「Targets」「Tasks」「Handlers」「Vars」の４つのセクションからなります。

```
- hosts: all
  vars:
     ntp_conf: /tmp/ntp.conf
  tasks:
     - name: Install NTP
        yum: name=ntp state=installed
     - name: Config NTP
       template: src=ntp.conf.j2 dest=/etc/ntp.conf
       notify:
         - Restart NTP
     - name: Enable NTP
        service: name=ntp state=running enabled=yes
  handlers:
     - name: Restart NTP
       service: name=ntp state=restarted
- hosts: webservers
  tasks:
     - name: Install HTTP
       yum: name=httpd state=installed
```



#Targets セクション
```
- hosts: all
  become: yes
  become_user: ansible
```
Targetsセクションでは管理対象サーバーへの接続に関する設定を行います。
「hosts」キーの値としては、特定のサーバーやグループ等の指定が可能です。
「hosts」キーの他に下記のような設定等も可能です。

| キー | 値 | 説明 |
|:-----------|------------:|:------------:|
| gather_facts | true/false | ターゲットノードの情報取得を行う|
| connection   | Connectionプラグイン| 接続方法の変更を行う|
| remote_user  | ユーザー名| 接続ユーザーの指定|
| port         | ポート番号| 接続ポートの指定|
| become       | true/false| 接続ユーザー以外で処理を行う。|
| become_user  | ユーザー名| ターゲットノードで処理を行うユーザー|
| become_method| sudo/su/pbrun etc| ターゲットノードで処理を行うコマンドの指定|

#Tasks セクション
```
tasks:
   - name: Install NTP
      yum: name=ntp state=installed
   - name: Config NTP
     template: src=vhost.conf.j2 dest=/etc/httpd/con
     notify:
       - Restart NTP
   - name: Enable NTP
      service: name=ntp state=running enabled=yes
```
実行した処理の内容をシーケンスリストで定義します。
シーケンスリストの中にはマッピング形式で、Keyにモジュール名、
値に各モジュールのオプションを定義できます。
この例では、yumモジュール、templateモジュール、serviceモジュールを
上から順番に実行するようになっています。
上から記述した順番に実行していることが非常に重要です。
モジュールによって与えるオプションは異なります。
モジュールの利用方法について記述しているサイトやansible-docコマンドで確認します。
##ansible-doc
```
(一部抜粋)
[root@localhost ~]# ansible-doc yum
> YUM    (/usr/lib/python2.7/site-packages/ansible/modules/packaging/os/yum.py)

        Installs, upgrade, downgrades, removes, and lists packages and
        groups with the `yum' package manager. This module only works
        on Python 2. If you require Python 3 support see the [dnf]
        module.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

- allow_downgrade
        Specify if the named package and version is allowed to
        downgrade a maybe already installed higher version of that
        package. Note that setting allow_downgrade=True can make this
        module behave in a non-idempotent way. The task could end up
        with a set of packages that does not match the complete list
        of specified packages to install (because dependencies between
        the downgraded package and others can cause changes to the
        packages which were in the earlier transaction).
        [Default: no]
        type: bool
        version_added: 2.4
:
```

[Module Index](https://docs.ansible.com/ansible/2.9_ja/modules/modules_by_category.html)

#Handlers セクション
```
tasks:
  - name: Config HTTP
    template:
      src: httpd.conf.j2
      dest: /etc/apache/httpd.conf
    notify:
      - Restart HTTP
 handlers:
  - name: Restart HTTP
    service:
      name: httpd
      state: restarted
```
Handlersセクションは、Tasksセクションと同様に、実行した処理の内容を
シーケンスリストで定義します。
タスクの定義で、「notify」を指定し、タスクの結果で「changed」となった場合にのみ、
処理を実行したい場合に利用します。
上記の例の場合、httpd(Apache)の設定ファイルとしテンプレートファイル(httpd.conf.j2)を利用し、httpd.confを作成します。
このタスクの結果が「changed」となり、「notify」で指定している「Restart HTTP」をもとに、
handlersセクションの「name」が「Restart HTTP」となっているものを実行します。
これは、httpd(Apache)の設定ファイルを変更した時、設定変更のために
httpd(Apache)を再起動するための定義になります。

##listenによる複数のhandlerタスクの利用
```
tasks:
  - name: Config HTTP
    template:
      src: httpd.conf.j2
      dest: /etc/apache/httpd.conf
    notify:
      - Restart HTTP
 handlers:
  - name: stop HTTP
    service:
      name: httpd
      state: stopped
    listen: Restart HTTP
  - name: start HTTP
    service:
      name: httpd
      state: started
    listen: Restart HTTP
```
Ansibleバージョン2.2以降では、listen機能が追加されました。
これは、「notify」で指定している「Restart HTTP」をもとに、
handlersセクションの「listen」が「Restart HTTP」となっているものを実行します。

#Vars セクション
```
vars:
   ntp_conf: /tmp/ntp.conf
```
タスクを効率化するための変数を定義するセクションです。
このセクションで定義する変数は、プレイ変数と呼ばれ、下記の3種類の利用方法があります。
・vars
・vars_files
・vars_prompt

##vars
vars内での変数を設定します。

```
vars:
  apache_log_dir: /var/log/httpd/logs
  user_id: 600
  group_id: 600
```

##vars_files
変数を定義した外部のYAMLファイルを複数読み込みます。
プレイブックとは別の外部のファイルに変数を定義して、処理によって定義読み込み利用します。
外部の変数を定義したファイルは、ansible-playbookコマンドを実行する時点で
存在している必要があります。

```
vars_files:
  - /vars/prod_vars.yml
```

``` /vars/prod_vars.yml
  apache_log_dir: /var/log/httpd/logs
  user_id: 600
  group_id: 600
```

##vars_prompt
変数を対話的にユーザーに問い合わせることができます。

```
vars_prompt
  - name: "Password"
    prompt: "Please enter your password."
    private: true
    confirm: true
```

###vars_promptで利用できる設定項目
| 項目 | 値 | 説明 |
|:-----------|------------:|:------------:|
| name | </文字列> | 変数名として利用します|
| prompt | </文字列> | 入力時のプロンプトに表示する文字列|
| private | true/false | trueは入力値画面に表示されない|
| default | </変数値> | デフォルト値|
| encrypt | 暗号化アルゴリズム(sha256_crpt等) | 入力値をハッシュして奥暗号化アルゴリズム|
| confirm | true/false | trueの場合は入力値を再入力|
| salt_size | </数値> | 指定した文字数分の”SALTJwoランダムに生成する|
| unsafe | true/false | trueは入力値として{％のようなテンプレートエラーを引きおこす文字列MO許容する|

#まとめで実行に必要な各種ファイル
```
/etc/ansible
├── ansible2-playbook.yml
├── ansible.cfg
├── template
│   └── conf
│       └── httpd
│           └── vhost.conf.j2
└── test_inventory
```
```:/etc/ansible/test_inventory
[test_servers]
192.168.11.21
```
```:/etc/ansible/template/conf/httpd/vhost.conf.j2
<VirtualHost *:80>
  ServerName {{ hostname }}
  DocumentRoot {{ document_root }}
</VirtualHost>
```
```:/etc/ansible/ansible2-playbook.yml
- hosts: test_servers
  vars:
    hostname: example.com
    document_root: /var/www/example.com/htdocs
  tasks:
  - name: Install httpd
    yum: name=httpd state=installed
    notify:
      - Enable service httpd
  - name: Config httpd
    template:
      src: template/conf/httpd/vhost.conf.j2
      dest: /etc/httpd/conf.d/virtualhost.conf
    notify:
      - Restart HTTP
  handlers:
  - name: Enable service httpd
    systemd:
      name: httpd
      enabled: yes
      masked: no
  - name: stop HTTP
    service:
      name: httpd
      state: stopped
    listen: Restart HTTP
  - name: start HTTP
    service:
      name: httpd
      state: started
    listen: Restart HTTP
```
#まとめの実行結果
```
[root@localhost ansible]# ansible-playbook -i ./test_inventory ./ansible2-playbook.yml

PLAY [test_servers] *************************************************************************************************************************

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

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

TASK [Config httpd] *************************************************************************************************************************
changed: [192.168.11.21]

RUNNING HANDLER [Enable service httpd] ******************************************************************************************************
changed: [192.168.11.21]

RUNNING HANDLER [stop HTTP] *****************************************************************************************************************
ok: [192.168.11.21]

RUNNING HANDLER [start HTTP] ****************************************************************************************************************
changed: [192.168.11.21]

PLAY RECAP **********************************************************************************************************************************
192.168.11.21              : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```