Edited at

ansible の公式ドキュメント(英語)を読んで見落としがちなところをメモ

More than 3 years have passed since last update.

公式ドキュメント を読んで重要な点をメモしておく。

version 1.9 を前提にメモ。


用語の整理



  • facts : 更新先となるリモートサーバの各種情報。冒頭で取ってくる。


  • inventory : hosts ファイルで定義されるもののこと。


  • handler : サーバでの変更に応じて他サーバで何かをするためのイベントの仕組み。


  • playbook : ansible-playbook コマンドに渡すメインの yml のこと。設計する上では、構築手順を書くのでなく、何者なのかを書くこと。


  • 冪等性(べきとうせい/idempotent) : 何度動かしても大丈夫なこと。


hosts


  • host をグループ化できる。グループごとにキーバリューを設定できる:


グループごとの値設定

[atlanta]

host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com



  • グループはネストできる:


グループのネスト

[southeast:children]

group1
group2


tasks


  • 書かれている順に実行される。

  • 1つ task を対象サーバすべてに適用してから、次の task に移る。


handlers


playbook

tasks:

- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted

と書いておくと、変更があった場合のみ、handler の実行できる。


注:



  • notify の中は書かれている順に実行される。


  • handlers の中の名前は global スコープ。(同名があれば片方のみ実行される。)


  • include の中にある handlernotify できない。


  • pre_tasks, tasks, post_tasks の中で notify された handler は、各セクションの終了時にフラッシュ(≒実際に実行)され、roles の中で notify された handler は、tasks セクションの全の handler の後にフラッシュされる。


  • meta: flush_handlers でただちにフラッシュすることも可能:


playbook

  tasks:

- shell: some tasks go here
- meta: flush_handlers
- shell: some other tasks


include


  • トップ階層に tasks ディレクトリを作成し、その中に再利用可能な task の yml を保存しておくことで、playbook 中で再利用できる。

  • パラメータを渡すことも可能:


パラメータを渡す例

- include: wordpress.yml wp_user=timmy

もしくは
- include: wordpress.yml
vars:
wp_user: timmy


  • 別の playbook を include することも可能。その場合、パラメータは渡せない?


role


次のように振る舞う:


  • roles/x/tasks/main.yml (あれば)

  • roles/x/handlers/main.yml (あれば)

  • roles/x/vars/main.yml (あれば)

  • roles/x/meta/main.yml (あれば) 内の role dependencies が roles に加わる。

  • role 内の copy, script, template, include タスクは roles/x/{files,templates,tasks}/ (ディレクトリはタスクによる) の下を見る。


パラメータを渡す role:

  roles:

- common
- { role: foo_app_instance, dir: '/opt/a', app_port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', app_port: 5001 }


条件付きの role:

  roles:

- { role: some_role, when: "ansible_os_family == 'RedHat'" }


タグ付きの role (role内の全タグを上書くので注意):

  roles:

- { role: foo, tags: ["bar", "baz"] }


role の前後に task を走らせないなら:

  pre_tasks:

- shell: echo 'hello'
roles:
- { role: some_role }
tasks:
- shell: echo 'still busy'
post_tasks:
- shell: echo 'goodbye'


別の role に依存するなら (roles/x/meta/main.yml の中で) :

dependencies:

- { role: common, some_parameter: 3 }
- { role: apache, appache_port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 }


  • 同じ role は(パラメータが異なっていたとしても)デフォルトでは複数回適用されない。複数適用したいなら呼ばれる側で allow_duplicates: yes (複数回の適用を許す) が必要:

yaml:roles/car/meta/main.yml (呼び出す側)

dependencies:

- { role: wheel, n: 1 }

- { role: wheel, n: 2 }

yaml:roles/wheel/meta/main.yml (呼ばれる側)

allow_duplicates: yes

dependencies:

- { role: tire }


変数


命名ルール



  • foo_port のようなフォーマットであること。

  • 値は yaml で map を書くこともできる。


値の定義場所

inventory:


hosts

[atlanta]

host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

playbook:


playbook

- hosts: webservers

vars:
http_port: 80

include に渡す:


playbook

tasks:

- include: foo.yml
vars:
aa: timmy
bb:
key1: keys/one.txt
key2: keys/two.txt

値を外出し:


playbook

- hosts: all

remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml


/vars/external_vars.yml

somevar: somevalue

password: magic

コマンドライン:

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

もしくは
ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
もしくは
ansible-playbook release.yml --extra-vars "@some_file.json"
もしくは
ansible-playbook release.yml --extra-vars "@some_file.yml"


優先順位(下にいくほど強い)


  1. role defaults

  2. inventory の定義

  3. facts

  4. その他(コマンドラインのスイッチ、playのvars、includeされたvars、roleのvarsなど)

  5. コネクション変数(ansible_user など)

  6. extra vars(コマンドラインの -e)

※2.x で変わるらしい。


値を使う



  • {{ aa }}{{ bb.key1 }} のように使う。


  • foo: {{ bar }}/22 は NG。foo: "{{ bar }}/22" とすべき。これは yaml の文法上、{ がディクショナリの開始と混同されるため。


フィルタ

参照1

参照2



  • {{ val|default('aaa') }} - val が未定義の場合に aaa を採用。


  • {{ val|default('aaa', true) }} - valfalse として評価される値の場合('' 等)に aaa を採用。


  • {{ val|escape }} - <>&"' を HTML 用にエスケープ。


  • {{ "%s - %s"|format("Hello?", "Foo!") }} - フォーマット。


  • {{ val|trim }} - トリム。

  • - shell: echo {{ string_value | quote }}


  • {{ (name == "John") | ternary('Mr','Ms') }} - true なら左。

  • {{ list | join(" ") }}


  • {{ path | basename }} - ファイル名


  • {{ path | dirname }} - ディレクトリ名

  • {{ path | realpath }}

  • {{ path | relpath('/etc') }}


  • when: some_string_value | bool - bool にキャスト


  • when: url | match("http://example.com/users/.*/resources/.*") - 正規表現でえ完全一致


  • when: url | search("/users/.*/resources/.*") - 正規表現で中間一致


  • {{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }} - 正規表現で置き換え


register

  tasks:

- shell: /usr/bin/foo
register: foo_result
ignore_errors: True

- shell: /usr/bin/bar
when: foo_result.rc == 5


結果をフィルタして条件に使う

  - shell: /usr/bin/foo

register: result
ignore_errors: True

- debug: msg="it failed"
when: result|failed

# in most cases you'll want a handler, but if you want to do something right now, this is nice
- debug: msg="it changed"
when: result|changed

- debug: msg="it succeeded in Ansible >= 2.1"
when: result|succeeded

- debug: msg="it succeeded"
when: result|success

- debug: msg="it was skipped"
when: result|skipped



  • 結果が失敗でも skip されても foo_result は失敗/skipの結果が登録される。登録を避けたいならタグを使えばいい。


予約語



  • hostvars - 別host用の値が入っている。この時点で全くやりとりの無いサーバでも変数値は取れるが、その場合 facts は取れない。使用例: {{ hostvars['test.example.com']['ansible_distribution'] }}


  • group_names - 現在の host が属するグループのリスト(配列)。


  • groups - inventory に存在するすべてのグループとhost。


スコープ


  • global - コンフィグ、環境変数、コマンドラインによるもの。

  • play - 各playと、含まれる構造体, varsのentries, include_vars, role defaults , vars

  • host - hostに直接関連する値(inventory、facts、taskの出力をregisterしたものなど)