Ansible備忘録

#Ansibleとは
* 構成管理ツールの一つ。
* sshなどのプロトコルを用いて他の機器の設定作業を自動化できる。（エージェントレス）

#Ansibleを使うと
* たくさんの機器に対してヒューマンエラーを起こさずに設定を入れることができる。
* 同じコマンドを複数回たたいても結果は収束する。（冪等性）

##インストール・環境の用意
* 基本的には`Python`のパッケージ管理ツール`pip`や`Anaconda`などでインストールをする。
* `Linux`の`dnf`や`yum`などでも可能。
* `Python`の仮想環境を用いて`Ansible`を使用する環境を事前に用意してそこに`Ansible`を入れるのが望ましい。

#Ansibleの動かし方
* Python上で動く（2系・3系どちらでも可）
* 対象とする機器を`inventory`ファイルに記述する
* Playbookと呼ばれる`yaml`ファイルに設定内容を記述して`Ansible`はそれをもとに設定を行う。
* `inventory`ファイルとPlaybookを合わせて動かすことで扱いやすくなる。
* Playbookは`vars`, `roles`と細分化して再利用しやすくすることが可能。
* Ansible単体でもアドホックコマンドで簡単な操作が可能。

```shell:アドホックコマンド例
root@myansible:/myansible/practice# ansible -i inventory.ini all  -m ping
ubuntu20 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
centos7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
```


##inventoryファイルを作る
* `Ansible`で扱う対象（ホスト）について記述する。
* これまでの`host`ファイルにあたるもの。
* グループ化をしてホストを論理的に集約することが可能。
* Playbookで使用する変数を記述することが可能。この変数はグループごとに作ることもできる。

```yaml:inventoryファイルの記述例
#Tokyoグループ
[Tokyo]
192.168.1.1
192.168.2.1

#Osakaグループ
[Osaka]
192.168.10.1
192.168.20.1

#Tokyoグループ変数
[Tokyo:vars]
http_port=8888
ansible_user=ansible_tokyo

#Osakaグループ変数
[Osaka]
ansible_user=ansible_osaka

#共通変数
[all:vars]
ansible_password=password
```

##Playbookを書く
* `yaml`形式で記述する。
* `inventory`ファイルで記述したホストに対して行う動作を記述します。
* `host`に対象のホストを記述。inventoryファイルのグループ名を使える。
* `tasks`の下にモジュールを使って動作を記述していく。
* `tasks`については条件分岐や繰り返しにも対応している。
* `host`-`tasks`で紐づき、`host`が１単位の構成となる。

```yaml:Playbookの例
---
- hosts: Tokyo
  become: yes　#権限昇格するかどうか
  tasks:
    - name: Create New file
      file:
        path: /root/foo.conf
        state: touch
        mode: 0644

- hosts: Osaka
  become: yes
  tasks:
    - name: Create file
      file:
        path: /root/hoge
        state: touch
        mode: 0644

    - name: Copy file
      copy:
        src: /root/hoge
        dest: /tmp/hoge
```

##Playbookを動かす。
`ansible-playbook -i {inventory} {playbook}`で`Ansible`を動かしてPlaybookに記述された動きを、対象に流すことができる。
ここで流したPlaybookは上記の例とは異なるもの。
ここでAnsibleを実行した環境はAWSのEC2内でDockerコンテナを建てて行っている。

```shell:Playbookの実行
# ansible-playbook -i inventory.ini playbook.yml

PLAY [Tokyo] *******************************************************************************************************************

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

TASK [Create New file] *********************************************************************************************************
changed: [centos7]

PLAY [Osaka] *******************************************************************************************************************

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

TASK [Create file] *************************************************************************************************************
changed: [ubuntu20]

TASK [Copy file] ***************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: If you are using a module and expect the file to exist on the remote, see the remote_src option
fatal: [ubuntu20]: FAILED! => {"changed": false, "msg": "Could not find or access '/root/hoge' on the Ansible Controller.\nIf you are using a module and expect the file to exist on the remote, see the remote_src option"}

PLAY RECAP *********************************************************************************************************************
centos7                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ubuntu20                   : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
```
成功したかどうかは最後の`PLAY RECAP`でまとめて参照できる。

Ansibleは冪等性を担保するため一度Playbookによる操作が行われた対象機器に対して再度同じPlaybookを流しても変更は加えられず、okのステータスのみ得られる。

* さらに`role`を活用することで`tasks`の部分を個別のファイルで管理できる。
* それによりPlaybookで対象や条件での動作の振り分けを行い、詳細な動きは`role`ファイルで管理することで、再利用・保守がしやすい状態をつくることができる。

#Ansibleの有効活用のために
* その作業は本当に自動化するときにそれ相応の利益があるかをよく考える。
* ものによってはAnsibleを使わなくてもよいことをわざわざAnsibleでやることにもつながってしまう。

#Ansibleをすぐ始めたいときに
最近はYoutubeにいい動画があふれているのでそれらをチェックするのが一番早いかも。
[you need to learn Ansible RIGHT NOW!! (Linux Automation)](https://youtu.be/5hycyr-8EKs)
[つまずきながら進める Ansible 【Part1】 #tekunabe](https://youtu.be/fbRuSht5gqg)


<details><summary>参考文献</summary>
・ [Ansible公式ドキュメント(ver2.9)](https://docs.ansible.com/ansible/2.9/index.html)
・ [Ansibleのinventory入門](https://dev.classmethod.jp/articles/inventory/)
・ [Docker内でAnsibleの勉強](https://github.com/comefigo/docker-ansible-practice)
</details>