generated at
Ansible
Ansibleとは
サーバ構成管理ツール(プロビジョニングツール)
Chefとかと同じタイプのツール
IaC(Infrastructure as code)に度々でてくるワード

Ansibleの長所と比較
サーバ設定ファイルがバージョン管理できる
IaCによりサーバと実サーバの環境設定の乖離を防げる
管理対象サーバにクライアントが不要
平易なyaml設定ファイルで構成が定義できる
diff
ChefAnsible
必要言語RubyPython3.5以上
クライアント要否不要
設定記述RubyYAML

基本用語
インベントリ(inventory)
サーバ構成対象の接続先の指定、グルーピングをするファイル
hostsと呼んだりもする
下記のようなファイル
dev-hosts
[webservers] 10.0.11.121 dev-web [dbservers] dev-db
.ssh/configとかのファイルを実行時に渡せばエイリアスで指定もできる
プレイブック(playbook)
サーバのあるべき状態を定義するファイル
下記のようなファイル
main.yml
- hosts: webservers tasks: - name: install httpd yum: name=httpd state=latest - name: install httpd - name: make root log directory file: path: /var/log/app1 mode: 0755 owner: root group: root state: directory become: yes
書き方は主に2種類ある
タスクで書く
上記のような書式
ロール(後述)で書く
dbserver.yml
- hosts: web roles: - log - user
モジュール(module)
ファイルの生成、ディレクトリの生成、ファイルのコピー、ミドルウェアのインストールといった最小の処理単位
タスク(task)
複数のモジュール実行をまとめたもの
ディレクトリを生成して、その配下にファイルを配置、といった複数の処理
ロール(role)
タスクとともに変数定義などをまとめたもの
ロール別で定義された変数は干渉しあわない
下記のディレクトリ構成でいう、rolesディレクトリ配下のディレクトリ名を指定する

今回作ったansible構成
dir
. |-- dbservers.yml |-- inventories | |-- development | | `-- hosts | `-- production | `-- hosts |-- roles | |-- log | | |-- defaults | | | `-- main.yml | | |-- files | | | `-- etc | | | |-- cron.d | | | | `-- app1 | | | |-- logrotate.d | | | | `-- app | | | `-- rsyslog.d | | | `-- app.conf | | |-- handlers | | | `-- main.yml | | `-- tasks | | `-- main.yml | `-- user | |-- files | | `-- home | | `-- foobar | `-- tasks | `-- main.yml |-- site.yml `-- webservers.yml 18 directories, 12 files

中身
playbook
site.ymlはシステム全体の状態を定義する
実態は2つのplaybookを読み出しているだけ
インデックスだけのファイル、に留めるのがベター
site.yml
- import_playbook: webservers.yml - import_playbook: dbservers.yml
webservers.yml
- hosts: web remote_user: foobar roles: # rolesのディレクトリ名を指定 - log - user
tasks
roles/log/tasks/main.yml
--- - name: make root log directory file: path: "{{ log_dir_root }}" # roles/log/defaults/main.ymlの値 mode: 0755 owner: root group: root state: directory become: yes - name: make application log directories file: path: "{{ log_dir_root }}/{{ item }}" # with_itemsの値 mode: 0755 owner: syslog group: syslog state: directory with_items: "{{ log_dir }}" become: yes - name: create application log files file: path: "{{ log_dir_root }}/{{ item }}/{{ item }}.log" mode: 0640 owner: syslog group: adm state: touch with_items: "{{ log_dir }}" become: yes - name: setup rsyslog vars: path: etc/rsyslog.d/app.conf copy: src: "../files/{{ path }}" dest: "/{{ path }}" mode: 0644 owner: root group: root backup: yes become: yes notify: restart_rsyslog # 変更があったら再起動。再起動の処理はhandersのファイルに記載 - name: setup logrotate vars: path: etc/logrotate.d/app copy: src: "../files/{{ path }}" dest: "/{{ path }}" mode: 0644 owner: root group: root backup: yes become: yes notify: restart_logrotate # 変更があったら再起動。再起動の処理はhandersのファイルに記載 - name: setup cron vars: path: etc/cron.d/app copy: src: "../files/{{ path }}" dest: "/{{ path }}" mode: 0644 owner: root group: root backup: yes become: yes notify: restart_cron # 変更があったら再起動。再起動の処理はhandersのファイルに記載
handlers
taskで変更があった場合だけ実行させたいものを書く
再起動の必要なミドルウェアの設定ファイルを更新した場合など(httpd, rsyslogなど)
roles/log/handlers/main.yml
- name: restart_rsyslog # 変更が合った時に実行。nameが完全一致する必要あり systemd: name: rsyslog.service # serviceまでフルに書く。find /etc/systemdで確認 state: restarted enabled: yes become: yes - name: restart_logrotate systemd: name: syslog.service state: restarted enabled: yes become: yes - name: restart_cron systemd: name: cron.service state: restarted enabled: yes become: yes
defaults
変数のデフォルト値を記載
roles/log/defaults/main.yml
log_dir_root: /var/log/app log_dir: - app1 - app2 - app3

上記の設定の構成をDockerコンテナ内のAnsibleから実行するサンプルはこちら

所感
pros
DockerでPython環境をラッピングすれば使い始めることの敷居は低そうに感じた
冪等性により何回でもリリースできる安心感がある
cons
お作法が多い
インフラ理解の浅い人がansible無視してサーバ設定をいじろうとしたりしそう
インフラ整備は誰かが一任しないと問題になりそう
単純にディレクトリを作成するだけのtasksでも結構時間がかかる
設定更新頻度が高いと待ち時間がネックになりそう
手動オペレーションで変更して、ansibleの設定に反映漏れ、とか起きそう

参考