playbook也有逻辑控制的语句:
when: 条件判断语句,类似于编程语言中的if
loop: 循环语句,类似于编程语言的中的while
block: 把几个tasks组成一块代码,便于针对一组操作的异常处理等操作。
条件语句When 类似于编程语言的if
When语句 有时候用户有可能需满足特定条件才执行某一个特定的步骤。例如,在某个特定版本的系统上装包,或者只在磁盘空间满了的文件系统上执行清理操作。这些操作在Playbook中用when语句实现。
主机为Debian Linux立刻关机
1 2 3 4 tasks: - name: "shutdown Debian flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "Debian"
根据action的执行结果,来决定接下来执行的action。
1 2 3 4 5 6 7 8 9 10 tasks: - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|success - command: /bin/still/something_else when: result|skipped
远程中的系统变量facts变量作为when的条件,用“|int”还可以转换返回值的类型:
1 2 3 4 5 --- - hosts: web tasks: - debug: msg="only on Red Hat 7, derivatives, and later" when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
条件表达式
基本款
1 2 3 tasks: - shell: echo "This certainly is epic!" when: epic
否定款:
1 2 3 tasks: - shell: echo "This certainly isn't epic!" when: not epic
变量定义款
1 2 3 4 5 6 tasks: - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is not defined
数值表达款
1 2 3 4 tasks: - command: echo {{ item }} with_items: [ 0, 2, 4, 6, 8, 10 ] when: item > 5
与Include一起用 1 2 - include: tasks/sometasks.yml when: "'reticulating splines' in output"
与Role一起用 1 2 3 - hosts: webservers roles: - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
Loop循环 标准循环 为了保持简洁,重复的任务可以用以下简写的方式:
1 2 3 4 5 - name: add several users user: name={{ item }} state=present groups=wheel with_items: - testuser1 - testuser2
如果你在变量文件中或者 ‘vars’ 区域定义了一组YAML列表,你也可以这样做:
1 2 3 4 5 6 vars: somelist: ["testuser1", "testuser2"] tasks: -name: add several user user: name={{ item }} state=present groups=wheel with_items: "{{somelist}}"
使用 ‘with_items’ 用于迭代的条目类型不仅仅支持简单的字符串列表.如果你有一个哈希列表,那么你可以用以下方式来引用子项:
1 2 3 4 5 - name: add several users user: name={{ item.name }} state=present groups={{ item.groups }} with_items: - { name: 'testuser1', groups: 'wheel' } - { name: 'testuser2', groups: 'root' }
注意:如果同时使用 when 和 with_items (或其它循环声明),when
声明会为每个条目单独执行.请参见 the_when_statement 示例.
嵌套循环 循环也可以嵌套:
1 2 3 4 5 - name: give users access to multiple databases mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo with_nested: - [ 'alice', 'bob' ] - [ 'clientdb', 'employeedb', 'providerd']
或者
1 2 3 4 5 - name: give users access to multiple databases mysql_user: name={{ item.0 }} priv={{ item.1 }}.*:ALL append_privs=yes password=foo with_nested: - [ 'alice', 'bob' ] - [ 'clientdb', 'employeedb', 'providerd']
对哈希表使用循环 1 2 3 4 5 6 7 8 9 10 11 12 13 --- vars: users: alice: name: Alice Appleworth telephone: 123-456-7890 bob: name: Bob Bananarama telephone: 987-654-3210 tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}"
对文件列表使用循环 with_fileglob 可以以非递归的方式来模式匹配单个目录中的文件.如下面所示:
1 2 3 4 5 6 7 8 9 tasks: # first ensure our target directory exists - file: dest=/etc/fooapp state=directory # copy each file over that matches the given pattern - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600 with_fileglob: - /playbooks/files/fooapp/*
Block块 多个action组装成块,可以根据不同条件执行一段语句 :
1 2 3 4 5 6 7 8 9 10 11 tasks: - block: - yum: name={{ item }} state=installed with_items: - httpd - memcached - template: src=templates/src.j2 dest=/etc/foo.conf - service: name=bar state=started enabled=True when: ansible_distribution == 'CentOS' become: true become_user: root
组装成块处理异常更方便:
1 2 3 4 5 6 7 8 9 10 11 tasks: - block: - debug: msg='i execute normally' - command: /bin/false - debug: msg='i never execute, cause ERROR!' rescue: - debug: msg='I caught an error' - command: /bin/false - debug: msg='I also never execute :-(' always: - debug: msg="this always executes"