Ansible
Ansibleとは
サーバ構成管理ツール(プロビジョニングツール)
IaC(Infrastructure as code)に度々でてくるワード Ansibleの長所と比較
サーバ設定ファイルがバージョン管理できる
IaCによりサーバと実サーバの環境設定の乖離を防げる
管理対象サーバにクライアントが不要
table:diff
Chef Ansible
必要言語 Ruby Python3.5以上
クライアント要否 要 不要
設定記述 Ruby YAML
基本用語
インベントリ(inventory)
サーバ構成対象の接続先の指定、グルーピングをするファイル
hostsと呼んだりもする
下記のようなファイル
code:dev-hosts
10.0.11.121
dev-web
dev-db
.ssh/configとかのファイルを実行時に渡せばエイリアスで指定もできる
プレイブック(playbook)
サーバのあるべき状態を定義するファイル
下記のようなファイル
code: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種類ある
タスクで書く
上記のような書式
ロール(後述)で書く
code:dbserver.yml
- hosts: web
roles:
- log
- user
モジュール(module)
ファイルの生成、ディレクトリの生成、ファイルのコピー、ミドルウェアのインストールといった最小の処理単位
タスク(task)
複数のモジュール実行をまとめたもの
ディレクトリを生成して、その配下にファイルを配置、といった複数の処理
ロール(role)
タスクとともに変数定義などをまとめたもの
ロール別で定義された変数は干渉しあわない
下記のディレクトリ構成でいう、rolesディレクトリ配下のディレクトリ名を指定する
今回作ったansible構成
code: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を読み出しているだけ
インデックスだけのファイル、に留めるのがベター
code:site.yml
- import_playbook: webservers.yml
- import_playbook: dbservers.yml
code:webservers.yml
- hosts: web
remote_user: foobar
roles: # rolesのディレクトリ名を指定
- log
- user
tasks
code: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など)
code: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
変数のデフォルト値を記載
code: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の設定に反映漏れ、とか起きそう
参考