ansible基礎編

# はじめに
新人エンジニアです!(^^)!
少し前ですがansibleに触れたのでその辺りを軽くまとめていきたいと思います。
足らない部分もありましたらコメントなど頂けると幸いです。

# この記事の対象者
ansibleに初めて触れる方。
ansibleの基本的な部分について思い出したい方向けです。
ansibleのインストール等の部分は省略しております。

# 目次
1. [Ansibleの基本情報](#Ansibleの基本情報)
2. [Ansibleファイル構成](Ansibleファイル構成) 
3. [利用例](利用例)
4. [最後に](終わり)


# 1. Ansibleの基本情報
Ansibleとは、プロビジョニング、構成管理、アプリケーションのデプロイメント、オーケストレーション、その他多くのITプロセスを自動化する、オープンソースのIT自動化エンジンです。
今回はAWS作成したEC2サーバに対してAnsibleを実行することで自動で構成を管理します。
Ansibleを利用する際は冪等性を担保することが重要になっていきます。
それぞれのファイルは基本的にyamlで記述します。

[ Ansible ドキュメント公式](https://docs.ansible.com/ansible/2.9_ja/index.html)

# 2. Ansibleディレクトリ構成 

以下でawsのEC2にユーザーを登録するansibleの構成について記載していきたいと思います。
サーバーがある前提になりますのでご了承ください。

```text

├── ansible.cfg
├── group_vars
│   ├──sample1.yaml ------ Group変数の設定(登録ユーザの設定)
│   └──sample2.yaml 
├── host_vars ------ ホスト変数の設定
├── inventory.yaml ------ 実行対象の指定
├── playbook.yaml ------ 実行内容の定義
└── roles ------ 実行内容を記載する
    └── adduser ------ ユーザ登録
    　　    └── files ------ ユーザ毎に公開鍵ファイルを設置する
            │  ├── hoge.pub
            │  └── piyo.pub
            └── tasks 
　　　　　　　　　　└── main.yaml --- ansibleで実行するコマンド設定
```

今回の場合はroles以下にadduserというユーザー登録を実行するディレクトリを作成しています。
他の構築を行いたい場合はこのroles以下に随時追加する形になります。
tasksにはmain.yamlが入っており、ここで実行するコマンドを記載します。これは後述します。

以下参考になりました。
[Ansible - ディレクトリ構成について](https://qiita.com/makaaso-tech/items/0375081c1600b312e8b0)

# ３.利用例

ではそれぞれ具体例をあげて説明していきたいと思います。
## ansible.cfg
ansible設定ファイル

ansible.configでは以下のリストを処理し、最初に見つかったファイルを使用し、他のファイルは無視されます
- ANSIBLE_CONFIG （設定されている場合は環境変数）
- ansible.cfg （現在のディレクトリ内）
- ~/.ansible.cfg （ホームディレクトリ内）
- /etc/ansible/ansible.cfg

```:ansible.cfg
[defaults]
stdout_callback = yaml
```

ansible.cfg の[defaults]に上記の内容を記述するとタスク失敗時などのログ表示がyamlになり読みやすくなります。
こちらのページには他にも[Ansibleの設定](https://runebook.dev/ja/docs/ansible/reference_appendices/config#default-stdout-callback)が書いてあります。

## inventory.yml

インベントリーの定義によってAnsibleで実行されるホストまたはグループの選択を行います。
Ansibleを実行するサーバの設定はこのファイルで行います。

```[inventory.yml]
all:
 children:
    sample1:　# sample1のグループ
      hosts: # sample1グループのホスト
　　　　sample1_1:
          ansible_host: 10.0.0.0 # ホスト変数
       sample1_2:
          ansible_host: 11.0.0.0 # ホスト変数 
      vars:　# sample1グループの変数
        env: dev
    sample2: # sample2のグループ
      hosts: 12.0.0.0 # ホスト変数 
      vars:
        env: stg
```

すべてのホストやグループが所属する```all```グループをトップに定義します。
グループ配下の定義には所属させたい子のグループを```children```で定義し、所属させたいホストを```hosts```で定義します。
ホスト変数はホスト名配下に定義します。グループ変数は```vars```配下に定義します。

[インベントリファイルをyamlで書く](https://tekunabe.hatenablog.jp/entry/2019/03/10/ansible_inventory_yaml)
[Ansibleのinventory入門](https://dev.classmethod.jp/articles/inventory/)

## group_vars
group_varsではインベントリファイルの各グループで使用する変数をまとめることができます。
今回の例であげるとグループ名がsample1,sample2とあります。
group_vars配下に上記のディレクトリ構成のように```group_vars/sample1.yml```,```group_vars/sample2.yml```とファイルを用意しグループ共通で利用する変数を定義することができます。
変数の使用例は[playbook.yaml](#playbook.yaml)に記述させていただきます。

```[sample1.yml]
users:
 - name: sample_name
   uid: 1111
```

[[Ansible] group_vars 配下にグループ名の「ディレクトリ」を用意すると複数の変数ファイルをまとめられる](https://tekunabe.hatenablog.jp/entry/2018/12/15/ansible_group_vars_dir)

## host_vars
ホスト毎の変数を定義するのに使います。group_vars と同じくファイル名はインベントリファイルに設定したホスト名です。インベントリファイルの中でホスト名の右に並べて書くこともできます。

## playbook.yaml　

```[playbook.yaml]
- hosts: all # 対象とするホストグループ
  roles: # 実行するタスク定義名を指定
    - adduser
```

allで全サーバー対象になります。
この記述でこれをそのまま```ansible-playbook -i inventory.yaml -l all playbook.yaml -v --check```と実行してしまうとイベントリファイルに書いてあるすべてのホストに対して実行を行ってしまいます。
これをsample1にのみ実行したい場合は下記のように指定する。
```ansible-playbook -i inventory.yaml -l sample1 playbook.yaml -v --check```

[実行コマンド](https://tech.withsin.net/2017/07/19/ansible-playbook-l/)


### roles 
rolesで指定したディレクトリにtask定義のファイルを置いておくことでそのファイルを実行してくれます。
今回は前述したようにadduserのRoleを作成しています。他にも置いていくつかの定義をすることが可能です。

[RolesでAnsibleのPlaybookを整理してみよう](https://www.indetail.co.jp/blog/ansible-2/)

#### tasks

rolesでいい感じに構造を作り読み込んでくれるようになりますが、tasksディレクトリにはmain.yamlは**必須**となります。

```[main.yaml]

- name: add user # ansibleで実行するコマンド　
  user:
    name: "{{ item.name }}"
    group: "{{ item.name }}"
    uid: "{{ item.uid }}"
    password: ""
    update_password: on_create
    state: present
  become: true
  with_items:
    - "{{ users }}"　# group_varsで定義したusers配列

- name: add authorized_key
  authorized_key:
    user: "{{ item.name }}"
    key: "{{ lookup('file', '../files/{{ item.name }}.pub') }}"
  ignore_errors: "{{ ansible_check_mode }}" #errorでも処理を継続
  become: true
  become_user: '{{ item.name }}'
  with_items:
    - "{{ users }}"
```

nameでansibleで実行するコマンドを定義しています。
その後に各変数を利用して設定を行っています。
```with_items:```で配列を指定し、```{{item}}```で配列の要素を入れることができます。

```add user``` ユーザー作成
```add authorized_key``` 鍵設定



変数の使い方などはこちら参考に
[Ansible入門 その２ Playbook](https://qiita.com/newnakashima/items/da474eedb072997de243)


# 4.最後に

いかがでしたでしょうか？
足りない記述もあるかもしれませんがansibleの基本からユーザー登録を行うところまでをまとめました。
それぞれのディレクトリ構成など実例を挙げながら分かりやすくまとめられていたらと思います。

他の誰が見ても直ぐに理解できるようにディレクトリの構成などには気を付けて行いたいです。

もうすぐエンジニア1年目が終わりますが2年目もまだ新人エンジニア？として頑張りますw


# 参考
以下のサイトや記事を参考にさせて頂きました。ありがとうございます。
[ Ansible ドキュメント公式](https://docs.ansible.com/ansible/2.9_ja/index.html)
[Ansible - ディレクトリ構成について](https://qiita.com/makaaso-tech/items/0375081c1600b312e8b0)
[Ansibleの設定](https://runebook.dev/ja/docs/ansible/reference_appendices/config#default-stdout-callback)
[インベントリファイルをyamlで書く](https://tekunabe.hatenablog.jp/entry/2019/03/10/ansible_inventory_yaml)
[[Ansible] group_vars 配下にグループ名の「ディレクトリ」を用意すると複数の変数ファイルをまとめられる](https://tekunabe.hatenablog.jp/entry/2018/12/15/ansible_group_vars_dir)
[実行コマンド](https://tech.withsin.net/2017/07/19/ansible-playbook-l/)
[RolesでAnsibleのPlaybookを整理してみよう](https://www.indetail.co.jp/blog/ansible-2/)
[Ansibleのinventory入門](https://dev.classmethod.jp/articles/inventory/)