细节

细节

是否可以根据某些条件(即另一个变量的值)改变角色变量的默认值?

细节

我有两个与命令相关的变量,envcomposer_opts

如果两者都保留默认值(env = "prod"composer_opts = "--no-dev"),则一切正常。

如果我更改envdev,另一个的默认值将破坏我的命令,因此我总是需要同时设置两者。是否可以通过使用自定义脚本 / if 设置条件默认值来避免这种情况?

重要提示:我不想总是composer_opts根据值设置值env。我只想在尚未设置时设置它(即动态默认值)。

伪代码

我想做这样的事情(以下代码无效,只是伪代码来表达我的需要)

---
# defaults/main.yml

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

答案1

我建议这个解决方案:

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

当变量等于' '时,它会将composer_opts变量设置为字符串。""envdev

以下是基于更新问题的剧本示例:

$ 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   

答案2

尽管@Navern 的回答确实有效,但我发现嵌入的 Jinja2 符号 ( "{% if env == 'prod' %} ...) 极易受到符号的影响,因此相当脆弱。例如,当为了更好的可读性而换行时,例如在这个未经测试的代码

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

我最终得到了意想不到的结果,例如额外的空格\ncomposer_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'

我还发现这篇博文是有用的,其本质上遵循相同的方法。

答案3

Ansible set_fact 根据条件一行:

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

答案4

- name: 

set_fact:path_install:| {% 如果 reportviewer_state == 'absent' 并且 reportviewer_handler[reportviewer_package].name == 'ReportViewer_2010.exe' %} C:\Windows\System32\msiexec.exe {% else %} {{ url_base_repository }}{{ reportviewer_handler[reportviewer_package].name }} {% endif %}

  • 名称:“安装 {{ reportviewer_handler[reportviewer_package].name }}” win_package:路径:“{{ path_install | replace('\n', '') }}” 状态:“{{ reportviewer_state }}” product_id:“{{ reportviewer_handler[reportviewer_package].product_id }}” 参数:“{{ reportviewer_handler[reportviewer_package].arguments }}”

相关内容