Edited at

【Ansible】かゆいところに手が届く12のTips その1

More than 3 years have passed since last update.

Ansibleを使っていて、個人的にハマって調べたことをTipとしてまとめていきたいと思います。Tipsが溜まったらその2もやります!

その2はこちら


今回紹介するTips


  1. shellモジュールで状態確認コマンドを実行した際にchangedを出さない

  2. 変数が未定義の時の判定

  3. 配列が空の場合にエラーを出さない

  4. 多重配列をループさせたい

  5. 現在時刻を取得したい

  6. ローカルに作業前のバックアップ領域を作成したい

  7. handlerを即座に実行したい

  8. Ansibleの変数の優先順位

  9. 変数のスコープについて

  10. Jinja2のtemplateはとても便利

  11. 仮想マシン作り直したらAnsibleが届かなくなった

  12. User用のパスワードの生成


shell moduleでの状態確認にchangedは出したくない

changed_when: falseをつける


task

shell: systemctl get-default

changed_when: false


変数が未定義の時の判定

is definedを使う


tasks

- copy:

src: "{{ host }}"
dest: /etc/hosts

when: host is defined



配列が空の場合にエラーを出さない

default([])を使う


tasks

- sysctl:

name: "{{ item.name }}"
value: "{{ item.value }}"

with_items:
- "{{ KERNELPARAMETER_LIST | default([]) }}"



多重配列をループさせたい

with_subelementsを使う


var

userlist:

- name: user1
uid: 100
groups:
- user1
- wheel


task


user:
name: "{{ item.0.name }}"
uid: "{{ item.0.uid }}"
group: "{{ item.1 }}"

with_subelements:
- "{{ userlist }}"
- groups



現在時刻を取得したい

lookupを使う


var

date: "{{ lookup('pipe','date +%Y%m%d%H%M') }}"



ローカルに作業前のバックアップ領域を作成したい


tasks

- file:

path: "/tmp/{{ lookup('pipe','date +%Y%m%d%H%M') }}"
state: directory
mode: 0777
owner: root
group: root
connection: local
run_once: True
changed_when: False


handlerを即座に実行したい

meta: flush_handlersを使う。

notifyを利用してhandlerを呼び出した場合、handlerが実行されるのは、いずれかです。


  • pre_task/tasks/post_taskセクションの終了時

  • roleを呼び出したtasksセクションの終了時

即座に実行させるためには、以下のようにします。


task

tasks:

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


Ansibleの変数の優先順位

↑弱い


var

- role defaults [1]

- inventory vars [2]
- inventory group_vars
- inventory host_vars
- playbook group_vars
- playbook host_vars
- host facts
- registered vars
- set_facts
- play vars
- play vars_prompt
- play vars_files
- role and include vars
- block vars (only for tasks in block)
- task vars (only for the task)
- extra vars (always win precedence)

↓強い


変数のスコープについて

Ansibleの変数のスコープは以下の3つです。

種類
内容

Global
コンフィグや環境変数やコマンドラインでセットされたもの

Play
それぞれのPlaybookごとに設定された値やinclude_varsの値

Host
実行されたホストごとの変数、gather_factsで収集した値や、registerで登録した値などそれぞれ独立しています

そのため、role内で定義した変数も別のroleに引き継がれます。変数は被らないように注意しましょう。


Jinja2のtemplateはとても便利

template内でifforが使え、自由度の高い記載が行えます。

ここを参考にすると良いです。

Template Designer Documentation


hosts.j2

{% for item in HOST_LIST %}

{{ item }}
{% endfor %}


ntp.conf.j2

・・・

{% for hostname in NTP_LIST %}
{% if loop.first %}
server {{ hostname }} iburst minpoll 4 maxpoll 5 prefer
{% else %}
server {{ hostname }} iburst minpoll 4 maxpoll 5
{% endif %}
{% endfor %}
・・・


仮想マシン作り直したらAnsibleが届かなくなった

SSHコマンドは通るのになぜー?

rhel7 | UNREACHABLE! => {

"changed": false,
"msg": "ERROR! SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh",
"unreachable": true
}


/var/log/secure

Mar 14 17:41:42 localhost sshd[5796]: Connection closed by x.x.x.x [preauth]


以下のいずれかを実施しましょう。



  • known_hostsに前のデータが残っている場合があるので削除


  • ansible.cfg内のANSIBLE_HOST_KEY_CHECKING=Falseのコメントを外す


User用のパスワードの生成

python -c 'import crypt; print crypt.crypt("パスワード", "$1$SomeSalt$")'

参考:AnsibleのUserモジュールでpasswordを設定する時の注意

その2はこちら