Ansible之Playbooks的when语句

在使用ansible做自动化运维的时候,大多数情况下都执行某些任务的时候都需要依赖某个变量的值或者是上一个任务的执行结果。如,根据facts信息中的系统版本相关的信息来确定使用哪种包管理器安装软件。Ansible提供when语句,可以控制任务的执行流程。

一个很简单的when语句的例子:


1

2

3

4

    tasks:

      - name: "shutdown Debian flavored systems"

        command: /sbin/shutdown -t now

        when: ansible_os_family == "Debian

表示当节点主机系统为Debian的时候,执行关机操作。

在符合语句中也可以使用小括号:


1

2

3

4

5

    tasks:

      - name: "shutdown CentOS 6 and 7 systems"

        command: /sbin/shutdown -t now

        when: ansible_distribution == "CentOS" and

              (ansible_distribution_major_version == "6" or ansible_distribution_major_version == "7")

在`when`语句中也可以使用过滤器。如,我们想跳过一个语句执行中的错误,但是后续的任务的执行需要由该任务是否成功执行决定:


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

有时候需要将一个字符串的变量转换为整数来进行数字比较:


1

2

3

    tasks:

      - shell: echo "only on Red Hat 6, derivatives, and later"

        when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

在playbooks和inventory中定义的变量都可以使用,如,需要根据一个变量的bool值决定是否执行该任务:


1

2

    vars:

      epic: true

条件语句:


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

如果引用的变量没有被定义,使用Jinja2的`defined`测试,可以跳过或者是抛出错误:


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

当`when`和`with_items`一起使用的时候,每个项都会单独被`when`语句处理:


1

2

3

4

    tasks:

        - command: echo {{ item }}

          with_items: [ 0246810 ]

          when: item > 5

示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

[[email protected] ~]# cat /etc/ansible/when.yml

    ---

    - hosts: webservers

      remote_user: root

      tasks:

       - command: echo {{ item }}

         with_items: [ 1,2,3,4,5,6,8,10]

         when: item > 5

    [[email protected] ~]# ansible-playbook /etc/ansible/when.yml

    

    PLAY [webservers] *************************************************************

    

    GATHERING FACTS ***************************************************************

    ok: [192.168.1.65]

    

    TASK: [command echo {{ item }}] ***********************************************

    skipping: [192.168.1.65=> (item=1)

    skipping: [192.168.1.65=> (item=2)

    skipping: [192.168.1.65=> (item=3)

    skipping: [192.168.1.65=> (item=4)

    skipping: [192.168.1.65=> (item=5)

    changed: [192.168.1.65=> (item=6)

    changed: [192.168.1.65=> (item=8)

    changed: [192.168.1.65=> (item=10)

    

    PLAY RECAP ********************************************************************

    192.168.1.65               : ok=2    changed=1    unreachable=0    failed=0

如果需要的话,也可以返回自定义的facts给控制节点。返回的自定义的facts变量也可以用作下个任务的执行条件:


1

2

3

4

5

    tasks:

        - name: gather site specific fact data

          action: site_facts

        - command: /usr/bin/thingy

          when: my_custom_fact_just_retrieved_from_the_remote_system == ‘1234‘

在角色和包含中使用when

如果有多个任务都需要使用同一个条件语句控制。可以将这些任务打包到一个单独的任务文件中,然后使用`include`包含和`when`条件语句。条件语句只对包含任务文件起作用,对包含playbook文件不起作用。指定的条件语句会作用到所包含的每个任务上:


1

2

 - include: tasks/sometasks.yml

      when: "‘reticulating splines‘ in output"

角色中使用when


1

2

3

  - hosts: webservers

      roles:

         - { role: debian_stock_config, when: ansible_os_family == ‘Debian‘ }

注册变量

在playbook中将某个命令运行的结果保存起来,提供给后续任务使用。如,通过command模块来判断远程节点上某个文件是否存在或者通过执行某个命令的获取其返回结果,并保存起来,下个任务根据获取的变量值来决定执行的具体操作。

register关键字可以将任务执行结果保存到一个变量中,该变量可以在模板或者playbooks文件中使用:


1

2

3

4

5

6

7

8

9

10

 - name: test play

      hosts: all

    

      tasks:

    

          - shell: cat /etc/motd

            register: motd_contents

    

          - shell: echo "motd contains the word hi"

            when: motd_contents.stdout.find(‘hi‘) != -1

上边中的例子中,通过注册变量访问返回的内容,`stdout`里面保存了命令的标准输出内容。注册变量还可以使用在`with_items`中,如果其保存的内容可以转换为列表,或者内容本身就是个列表。如果命令的输出本身就是列表,可以通过`stdout_lines`访问:


1

2

3

4

5

6

7

8

9

10

11

12

13

 - name: registered variable usage as a with_items list

      hosts: all

    

      tasks:

    

          - name: retrieve the list of home directories

            command: ls /home

            register: home_dirs

    

          - name: add home dirs to the backup spooler

            file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link

            with_items: home_dirs.stdout_lines

            # same as with_items: home_dirs.stdout.split()

示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

[[email protected] ~]# cat /etc/ansible/rewith.yml

    ---

    - hosts: webservers

      remote_user: root

      tasks:

       - name: list of home dir

         command: ls /home

         register: home_dirs

       - name: add home dirs to the backup

         file: path=/tmp/back/{{ item }} src=/home/{{ item }} state=link

         with_items: home_dirs.stdout_lines

    [[email protected] ~]# ansible-playbook /etc/ansible/rewith.yml

    

    PLAY [webservers] *************************************************************

    

    GATHERING FACTS ***************************************************************

    ok: [192.168.1.65]

    

    TASK: [list of home dir******************************************************

    changed: [192.168.1.65]

    

    TASK: [add home dirs to the backup] *******************************************

    changed: [192.168.1.65=> (item=1.sql)

    changed: [192.168.1.65=> (item=1youku.sql)

    changed: [192.168.1.65=> (item=liuzhenwei)

    changed: [192.168.1.65=> (item=tom)

    

    PLAY RECAP ********************************************************************

    192.168.1.65               : ok=3    changed=2    unreachable=0    failed=0

    ###远程节点

    [[email protected] ~]# ll /tmp/back

    total 0

    lrwxrwxrwx. 1 root root 11 Aug  4 14:37 1.sql -/home/1.sql

    lrwxrwxrwx. 1 root root 16 Aug  4 14:37 1youku.sql -/home/1youku.sql

    lrwxrwxrwx. 1 root root 16 Aug  4 14:37 liuzhenwei -/home/liuzhenwei

    lrwxrwxrwx. 1 root root  9 Aug  4 14:37 tom -/home/tom

在ansible中when语句的使用还是比较多的,它可以用来控制playbooks中任务的执行流程。类似于程序中的条件语句一样,使得ansible可以更好的按照运维人员的意愿来对远程节点执行特定的操作。

时间: 2024-07-31 06:17:01

Ansible之Playbooks的when语句的相关文章

自动化运维工具Ansible之Playbooks循环语句

在使用ansible做自动化运维的时候,免不了的要重复执行某些操作,如:添加几个用户,创建几个MySQL用户并为之赋予权限,操作某个目录下所有文件等等.好在playbooks支持循环语句,可以使得某些需求很容易而且很规范的实现. with_items是playbooks中最基本也是最常用的循环语句. - name: add several users   user: name={{ item }} state=present groups=wheel   with_items:      - t

自动化运维工具Ansible之Playbooks变量的使用

在平时运维工作中有时候需要根据不同的远程节点或者针对不同的IP的系统做不同的配置部署.如,Ansible可以根据不同的IP地址来对各个节点上的配置文件做不同的处理,这里就需要用到变量. 可以在playbooks文件中直接定义变量: - hosts: webservers   vars:     http_port: 80 定义了一个变量名为http_port的变量,值为80. 通过文件包含和角色定义变量 [[email protected] ~]# cat /etc/ansible/roles/

Ansible的几个基本语句

如约签约了新东家,环境很不错,同事人都很随和,领导也很好说话,加班福利很赞,总而言之,好好工作,多多挣钱. 批处理工具我最早接触的是pssh,因为它实在很简单粗暴,但是它由于太简单粗暴了,应付十台二十台机器还OK,应付五十台一百台服务器就心有余力不足了,而且我还不太喜欢puppet,总觉得那玩意跟我八字不合,于是乎,在新头头的推荐下,我把目光放在了Ansible. Ansible的安装很简单,在Redhat环境下直接#yum install ansible -y就行.Redhat已经将Ansib

自动化运维工具Ansible之Playbooks的roles和include

当需要对多个远程节点,做很多操作的时候,如果将所有的内容都书写到一个playbooks中,这就会产生一个很大的文件,而且里面的某些内容也很难复用.此时不得不考虑怎么样分隔及组织相关的文件. 最基本的,可以将任务列表单独分隔到一个小文件里,然后在tasks中包含该文件即可.同样的handlers其实也是一个任务列表(里面指定的任务都需要有一个全局唯一的名称),所以也可以在handlers中包含单独定义好的handlers任务文件. playbooks也可以包含其他playbooks文件. play

Ansible之playbooks

playbook是一个或多个"paly"组成的列表.play的主要功能在于将事先并归为一组的主机扮成事先通过ansible中task定义好的角色,从根本上将,所谓的task就是调用ansible的一个module.将多个play组织的一个playbook中就可以让它们连同起来按事先安排的机制同唱一台大戏. 下面是一个简单的示例 /etc/ansible/playbooks/nginx.yml 分析 1.定义了执行的远程主机是 webservers组,这个组定义主机有(192.168.8

Ansible Playbook 使用条件判断语句

先介绍一下 gather_facts 参数,该参数用于指定在执行任务前,是否先执行 setup 模块获取主机相关信息,以便给后面的任务使用 [[email protected] ~]# ansible 192.168.119.134 -m setup # 查看主机的facter信息 192.168.119.134 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "19

Ansible Playbooks学习

Ansible的Playbooks是Ansible用于配置,部署应用的结构化语言.Ansible的模块就好比shell命令,那么playbooks就好比shell脚本,在脚本中指定怎么使用哪些命令再加上一些判断语句等等. Playbooks使用YAML文件来表示执行步骤. --- - hosts: webservers   vars:     http_port: 80     max_clients: 200   remote_user: root   tasks:   - name: ens

Ansible 自动化运维工具之when条件语句

1.When语句 有时候用户有可能需要某一个主机越过某一个特定的步骤.这个过程就可以简单的像在某一个特定版本的系统上少装了一个包一样或者像在一个满了的文件系统上执行清理操作一样. 这些操作在Ansible上,若使用`when`语句都异常简单.When语句也含Jinja2表达式, 第一个例子: tasks:   - name: "shutdown Debian flavored systems"     command: /sbin/shutdown -t now     when: a

ansible批量管理远程服务器

使用ansible批量管理远程服务器 背景 本地需要管理远程的一批服务器,主要执行以下任务: 1) 将本地的文件复制到远端所有服务器:  2) 需要在远程服务器中执行一个个命令: 远端服务器路径并非完全一致,一般访问通过环境变量中定义的变量路径访问:  比如在.bashrc中定义$app_path=/opt/app/bin 最终选择ansible,使用这个自动化运维工具可以满足我的需求:  下面介绍下对于我这种场景需要使用的ansible的主要模块:  关于ansible是什么以及安装配置请自行