レッドハットの杉村です。Ansible のテクニカルサポートをしています。毎月1つは何か書くことを目標にしているのですが、3月があっという間に去ってしまいました。
今回はたまにお問い合わせいただく変数について紹介してみようと思います。Ansible のバージョンは Ansible Core 2.12.1 で試しています。
まずはこのような playbook を題材にしてみます。
--- - hosts: all tasks: - name: debug debug: msg: "Hello Ansible!"
実行するとこうなります。
$ ansible-playbook playbook.yml -i localhost, -e ansible_connection=local PLAY [all] ************************************************************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************************************************ ok: [localhost] TASK [debug] ********************************************************************************************************************************************************************** ok: [localhost] => { "msg": "Hello Ansible!" } PLAY RECAP ************************************************************************************************************************************************************************ localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
モジュールに渡す変数
この Hello Ansible!
の文字列を変数にすることができます。
--- - hosts: all tasks: - name: debug debug: msg: "{{ message }}" vars: message: "Hello Ansible!"
debug モジュールについては、msg パラメータの代わりに変数を var パラメータで渡すこともできます。
--- - hosts: all tasks: - name: debug debug: var: message #msg: "{{ message }}" vars: message: "Hello Ansible!"
タスクに定義する形ではあまりありがたくないかもしれません。プレイに定義することが多いでしょう。
--- - hosts: all vars: message: "Hello Ansible!" tasks: - name: debug debug: var: message
ファイルに外出しすることもできます。variables.yml に書いたとします。
--- message: "Hello Ansible!"
このとき playbook.yml ではファイル名を指定します。
---
- hosts: all
vars_files:
- variables.yml
tasks:
- name: debug
debug:
var: message
変数の型
上の例では変数は文字列でしたが、他にもこのようなものがあります。
- 真偽値 (true/false)
- 文字列
- 数値
- ディクショナリ
- リスト
厳密なところは YAML の文法定義などを見ていただいて、ここではざっくりと紹介します。
真偽値
true を yes と書いたり、false を no と書いたりすることもできます。わたしは true / false が好みですが、Ansible のドキュメントでは yes / no で書いてあることもよくあります。True のように大文字で始める流儀も結構目にします。
文字列
‘文字列’ や “文字列” のように書きます。”” の中で {{ }} を使って変数参照して連結するのがよくあります。
--- - hosts: all vars_files: - variables.yml tasks: - name: debug debug: msg: "Good morning! {{ message }}"
数値
file モジュールでよくひっかかるやつです。
- name: touch file: path: /tmp/temporaryfile.tmp state: touch mode: 644
例えばこのように書いて実行しますと、このようによくわからない権限がつけられてしまいます。644 が数値として解釈されたために、8進法では 1204 となってそのように設定されます。
$ ls -l /tmp/temporaryfile.tmp --w----r-T. 1 sugimura sugimura 0 4月 7 14:28 /tmp/temporaryfile.tmp
正しくはこのように文字列型として指定するか、8進法の数値であることを明示するために 0 で始めます。
- name: touch file: path: /tmp/temporaryfile.tmp state: touch mode: 0644 # mode: "0644" ... こちらをおすすめします
ディクショナリ
key: value の組を並べたものです。
--- a_dict_variable: foo: true bar: "hello" baz: 123456
このような形で定義します。変数名の後に、同じレベルのインデントで key: value の形で並べていきます。
--- - hosts: all vars_files: - dict.yml tasks: - name: debug debug: var: a_dict_variable
出力してみるとこのように出てきます。{ } でくくられています。
TASK [debug] ********************************************************************************************************************************************************************** ok: [localhost] => { "a_dict_variable": { "bar": "hello", "baz": 123456, "foo": true } }
中身を取り出すこともできます。
- name: debug debug: msg: "The numeric var is {{ a_dict_variable['baz'] }}"
このように .
で接続する形でも取れますが、変数名によっては取れないことがありますので注意してください。
- name: debug debug: msg: "The numeric var is {{ a_dict_variable.baz }}"
リスト
他の言語では配列と呼ぶこともあります。同じ要素を並べているものです。
変数名の後ろで -
を使って並べていきます。インデントはしなくてもいいようですが、したほうが好みです。
--- list_example: - "item1" - "item2" - "item3"
出力してみると [ ] でくくられていることがわかります。
TASK [debug] ********************************************************************************************************************************************************************** ok: [localhost] => { "list_example": [ "item1", "item2", "item3" ] }
配列は [n] で参照することができます。0 始まりです。
- name: debug debug: var: list_example[1]
[1] は2番目なので、”item2” が取れています。
TASK [debug] ********************************************************************************************************************************************************************** ok: [localhost] => { "list_example[1]": "item2" }
ディクショナリとリストの組み合わせ
ディクショナリとリストを組み合わせることができます。
例えば setup モジュールではマネージドノード(管理対象)からさまざまな情報を収集して変数に格納することができますが、この変数はディクショナリとリストの組み合わせで成り立っていることがわかります。
$ ansible -m setup -i localhost, -e ansible_connection=local localhost localhost | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "192.168.0.xxx", "10.88.0.1" ], "ansible_all_ipv6_addresses": [ "2404:xxxx:xxxx:xxxx:250:56ff:xxxx:f278", "fe80::250:56ff:xxxx:f278", "fe80::54ff:d9ff:xxxx:1fe8" ], "ansible_apparmor": { "status": "disabled" }, "ansible_architecture": "x86_64", "ansible_bios_date": "12/24/2020", "ansible_bios_vendor": "VMware, Inc.", "ansible_bios_version": "VMW71.00V.17369862.B64.2012240522", "ansible_board_asset_tag": "NA", "ansible_board_name": "440BX Desktop Reference Platform", "ansible_board_serial": "NA", "ansible_board_vendor": "Intel Corporation", "ansible_board_version": "None", "ansible_chassis_asset_tag": "No Asset Tag", "ansible_chassis_serial": "NA", "ansible_chassis_vendor": "No Enclosure", "ansible_chassis_version": "N/A", "ansible_cmdline": { "BOOT_IMAGE": "(hd0,gpt2)/vmlinuz-4.18.0-348.el8.x86_64", "crashkernel": "auto", "quiet": true, "rd.lvm.lv": "rhel_rhel85/swap", "resume": "/dev/mapper/rhel_rhel85-swap", "rhgb": true, "ro": true, "root": "/dev/mapper/rhel_rhel85-root" }, ...
"ansible_facts" は {} で始まっていることから全体としてはディクショナリになっていて、その要素の "ansible_all_ipv4_addresses" では IP アドレスがリストになっていたり、"ansible_cmdline" はさらにディクショナリになっていたりということがわかります。
ansible_facts は特別な処理を行っているので、この下の要素を直接指定して値を得ることができます。
--- - hosts: all gather_facts: true tasks: - name: debug debug: var: ansible_architecture
リストを loop で回しつつ、その中の値をディクショナリとして参照するというのはよくある使い方です。
--- - hosts: all gather_facts: true tasks: - name: debug debug: msg: "{{ item.mount }} : {{ item.size_total }}" loop: "{{ ansible_mounts }}"
変数の加工
これまで見てきたものでほとんどの用途はカバーできますが、加工して条件判定や他のタスクに渡したくなったり、うまくループするために参照方法を工夫したいということがあります。このあたりのドキュメントをよく読んでいます。他にも役に立つものがありますので探してみてください。
終わりに
今回は Ansible で扱う変数について紹介してみました。次回はこの変数を受け渡しすることについてまとめてみようと思います。
Ansible Automation Platform の試用版はこちらをご覧ください。
Happy Automation!