Назад | Перейти на главную страницу

Возможное изменение значения по умолчанию в соответствии с условием

Можно ли изменить значение по умолчанию для ролевой переменной в соответствии с каким-либо условием (то есть значением другой переменной)?

подробности

У меня есть две связанные переменные для команды, env и composer_opts.

Если оба оставлены по умолчанию (env = "prod" и composer_opts = "--no-dev") все в порядке.

Если я изменю env к dev, значение по умолчанию для другого нарушит мою команду, поэтому мне всегда нужно устанавливать оба. Можно ли этого избежать, установив условное значение по умолчанию с помощью специального скрипта / if?

Важно: я не хочу всегда установить composer_opts стоимость в соответствии с env стоимость. Я хочу установить его, только если он еще не установлен (т.е. динамическое значение по умолчанию).

Псевдокод

Я хотел бы сделать что-то подобное (следующий код недействителен, просто псевдокод, чтобы выразить мою потребность)

---
# defaults/main.yml

env: prod
composer_opts: 
    when: "{{env}}" = 'prod'
        '--no-dev --optimize-autoloader --no-interaction'
    when: "{{env}}" = 'dev'
        '' 

Предлагаю такое решение:

---
 - set_fact:
     composer_opts: ""
   when: "{{env}}" == 'dev'

Он установит composer_opts переменная в строку "" когда переменная env равно 'dev'.

Вот пример playbook на основе обновленного вопроса:

$ cat test.yml

---
- hosts: 127.0.0.1
  connection: local
  tasks:
  - set_fact:
      composer_opts: "{% if env == 'prod' %} '--no-dev --optimize-autoloader --no-interaction' {% else %} '' {% endif %}"

  - debug: var=composer_opts

Пример вывода:

sudo ansible-playbook test.yml -e env=dev

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '' ": " '' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   


sudo ansible-playbook test.yml -e env=prod

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '--no-dev --optimize-autoloader --no-interaction' ": " '--no-dev --optimize-autoloader --no-interaction' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   

Пока @ Ответ Наверна действительно работает, я нашел встроенную нотацию Jinja2 ("{% if env == 'prod' %} ...), чтобы быть чрезвычайно восприимчивым к обозначениям и, следовательно, довольно хрупким. Например, при переносе рассматриваемой строки для лучшей читаемости, как в этом непроверенный код:

composer_opts: >
               "{% if env == 'prod' %}
                   '--no-dev --optimize-autoloader --no-interaction'
                {% else %}
                   ''
                {% endif %}"

Я получил неожиданные результаты, такие как дополнительные пробелы или \n в composer_opts.

Подход, который я использую, намного тупее, но и более стабилен:

- name: set composer_opts for dev env
  set_fact:
     composer_opts: ''
     when: "{{env}}" == 'dev'

- name: set composer_opts for prod env
  set_fact:
     composer_opts: '--no-dev --optimize-autoloader --no-interaction'
     when: "{{env}}" == 'prod'

Я также нашел это сообщение в блоге быть полезным, который, по сути, следует тому же подходу.

Ansible set_fact на основе условия в одном лайнере:

- name: "set composer_opts based on environment"
  set_fact:
     composer_opts:  "{{ '--no-dev --optimize-autoloader --no-interaction' if (env == 'prod') else '' }}"