Ansible:当一个;什么时候;条件*不*满足?

Ansible:当一个;什么时候;条件*不*满足?,ansible,ansible-playbook,Ansible,Ansible Playbook,我有以下Ansible剧本代码: - name: Users | Generate password for user (Debian/Ubuntu) shell: makepasswd --chars=20 register: make_password when: ansible_distribution in ['Debian', 'Ubuntu'] - name: Users | Generate password for user (Fedora) shell: ma

我有以下Ansible剧本代码:

- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password
  when: ansible_distribution in ['Debian', 'Ubuntu']

- name: Users | Generate password for user (Fedora)
  shell: makepasswd -m 20 -M 20
  register: make_password
  when: ansible_distribution in ['Fedora', 'Amazon']

- name: Users | Generate password for user (CentOS)
  shell: mkpasswd -l 20
  register: make_password
  when: ansible_distribution in ['CentOS']

- name: debug
  debug: var=make_password
哪些产出:

TASK: [users | debug] 
ok: [127.0.0.1] => {
                     "var": {
                       "make_password": {
                         "changed": false,
                         "skipped": true
                       }
                     }
                   }
。。。因为每个
寄存器
块都会执行,而不管
何时
条件如何

我如何修复此问题,使
密码在
条件不满足时不会被覆盖


或者,如果这是一个错误的方法,你可以看到我正在努力实现,让我知道一个更好的。

不幸的是,这是预期的行为。从

注意 如果任务失败或被跳过,变量仍将被注册 对于失败或跳过状态,避免注册 变量正在使用标记

我不知道如何使用标签来解决您的问题

编辑:我找到了一种方法,尽管这是一个粗糙的解决方案。存储结果,使其不会被覆盖

  - set_fact: mypwd="{{make_password}}"
    when: make_password.changed
因此,您的代码将如下所示:

- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password
  when: ansible_distribution in ['Debian', 'Ubuntu']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: Users | Generate password for user (Fedora)
  shell: makepasswd -m 20 -M 20
  register: make_password
  when: ansible_distribution in ['Fedora', 'Amazon']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: Users | Generate password for user (CentOS)
  shell: mkpasswd -l 20
  register: make_password
  when: ansible_distribution in ['CentOS']

- set_fact: mypwd="{{make_password}}"
  when: make_password.changed

- name: debug
  debug: var=mypwd

也许将所有变体放在一个shell脚本中,然后只运行该脚本而不是多个Ansible任务是有意义的

脚本可以检测操作系统,也可以只对传递的参数作出反应

#!/bin/bash

case "$1" in
"Debian" | "Ubuntu")
    makepasswd --chars=20
    ;;
"Fedora" | "Amazon")
    makepasswd -m 20 -M 20
    ;;
"CentOS")
    mkpasswd -l 20
    ;;
*)
    echo "Unexpected distribution" 1>&2
    exit 1
    ;;
esac
将其作为
make_password.sh
放入角色的脚本文件夹中,然后将其命名为:

- name: Users | Generate password for user
  script: make_password.sh {{ ansible_distribution }}
  register: make_password

另一个想法:您似乎实际上是远程生成密码,注册输出,然后在以后的其他任务中使用它。如果您可以保证Ansible主主机始终是相同类型的,并且不是每个团队成员都使用不同的分发版,那么您可以在本地运行该任务

假设您使用Ubuntu:

- name: Users | Generate password for user
  shell: makepasswd --chars=20
  delegate_to: localhost
  register: make_password

这些任务是在运行Ansible的主机上本地执行的,通过
delegate_to

通常对于在不同发行版上运行不同的任务,我倾向于包括一个发行版特定的剧本,然后有条件地包括在main.yml中

因此,示例可能如下所示:

main.yml: Debian.yml 显然,对其他两个发行版重复上述步骤


通过这种方式,您可以使main.yml只运行角色的所有通用任务,这些任务可以在任何发行版上运行,但需要不同的任务可以在发行版特定的剧本中运行。因为include是有条件的,如果不满足条件,它甚至不会加载任务,所以不应该注册变量。

在var文件中定义dict如何

猫vars.yml cat test.yml 运行结果:

TASK: [get mkpasswd]
ok: [10.10.10.1] => {
    "mkpasswd -l 20": "mkpasswd -l 20"
}

我不确定你在这里的想法是否正确。ansible文档(playbooks_conditionals)状态(emphasis mine):>请注意,如果您有多个任务共享同一个条件语句,则可以将条件附加到任务包含语句,如下所示。所有任务都会得到评估,但条件应用于每个任务。这真的很有帮助,谢谢。有时我想知道ansible是否能帮我节省时间。这似乎是“when”和“register”的一个非常常见的用例。。。
- name: Users | Generate password for user (Debian/Ubuntu)
  shell: makepasswd --chars=20
  register: make_password
make_password: {
                'Debian':'makepasswd --chars=20',
                'Ubuntu':'makepasswd --chars=20',
                'Fedora':'makepasswd -m 20 -M 20',
                'Amazon':'makepasswd -m 20 -M 20',
                'CentOS':'mkpasswd -l 20'
                }
---
- hosts: "{{ host }}"
  remote_user: root
  vars_files:
    - vars.yml 
 tasks:
    - name: get mkpasswd
      debug: var="{{ make_password[ansible_distribution] }}"
TASK: [get mkpasswd]
ok: [10.10.10.1] => {
    "mkpasswd -l 20": "mkpasswd -l 20"
}