Score:0

ansible main.yml if else conditionals

us flag

So I'm running an ansible role which has a file main.yml in the defaults/ role folder. The content of that file is this:

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

Now I want to include to the api_secrets block, after the MGMT_SERVER_ADDRESS something like this:

{% 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 %}

With everything from here, a file is created on the server having the content above and of course replacing the variables with their actual values.

No matter how I try, it always results in different errors. I tried with "{% if ... endif %}", also with ''

The error would be this:

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

I've also tried like this:

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

In this case the error is:

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 }}"

What's the proper way to do this?

I know it would have been easier by using a jinja2 template but the playbooks are created like this and I have to stick to this method.

Score:1
th flag

Templating of variables happens well after the YAML parsing step, so you cannot use it to template YAML in this way.

The easiest approach is to move the condition into the individual Jinja expressions:

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 }}"

You can also use Jinja statements, though that makes the value a bit lengthier for the same result.

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 %}"
Score:0
lr flag

Ansible is not meant to treat If-Else-Statements.

As you mentioned in the bottom of your question, with jinja2 templates it would be easier, but it would not just be easier, but it would make it the correct way to do it.

So instead of trying to mess up your yaml file with if-else statements, create a single jinja2 file with the required template parameters (looks like you pretty much got jinja2 template structure anyways!) and create a configuration file using that.

Then you can do a template command to include the template in the correct location with the correct parameters.

"Playbooks are created like this and I have to stick to this method" yells that whoever came up with that policy is either insecure or just a child.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.