はじめに
以前の記事でもご紹介しましたが、ロールの実行に必要な変数をチェックする「Role argument validation」という機能があります。
ロールの meta/argument_specs.yml
というファイルに、どういう変数が必須か、型は何かなどを定義すると、Playbook からロールを呼ぶ際に、冒頭で変数のチェックをしてくれます。要件を満たさない場合はロールが実行されません。
ロールの実行と変数のチェックがセットであるため、ただ変数のチェックのみしたい(テスト目的など)場合は少々不都合です。
そこで利用できるのが、ansible.builtin.validate_argument_spec
モジュールです。
この記事では簡単な検証をした結果をまとめます。
- 検証環境
- ansible-core 2.16.0
サンプル
roles
ディレクトリ配下に myapp
ロールを作成し、その中の meta/argument_specs.yml
に以下のファイルを用意します。
myapp_int
は int
で必須、myapp_str
は str
で任意、という定義です。
--- argument_specs: main: # main.yml に対応 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 # int にすべきところを意図的に文字列 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
まとめ
用途は限られるかもしれませんが、ロールの処理はしたくないけど変数のチェックだけしたい、というときには有効な手段だと思います。
参考
おまけ
ロールの実行に必要な変数のチェックという用途とは異なりますが、何かしらの変数のチェックを JSON Schema で行いたい場合は、ansible.utils
コレクション内の validate
モジュールなどが利用できます。