Ansible Tips:  文字列中の {{ や }} などをエスケープする2つの方法

備忘

# 環境
Fedora Linux 36 (Workstation Edition)
ansible                           4.8.0
ansible-core                      2.11.6




# I. 単純に文字列中で利用


## a. 文字列中に {{ }} や {% %} を含める場合、{% raw %} ... {% endraw %} が使用可能



### Task例1

```yaml
- debug:
    msg: "文字列の参照は {% raw -%} '{{ 変数 }}' {%- endraw %} にて可能です"
```

この例では -%} によりその後の空白を、{%- によりその前の空白を除去。

## b. !unsafe を付与することでJinja2処理をさせないことが可能。


### Task例2
 

```yaml
- debug:
    msg: !unsafe "文字列の参照は '{{ 変数 }}' にて可能"
```


### 例1,2の実行例 ◯

何れも以下の樣な出力となる

```
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "文字列の参照は '{{ 変数 }}' にて可能です"
}
```

# II. 変数に設定し、参照

## a. {% raw %} ... {% endraw %} 利用ケース

設定時にエスケープ指示が消えてしまう為、参照時にJinja2が適用されて問題となる。

### Task例
```yaml
- set_fact:
    foo: "文字列の参照は {% raw -%} '{{ 変数 }}' {%- endraw %} にて可能"
- debug: { var: foo }
- debug: { var: foo|type_debug }
```


### 実行結果 ×

設定時にエスケープ指示が消えてしまう為、参照時に意図せずJinja2が適用されてしまい問題となりうる。
設定される文字列に{% raw %} ... {% endraw %}を残せば良いのだろうが、エスケープ指示のエスケープとなるのでかなり複雑になりそう。
ここではこれ以上追求しない。


```
TASK [set_fact] ******************************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts": {
        "foo": "文字列の参照は '{{ 変数 }}' にて可能"
    },
    "changed": false
}

TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "foo": "VARIABLE IS NOT DEFINED!: 文字列の参照は '{{ 変数 }}' にて可能: '変数' is undefined"
}

TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "foo|type_debug": "VARIABLE IS NOT DEFINED!: 文字列の参照は '{{ 変数 }}' にて可能: '変数' is undefined"
```



## b. !unsafe 利用ケース

こちらは問題なく使用可能。

### Task例

```yaml
- set_fact:
    foo: !unsafe "文字列の参照は '{{ 変数 }}' にて可能"
- debug: { var: foo }
- debug: { var: foo|type_debug }
```

### 実行結果 ◯

```
TASK [set_fact] ******************************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts": {
        "foo": "文字列の参照は '{{ 変数 }}' にて可能"
    },
    "changed": false
}

TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "foo": "文字列の参照は '{{ 変数 }}' にて可能"
}

TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "foo|type_debug": "AnsibleUnsafeText"
```
問題なく使用できている
AnsibleUnsafeText というタイプが目新しい



# 参考
https://jinja.palletsprojects.com/en/3.0.x/templates/#escaping
https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_advanced_syntax.html#raw