ansible main.yml if else 条件

ansible main.yml if else 条件

因此,我正在运行一个 ansible 角色,该角色在 defaults/role 文件夹中有一个文件 main.yml。该文件的内容如下:

---
api_secrets:
  'API_PROFILE': "{{ api_profile }}"
  'SERVER_ADDRESS': "{{ server_address }}"
  'MGMT_SERVER_ADDRESS': "{{ management_server_address }}"

现在我想将其添加到 api_secrets 块中,在管理服务器地址像这样:

{% if '"port" in mgmt_ports' %}
'MGMT_SERVER_PORT': "{{ management_server_port1 }}"
'MGMT_SERVER_USER': "{{ user1 }}"
{% else %}
'MGMT_SERVER_PORT': "{{ management_server_port2 }}"
'MGMT_SERVER_USER': "{{ user2 }}"
{% endif %}

完成此处的所有内容后,将在服务器上创建一个包含上述内容的文件,当然还会用变量的实际值替换它们。

无论我如何尝试,它总是会导致不同的错误。我尝试使用“{% if ... endif %}”,也尝试使用“”

错误可能是这样的:

ERROR! Syntax Error while loading YAML.
  found character that cannot start any token

The error appears to be in '/opt/ansible/roles/api/defaults/main.yml': line 55, column 2, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

{% if '"port" in mgmt_ports' %}
 ^ here

我也尝试过这样的方法:

   "{% if (port in mgmt_ports) %}
   'MGMT_SERVER_PORT': "{{ management_server_port1 }}"
   {% else %}
   'MGMT_SERVER_PORT': "{{ management_server_port2 }}"
   {% endif %}"

在这种情况下,错误是:

ERROR! Syntax Error while loading YAML.
  could not find expected ':'

The error appears to be in '/opt/ansible/roles/api/defaults/main.yml': line 56, column 24, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  "{% if (port in mgmt_ports) %}
  'MGMT_SERVER_PORT': "{{ management_server_port1 }}"
                       ^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

正确的做法是什么?

我知道使用 jinja2 模板会更容易,但是剧本就是这样创建的,我必须坚持使用这种方法。

答案1

变量的模板化发生在 YAML 解析步骤之后,因此您不能以这种方式使用它来模板化 YAML。

最简单的方法是将条件移到各个 Jinja 表达式中:

api_secrets:
  API_PROFILE: "{{ api_profile }}"
  SERVER_ADDRESS: "{{ server_address }}"
  MGMT_SERVER_ADDRESS: "{{ management_server_address }}"
  MGMT_SERVER_PORT: "{{ management_server_port1 if 'port' in mgmt_ports else management_server_port2 }}"
  MGMT_SERVER_USER: "{{ user1 if 'port' in mgmt_ports else user2 }}"

您也可以使用 Jinja 语句,尽管这会使相同结果的值稍微长一些。

api_secrets:
  API_PROFILE: "{{ api_profile }}"
  SERVER_ADDRESS: "{{ server_address }}"
  MGMT_SERVER_ADDRESS: "{{ management_server_address }}"
  MGMT_SERVER_PORT: "{% if 'port' in mgmt_ports %}{{ management_server_port1 }}{% else %}{{ management_server_port2 }}{% endif %}"
  MGMT_SERVER_USER: "{% if 'port' in mgmt_ports %}{{ user1 }}{% else %}{{ user2 }}{% endif %}"

答案2

Ansible 不适用于处理 If-Else 语句。

正如您在问题底部提到的那样,使用 jinja2 模板会更容易,但它不仅会更容易,而且还会使其成为正确的方法。

因此,不要试图用 if-else 语句弄乱你的 yaml 文件,而是创建一个带有所需模板参数的 jinja2 文件(看起来你已经获得了 jinja2 模板结构!)并使用该文件创建一个配置文件。

然后,您可以执行模板命令,将模板使用正确的参数包含在正确的位置。

“剧本就是这样制定的,我必须坚持这种方法”大喊,无论是谁想出这个政策,要么没有安全感,要么就是个孩子。

相关内容