はじめに
以前の記事でもご紹介しましたが、ロールの実行に必要な変数をチェックする「Role argument validation」という機能があります。
tekunabe.hatenablog.jp
ロールの meta/argument_specs.yml
というファイルに、どういう変数が必須か、型は何かなどを定義すると、Playbook からロールを呼ぶ際に、冒頭で変数のチェックをしてくれます。要件を満たさない場合はロールが実行されません。
ロールの実行と変数のチェックがセットであるため、ただ変数のチェックのみしたい(テスト目的など)場合は少々不都合です。
そこで利用できるのが、ansible.builtin.validate_argument_spec
モジュールです。
この記事では簡単な検証をした結果をまとめます。
サンプル
roles
ディレクトリ配下に myapp
ロールを作成し、その中の meta/argument_specs.yml
に以下のファイルを用意します。
myapp_int
は int
で必須、myapp_str
は str
で任意、という定義です。
---
argument_specs:
main:
short_description: The main entry point for the myapp role
options:
myapp_int:
type: "int"
required: true
description: "The integer value"
myapp_str:
type: "str"
description: "The string value"
上記のファイルを利用し、変数のチェックをする Playbook は以下の通りです。
---
- name: Test Play
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Verify variables by argument_specs.yml
ansible.builtin.validate_argument_spec:
argument_spec: "{{ (lookup('ansible.builtin.file', spec_file) | from_yaml)['argument_specs']['main']['options'] }}"
provided_arguments: "{{ my_parameters }}"
vars:
spec_file: roles/myapp/meta/argument_specs.yml
my_parameters:
myapp_int: 12345
myapp_str: sakana
argument_spec
オプションに、argument_specs.yml
の中身を渡しています。
provided_arguments
オプションにはチェックさせたい変数を指定します。ここでは、vars
ディレクティブ配下の my_parameters
の中身(myapp_int
、myapp_str
)がチェックさせたい変数です。provided_arguments
オプションの指定なので、チェックしたい変数が別の場所(インベントリ変数、Play 変数、extra vars など)してあるなら指定不要です。
正常時の結果
先程の my_parameters
は要件を満たしています。この状態で Playbook を実行します。
PLAY [Test Play] *****************************************************************************************************
TASK [Verify variables by argument_specs.yml] *************************************************************************
ok: [localhost]
PLAY RECAP ***********************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ok
になりました。
チェックだけなので、ロール自体の処理は実行されません。
異常時の結果
今度は要件を満たさないようにしてみます。
my_parameters:
myapp_int: damedesuyo
myapp_str: sakana
Playbook 実行結果は以下のとおりです。myapp_int
の int
にできないという親切なメッセージが表示されました。
fatal: [localhost]: FAILED! => {
"argument_errors": [
"argument 'myapp_int' is of type <class 'str'> and we were unable to convert to int: <class 'str'> cannot be converted to an int"
],
"argument_spec_data": {
"myapp_int": {
"description": "The integer value",
"required": true,
"type": "int"
},
"myapp_str": {
"description": "The string value",
"required": true,
"type": "str"
}
},
"changed": false,
"msg": "Validation of arguments failed:\nargument 'myapp_int' is of type <class 'str'> and we were unable to convert to int: <class 'str'> cannot be converted to an int",
"validate_args_context": {}
}
PLAY RECAP ***********************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
まとめ
用途は限られるかもしれませんが、ロールの処理はしたくないけど変数のチェックだけしたい、というときには有効な手段だと思います。
参考
docs.ansible.com
おまけ
ロールの実行に必要な変数のチェックという用途とは異なりますが、何かしらの変数のチェックを JSON Schema で行いたい場合は、ansible.utils
コレクション内の validate
モジュールなどが利用できます。