Ansibleとは何か　構成管理ツールの目的〜Ansible導入まで最速で理解する

# はじめに
本記事は、構成管理ツールの目的〜Ansible導入まで最速で理解することを目標に、インフラエンジニアの観点でまとめました。

なお、文明が遅れているSI業界の片隅のシステムにおけるインフラ構築は大体こんな感じです。

【現状】

1. 設計書を基に、パラメータシート（Excel）及び構築手順書（ExcelまたはWord）の作成
2. 構築手順書を見ながら、構築作業の実施（※1）
3. 運用開始後、設定変更が発生した場合は、パラメータシート（Excel）に変更履歴を記入

（※1）SI業界に構成管理ツールは存在しない。（同じSIでも使っているところはあると思うが、行政のようなレガシーシステムでは皆無）せいぜいテラタームでブロードキャストして、実行するコマンドを書いたスクリプト動かすだけ。あとは、confファイルなど必要資材は、WinSCPで送ったりする。

【問題点】

- ドキュメント作成に時間がかかる（構築手順やパラメータの妥当性確認及び、表紙、改版履歴、誤字脱字、表記ゆれ、印刷設定、PDFでの見切れチェック等体裁を整えるための作業に時間がかかる）
- 大量構築時に、同じことの繰り返しの場合、指数法則的に時間がかかる
- 構築時に手入力した場合のオペミス発生のリスク
- ドキュメントと実機の整合性確保（運用開始後に実機の設定値を変更したら、全てのドキュメントに横展開が必要（※2））

（※2）SI業界はドキュメントありきで考えるため、サーバの設定を確認する場合はまず、分散されたドキュメントの情報を確認する。もし、ドキュメントの設定値に不備などがあった際はサーバの設定を確認する。よって、ドキュメントが間違っていてそれで品質を疑われた場合は、サーバの設定全台チェック何てよくある話。つまりは、作るだけ作って、きちんと整備しないと構築から運用に係る全ての人を不幸に落とし入れてしまう。

Web業界の人からしたら、何のことを言っているかわからないと思いますが、これはフィクションではなく、SI業界の悲しい現実です。DevOpsやデジタルトランスフォーメーションなんて、言葉は存在しません。

サーバ操作している時間より、ExcelまたはWordと戦っている時間の方が圧倒的に長いのが実情です。

## 構成管理ツール
### 構成管理ツールの目的
構成管理ツールの目的について考えます。

インフラ管理者にとって最大の目的は、効率化による時間の短縮です。
これは、Web業界もSI業界も変わりません。
そして、構成管理ツールの導入により、以下の恩恵を受けることができます。

![Ansible_image.png](https://qiita-image-store.s3.amazonaws.com/0/221759/18651966-e257-6b1d-70b3-efd69016316e.png)

- インフラ構築として、特にOS及びMWに係る作業時間が、劇的に短縮される
- ドキュメントに対する文化の革命をもたらし、ドキュメントと言われていたものを駆逐することで、新たな価値を提供するための時間が手に入る（構成管理ツールの設定ファイルがドキュメントの役割を持つ）
- 構成管理ツールの設定ファイルに、コメントを入れることで、変更履歴が管理できる
- 構成管理ツールの設定ファイルを流用することで、一定の品質確保や属人化の排除により、誰が作っても同じサーバを構築することができる

**従って、構成管理ツールを導入することにより、それ自体がドキュメント及び手順書的な意味合いを持つことになります。逆に、システム構成が複雑になり、ブラックボックス化した場合、塩漬される可能性があります。**

よって、構成管理ツールの目的を明確にし、メリットや運用後のフローを理解し予測できていないと、その恩恵を最大限に発揮できません。

また、構成管理ツールを導入することにより、パラメーターシートや手順書等のドキュメントは不要と思われますが、BCPを考慮して、業務を継続するための運用等に係るドキュメントは文書化を検討すべきです。例として運用が属人化して、その人がいなくなった場合を考えてみましょう。明文化して職人の技能伝達が行われないのであれば、ドキュメントを整備して、インシデント発生時のリスクを抑えるべきです。

**もっと言うと、ミッションクリティカルなインシデント発生時に、人間が冷静に物事を判断してオペレーションを行うことができるか。業務影響を最大限に考慮して、止めてはいけないシステムを作るためには、運用に係るドキュメントの文書化は必要であると考えます。**

**SI業界で唯一、評価すべきところはその点考慮して設計しているところです。**

### 構成管理ツールの種類
Ansible以外の構成管理ツールは、以下のようなツールがあります。
なお、昨今でいう構成管理ツールと言われる自動インストールを行ってくれるものと、クローニングは区別しています。（Norton GhostやClonezilla等）

| 構成管理ツール       |概要 | 
|:-----------------|:------------------|
| Kickstart             | 自動インストール（RHEL系）             |
| Preseed             | 自動インストール（Debian GNU/Linux系）             |
| Puppet             | Rubyで記述されたサーバ、クライアント型アプリケーション            |
| FAI             | 自動インストール（Debian GNU/Linux系）             |
| Chef             | Rubyで記述されたサーバ、クライアント型アプリケーション            |

## Ansible概要
Ansibleは、RedHat社が開発するオープンソースの構成管理ツールになります。
OSSで提供されているコミュニティ版とRedHatサポートのエンタープライズ版の2種類があり、エンタープライズ版のAnsible Towerでは、WebブラウザによるGUIでの操作が可能になります。

Ansibleの特徴は、ITインフラに係る様々な作業を自動化できます。
Ansibleは構成管理ツールと言われたり、自動化ソフトとも言われていますが、本記事では構成管理ツールとして扱います。

![スクリーンショット 2019-01-21 00.59.43.png](https://qiita-image-store.s3.amazonaws.com/0/221759/8300a7bc-0dae-a666-a0b4-c31d24ff8d73.png)

### アーキテクチャ
![Ansible_image2.png](https://qiita-image-store.s3.amazonaws.com/0/221759/fa4a8305-45cf-7e7a-9da8-371a01a1eaa0.png)

Ansibleは**冪等性**を担保するように作られています。
管理対象サーバに対して「何を実行するのか」ではなく、「どのような状態があるべき姿なのか」ということを記述します。

- **エージェントレス**なため、基本的にPythonが使用可能でSSHの通信ができればよい
- Ansibleにおける一連の処理はPlaybookという単位にまとめられ、Playbookは**YAML**形式で記述される
- **モジュール**により、AWS/Azure/GCP/OpenStackをはじめとするクラウド関連モジュール等の拡張が可能

- 対応OS
    - Red Hat Enterprise Linux
    - CentOS
    - Debian
    - Ubuntu
    - FreeBSD
    - Mac OS X
    - ネットワーク機器（Cisco IOS等）

### YAML
YAMLは、JSONの様なデータフォーマットの一つです。
インデントを使い階層構造を表現し、オブジェクトを文字列にシリアライズ（直列化）して書きます。

### メリット/デメリット
#### メリット
- Chef等他の構成管理ツールでは、独自記述言語を採用しているため学習コストが高いが、AnsibleではYAMLを使用しているので導入が容易
- モジュールによる拡張がしやすい。利用できるモジュールは[公式サイト](https://docs.ansible.com/ansible/latest/modules/modules_by_category.html)で確認できる
- 既存の資産（シェルスクリプト）も流用できるので、スモールスタートできる

#### デメリット
- 他の構成管理ツールと比較すると、複雑な処理を表現しにくいという面があり、「多段の条件分岐」「反復構造」を記述する場合には、複雑な表記になりやすい

## Ansible導入
Ansibleは各種Linuxディストリビューションでインストールできます。
本記事では、macOSとLinux（Centos）の導入手順について記載しています。

### macOS
macOSの場合、前提条件としてHomebrewがインストールされている必要があります。
Homebrewで以下のコマンドを実行します。

`brew install ansible`

インストール後、ansibleコマンドで動作確認します。
以下の場合、**-m**でモジュールを指定し、**-a**でモジュールのパラメータを指定しています。
なお、shellモジュールは名前の通りに/bin/shでパラメータで与えられたコマンドを実行します。

`ansible localhost -m shell -a 'hostname'`

```terminal
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'

localhost | CHANGED | rc=0 >>
ホスト名
```

初回、インベントリファイルがない場合は警告が表示されます。
そのため、インベントリファイルとして、「/etc/ansible/hosts」を作成します。

`sudo mkdir /etc/ansible/`
`cd /etc/ansible/`
`sudo vi hosts`

インベントリファイルは、[文字列]でグループを定義し、その下に管理対象のホストをIPアドレスかホスト名で記述し、その後ろにオプションを記述します。

以下の場合は、[localhost]はansibleを導入したmac自身で、[web]はmacのVirtualboxで作成した仮想マシンをさします。なお、ansible_connectionのオプションは、対象ホストへ接続する際の接続方法に関する情報を与えます。

- /etc/ansible/hosts

```text
[localhost]
127.0.0.1 ansible_connection=local

[web]
192.168.N.N
```

再度、実行すると警告が消えます。

```console
127.0.0.1 | CHANGED | rc=0 >>
ホスト名
```

次に、playbookを作成します。
playbookはYAML形式で記述するため、インデントに注意します。

以下は検証として、macのVirtualboxで作成した仮想マシンに、apacheをインストールする例です。

`sudo vi playbook.yml`

- playbook.yml

```yaml
- hosts: web
  tasks:
    - name: install package
      yum:
        name: httpd
        state: latest

    - name: start service
      systemd:
        name: httpd
        state: started
        enabled: yes
```

ansible-playbookコマンドを実行します。
**-i**でインベントリを記述したファイルを指定し、**-u**でユーザ、**-k**でコマンド実行時にパスワード入力プロンプトを起動します。

`ansible-playbook -i hosts -u root -k playbook.yml `

```console
SSH password: 

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

TASK [Gathering Facts] ***************************************************************************************************
ok: [192.168.N.N]

TASK [install package] ***************************************************************************************************
changed: [192.168.N.N]

PLAY RECAP ***************************************************************************************************************
192.168.N.N            : ok=2    changed=1    unreachable=0    failed=0 
```

Ansibleは冪等性を担保するため、TASKに変更がない場合は「OK」、変更があった場合は「changed」と表示されます。

- リモートホストの実行結果

| RECAP       |意味 | 
|:-----------------|:------------------|
| ok             | 定義された状態となっている             |
| changed        | 定義された状態に変更が行われた             |
| unreachable    | リモートホストへの接続に失敗した             |
| failed         | タスクの実行に失敗（エラー）             |
 
### Linux（CentOS）
Linux（CentOS）は以下のコマンドでインストールできます。

`yum install -y epel-release`
`yum install -y ansible`

インベントリ及びplaybookの作成手順は同じです。
また、ssh接続したことがないと、以下のようなメッセージが出力されます。
その場合、ssh接続することで「~/.ssh/known_hosts」が作成されて、ssh接続できるようになります。

```console
TASK [Gathering Facts] ***************************************************************************************************
fatal: [192.168.N.N]: FAILED! => {"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."}
	to retry, use: --limit @/root/playbook.retry
```

## Tips
### ansible-playbookコマンド
- 構文チェック   
`ansible-playbook -i hosts playbook.yml --syntax-check`
- 実行されるタスクの一覧を表示   
`ansible-playbook -i hosts playbook.yml --list-tasks`
- verboseオプション（-vvv）で詳細情報の表示及び、実行結果をJSONで返す  
`ansible-playbook -i hosts -u root -k playbook.yml -vvv`

### ansible-docコマンド
- モジュール確認  
`ansible-doc -l`

### その他
- 複数のファイルに分けたタスクを一つにまとめる場合は、"include"という記法を使う
- Ansible Containerを使用してコンテナを作成することができる

### 応用
- 障害検知した場合、Ansibleを起動して、障害発生時の一時対応自動化
- AnsibleとTerraformの両立（インスタンスの追加及び削除等リソースの構築はTerraformで行う）
- Serverspecを使ってテストの自動化

# おわりに
Ansibleについてまとめです。

Ansibleは、スモールスタートにより、システムに合わせて徐々に自動化を行うことができます。しかし、自動化を行うにあたり、Playbookの妥当性や、ツール実行後に、サーバのログを見て確認するなど、新たな悩みどころが出てきます。言い方を変えると、品質の確保になりますが、これについては**継続的インテグレーション**の話になるため、また今度にします。

![Ansible_image3.png](https://qiita-image-store.s3.amazonaws.com/0/221759/118e6c3d-fb87-cf4c-072d-795c25096482.png)

Ansibleの導入により、これまで常識と思っていた構築手順書及びパラメータシートは、コード化されインフラエンジニアの作業プロセスや方法は180℃変わります。

例えるなら、産業革命の中に蒸気機関の発達があったように、インフラの世界はここ数年、コンテナ技術や構成管理ツール等の自動化により、大きく変わりつつあります。

それでも、なお、SI業界の片隅では、絶対的なウォーターフォールから始まり、レガシーな開発手法でシステムが作られ運用されています。

そんな状況にいるので、時代に取り残されないように、自動化について学習していきます。

## 参考
- [GitHub](https://github.com/ansible/ansible)
- [Ansible公式ドキュメント](https://docs.ansible.com/)
- [Red Hat Ansible Automation](https://www.redhat.com/ja/explore/ansible)