【ルール説明】args

こちらの記事は [Ansible lint Advent Calendar 2022 カレンダー2](https://qiita.com/advent-calendar/2022/ansible-lint) 21日目の記事になります。


今回はルール [args](https://ansible-lint.readthedocs.io/rules/args/) について説明します。

### args

[args](https://ansible-lint.readthedocs.io/rules/args/) はモジュールを利用する際に必要なパラメーターが全て渡されているかを検証します。[args](https://ansible-lint.readthedocs.io/rules/args/) はモジュールのコードを読み込み内部的に解析します。モジュールのパラメーターを処理する部分で`mutually_exclusive`、`required_together`、`required_one_of`などの条件からモジュールを利用する際に必要なパラメーターを判断します。

#### 問題のあるコードその１

```yaml
---
- name: Fixture to validate module options failure scenarios
  hosts: localhost
  tasks:
  - name: Clone content repository
    ansible.builtin.git: # <- パラメーター repo が定義されていない
      dest: /home/www
      accept_hostkey: true
      version: master
      update: false
```

#### 修正されたコードその１

```yaml
---
- name: Fixture to validate module options pass scenario
  hosts: localhost
  tasks:
  - name: Clone content repository
    ansible.builtin.git: # <- repo を定義する
      repo: https://github.com/ansible/ansible-examples.git
      dest: /home/www
      accept_hostkey: true
      version: master
```

#### 問題のあるコードその２

```yaml
---
- name: Fixture to validate module options failure scenarios
  hosts: localhost
  tasks:
  - name: Copy an object already stored in another bucket
    amazon.aws.s3_object:
      bucket: mybucket
      object: /my/desired/key.txt
      # mode が copy になっているが copy_src.bucket が定義されていない
      mode: copy
      copy_src:
        object: /source/key.txt
```

#### 修正されたコードその２

```yaml
---
- name: Fixture to validate module options pass scenario
  hosts: localhost
  tasks:
  - name: Copy an object already stored in another bucket
    amazon.aws.s3_object:
      bucket: mybucket
      object: /my/desired/key.txt
      mode: copy
      copy_src:
        bucket: srcbucket  # <- copy_src.bucket を定義する
        object: /source/key.txt
```

#### 問題のあるコードその３

```yaml
---
- name: Fixture to validate module options failure scenarios
  hosts: localhost
  tasks:
  - name: Use quiet to avoid verbose output
    ansible.builtin.assert:
      test:
        - my_param <= 100
        - my_param >= 0
      quiet: invalid # <- quiet の値が無効
```

#### 修正されたコードその３

```yaml
---
- name: Fixture to validate module options pass scenario
  hosts: localhost
  tasks:
  - name: Use quiet to avoid verbose output
    ansible.builtin.assert:
      test:
        - my_param <= 100
        - my_param >= 0
      quiet: true # <- quiet の値は boolean 型で定義する
```

### 特殊なケースその１

リスト形式の変数を利用したい場合は [Ansible lint](https://ansible-lint.readthedocs.io) の検証を無効にします。

#### 問題のあるコード

```yaml:group_vars/all
---
# リスト型の変数を定義する
security_group_rules:
  - proto: tcp
    from_port: "{{ ssh_port }}"
    to_port: "{{ ssh_port }}"
    cidr_ip: '0.0.0.0/0'
  - proto: icmp
    from_port: 8
    to_port: -1
    cidr_ip: '0.0.0.0/0'
```

```yaml:some_playbook.yml
---
- name: Fixture to validate module options failure scenarios
  hosts: localhost
  tasks:
  - name: Create security group
    amazon.aws.ec2_security_group:
      name: "{{ security_group_name }}"
      description: "{{ security_group_name }}"
      profile: "{{ profie | default(omit) }}"
      rules: "{{ security_group_rules }}" # <- 本来はリスト型のオプションなのでエラーになる
      rules_egress: "{{ security_group_rules_egress }}"
    register: security_group
```

#### 修正されたコード

```yaml:group_vars/all
---
# リスト型の変数を定義する
security_group_rules:
  - proto: tcp
    from_port: "{{ ssh_port }}"
    to_port: "{{ ssh_port }}"
    cidr_ip: '0.0.0.0/0'
  - proto: icmp
    from_port: 8
    to_port: -1
    cidr_ip: '0.0.0.0/0'
```

```yaml:some_playbook.yml
---
- name: Fixture to validate module options pass scenario
  hosts: localhost
  tasks:
  - name: Create security group # noqa: args[module] <- 検証を無効にする
    amazon.aws.ec2_security_group:
      name: "{{ security_group_name }}"
      description: "{{ security_group_name }}"
      profile: "{{ profie | default(omit) }}"
      rules: "{{ security_group_rules }}" # <- 検証が無効になっているためエラーにならない
      rules_egress: "{{ security_group_rules_egress }}"
    register: security_group
```

### 特殊なケースその２

オプションのパラメーターがいくつものパターンを取りうる場合は [Ansible lint](https://ansible-lint.readthedocs.io) の検証を無効にします。

#### 修正されたコード

```yaml
---
# url と data は同時に定義できないが変数などで動的に制御したい
- name: Fixture to validate module options pass scenario
  hosts: localhost
  tasks:
  - name: Add apt keys  # noqa: args[module] <- 検証を無効にする
    become: true
    ansible.builtin.apt_key:
      url: "{{ zj_item['url'] | default(omit) }}"
      data: "{{ zj_item['data'] | default(omit) }}"
    loop: "{{ repositories_keys }}"
    loop_control:
      loop_var: zj_item
```

### 参考サイト

* [args — Ansible Lint Documentation](https://ansible-lint.readthedocs.io/rules/args/)