【小ネタ】Ansible Vaultで暗号化された文字列が関数を挟むと何故かデコードされない場合は

Ansible Vaultはパスワードなど秘密をキーファイルで暗号化してリポジトリに入れられるので便利です。[^1]

[^1]: もちろんキーファイルはリポジトリに入れてはいけません。

```yaml:group_vars/all.yml
# $ ansible-vault encrypt_string --encrypt-vault-id production 'Passw0rd!'
secret_string: !vault |
          $ANSIBLE_VAULT;1.2;AES256;production
          63303765363236336162663032356433396165336163666439326638356231313166373066636564
          3133396434386262373862656662623066346166343437650a366463343239346134303137303831
          61613062643835393435666138653364656261303062306663656637343362336532316465323066
          3936326532633831650a336162393538366337396432633232343635663561633663623862366535
          3861
```

通常、こういった暗号化文字列はAnsibleを実行する際に透過的にデコードされるのですが、

```yaml:playbook.yml
- hosts: localhost
  gather_facts: false
  tasks:
     - ansible.builtin.debug:
         msg: "{{ secret_string }}"
```

```bash
$ ansible-playbook playbook.yml
PLAY [localhost] ********************************************************************************************************************************************************************************************************************************************************************************************************

TASK [ansible.builtin.debug] ********************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Passw0rd!"
}
```

たとえば、これを何かの関数に通すと、デコードをサボり始めることがあります。

```yaml:playbook.yml
- hosts: localhost
  gather_facts: false
  tasks:
     - ansible.builtin.debug:
         # to_nice_yaml を介するとデコードしなくなる
         msg: "{{ secret_string | to_nice_yaml() }}"
```

```bash
TASK [ansible.builtin.debug] ********************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "!vault |\n    $ANSIBLE_VAULT;1.2;AES256;production\n    63303765363236336162663032356433396165336163666439326638356231313166373066636564\n    3133396434386262373862656662623066346166343437650a366463343239346134303137303831\n    61613062643835393435666138653364656261303062306663656637343362336532316465323066\n    3936326532633831650a336162393538366337396432633232343635663561633663623862366535\n    3861\n"
}
```

Ansible内部のデコード関数に到達していないためこうなってしまうと思われるのですが、こういった **Ansible Vault文字列がデコードされない場合は、パイプラインの途中で一旦 `| string` を挟んであげるとデコードし始めるようになります**。（あまり気持ちのいい挙動ではないですが）

```yaml:playbook.yml
- hosts: localhost
  gather_facts: false
  tasks:
     - ansible.builtin.debug:
         # string でデコードされるようになる
         msg: "{{ secret_string | string | to_nice_yaml() }}"
```

```bash
TASK [ansible.builtin.debug] ********************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Passw0rd!\n"
}
```