Ansibleの実行時間を短縮させるための小ネタ

# 概要

　シングルテナントの[自社クラウドサービス](https://qiita.com/comefigo/items/1fc1061dd4519bfac0af)をAnsibleで運用しているが、テナント数が増えるのに比例して実行時間も増えるようになってきました。AWXクラスターで運用しているが、それでも一斉実行するとそれなりに時間がかかります。
今回はだれでも手軽に実行時間を短縮できる方法として「タスク数を減らす」を紹介したいと思います。

# さっそく結論

タスク数を減らすために複数のタスクをShellスクリプトに置き換える。
Shellスクリプトとしましたが、考え方としてはタスク数が増えるとその分実行時間が増えるので、1つのタスクに複数の処理をまとめることで実行時間を短縮できればなんでもよいです。
ただし、スクリプトに置き換えたときは冪等性の担保も忘れずに！

# 実験結果

`/home/from/`にあるファイルを`/home/to/`にコピーするタスクをShellスクリプトに置き換えた実験結果になります。
すべて同じ処理ですが、あくまでもタスク数を減らすとこれだけの効果が得られるを紹介するのが目的なのでご了承ください。

**タスクをまとめた時の実行時間：**`0:00:00.258` <<<< **従来通りのタスクを1つずつ実行した時の実行時間：**`0:00:01.580`
処理をまとめたほうが圧勝でした。

今回は非常にシンプルな処理で実験しましたが、タスクのI/Oは塵積でバカにならないと思いますので、興味を持った方は是非一度チャレンジしてみてください。

## 結果詳細（実行ログ）

タスクをまとめた場合

```shell
PLAY [Test] *************************************************************************

TASK [ansible.builtin.shell] *******************************************************************************************
Saturday 07 December 2024  17:49:47 +0900 (0:00:00.024)       0:00:00.024 ***** 
changed: [localhost]

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

Saturday 07 December 2024  17:49:47 +0900 (0:00:00.234)       0:00:00.258 ***** 
=============================================================================== 
ansible.builtin.shell --------------------------------------------------------------- 0.23s
```

1つずつタスクで実行した場合
```shell
PLAY [Test2] *****************************************************************

TASK [copy file1] ************************************************************
Saturday 07 December 2024  17:11:50 +0900 (0:00:00.025) 0:00:00.025 ***** changed: [localhost]

TASK [copy file2] ***********************************************************************************
Saturday 07 December 2024  17:11:50 +0900 (0:00:00.403) 0:00:00.429 ***** changed: [localhost]

TASK [copy file3] *********************************************************************************
Saturday 07 December 2024  17:11:51 +0900 (0:00:00.284)  0:00:00.713 ***** changed: [localhost]

TASK [copy file4] *************************************************************************************
Saturday 07 December 2024  17:11:51 +0900 (0:00:00.280)  0:00:00.994 ***** changed: [localhost]

TASK [copy file5] **************************************************************************************
Saturday 07 December 2024  17:11:51 +0900 (0:00:00.279) 0:00:01.273 ***** changed: [localhost]

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

Saturday 07 December 2024  17:11:52 +0900 (0:00:00.306)       0:00:01.580 ***** 
=============================================================================== 
copy file1 ------ 0.40s
copy file5 ------ 0.31s
copy file2 ------ 0.28s
copy file3 ------ 0.28s
copy file4 ------ 0.28s
```


## 実験環境

```shell
ansible [core 2.15.9]
  config file = /root/.ansible.cfg
  configured module search path = ['/ansible/ansible/playbooks/library']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.16 (main, Jul  5 2024, 00:00:00) [GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
```

## サンプルコード

```shell
#!/bin/bash

# コピー先の冪等性は担保していない
if [ -f "/home/from/file1" ]; then cp /home/from/file1 /home/to/; fi
if [ -f "/home/from/file2" ]; then cp /home/from/file2 /home/to/; fi
if [ -f "/home/from/file3" ]; then cp /home/from/file3 /home/to/; fi
if [ -f "/home/from/file4" ]; then cp /home/from/file4 /home/to/; fi
if [ -f "/home/from/file5" ]; then cp /home/from/file5 /home/to/; fi

```

```yaml
# シェルスクリプトでまとめて処理
- name: Test
  hosts: localhost
  gather_facts: False
  tasks:
    - ansible.builtin.shell: "/home/copy.sh"
      args:
        executable: /bin/bash
```

```yaml
# タスクで１つずつ処理
---
- name: Test2
  hosts: localhost
  gather_facts: False
  tasks:
    - name: copy file1
      ansible.builtin.copy:
        src: "/home/from/file1"
        dest: "/home/to/"
    - name: copy file2
      ansible.builtin.copy:
        src: "/home/from/file2"
        dest: "/home/to/"
    - name: copy file3
      ansible.builtin.copy:
        src: "/home/from/file3"
        dest: "/home/to/"
    - name: copy file4
      ansible.builtin.copy:
        src: "/home/from/file4"
        dest: "/home/to/"
    - name: copy file5
      ansible.builtin.copy:
        src: "/home/from/file5"
        dest: "/home/to/"
```