Ansibleのimport_roleでimportしたroleが複数実行される条件を確認した

## はじめに

Ansibleのimport_roleがどの場合に複数回実行されるか調べたのでメモ

下記2x2=4パターンを調べた

* `allow_duplicates` がyes/no
* varsで渡す変数が同じ/異なる


## 前提条件

* ansible-core: 2.12.3

ディレクトリ構造

```shell-session
$ tree
.
├── playbook.yml
└── roles
    └── testrole
        └── tasks
            └── main.yml

3 directories, 2 files
```


`roles/testrole/tasks/main.yml`

```yml
- debug: msg="testvar is {{ testvar }}"
```


### 1. `allow_duplicates: yes`、varsで同じ変数を渡す

`playbook.yml`

```yml
- name: test
  hosts: localhost
  connection: localhost
  tasks:
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: hoge
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: hoge
```

#### 実行結果

2回実行される

```shell-session
$ ansible-playbook /ansible/playbook.yml

PLAY [test] **************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [localhost]

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is hoge"
}

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is hoge"
}

PLAY RECAP ***************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0      
```


### 2. `allow_duplicates: yes`、varsで異なる変数を渡す

`playbook.yml`

```yml
- name: test
  hosts: localhost
  connection: localhost
  tasks:
    - import_role:
        name: testrole
        allow_duplicates: yes
      vars:
        testvar: hoge
    - import_role:
        name: testrole
        allow_duplicates: yes
      vars:
        testvar: fuga
```

#### 実行結果

2回実行される

```shell-session
$ ansible-playbook /ansible/playbook.yml

PLAY [test] **************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [localhost]

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is hoge"
}

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is fuga"
}

PLAY RECAP ***************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
```


### 3. `allow_duplicates: no`、varsで同じ変数を渡す

`playbook.yml`

```yml
- name: test
  hosts: localhost
  connection: localhost
  tasks:
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: hoge
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: hoge
```

#### 実行結果

1回だけ実行される

```shell-session
$ ansible-playbook /ansible/playbook.yml

PLAY [test] **************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [localhost]

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is hoge"
}

PLAY RECAP ***************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
```


### 4. `allow_duplicates: no`、varsで異なる変数を渡す

`playbook.yml`

```yml
- name: test
  hosts: localhost
  connection: localhost
  tasks:
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: hoge
    - import_role:
        name: testrole
        allow_duplicates: no
      vars:
        testvar: fuga
```

#### 実行結果

2回実行される

```shell-session
$ ansible-playbook /ansible/playbook.yml

PLAY [test] **************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [localhost]

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is hoge"
}

TASK [testrole : debug] **************************************************************************************
ok: [localhost] => {
    "msg": "testvar is fuga"
}

PLAY RECAP ***************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
```


### 終わりに

1~3は想定通りだが、4の場合に複数回実行されることが分かった。