Можно ли изменить значение по умолчанию для ролевой переменной в соответствии с каким-либо условием (то есть значением другой переменной)?
У меня есть две связанные переменные для команды, 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 '' }}"