天天看点

04@ansible playbook语句详解

文章目录

  • ​​playbook条件语句​​
  • ​​一、根据不同的操作系统安装apache​​
  • ​​1、示例​​
  • ​​2、使用括号对条件进行分组​​
  • ​​3、指定多条件为列表​​
  • ​​4、条件运算​​
  • ​​5、rsync(剧本)​​
  • ​​6、register命令(执行结果保存变量,通过when语句进行判断)​​
  • ​​二、playbook循环语句​​
  • ​​1、启动多个服务​​
  • ​​2、定义变量(循环)​​
  • ​​3、字典循环​​
  • ​​三、playbook——handlers​​
  • ​​四、playbook任务标签​​
  • ​​1、标签方式​​
  • ​​2、标签的使用​​
  • ​​3、使用标签(-t)​​
  • ​​五、playbook(文件复用)​​
  • ​​1、示例一​​
  • ​​2、示例二​​
  • ​​3、示例三​​
  • ​​六、playbook(忽略错误)​​
  • ​​六、playbook(错误处理)​​
  • ​​1、强制调用handler​​
  • ​​2、抑制changed​​

playbook条件语句

我们使用​

​Ansible​

​​的过程中,条件判断的使用频率极其高,不管是​

​shell​

​还是各大编程语言中,流程控制,条件判断这些都是必不可少的

例如:

1.我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。

2.在​​

​nfs​

​​和​

​rsync​

​​安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。

3.我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

一、根据不同的操作系统安装apache

1、示例

"shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_facts['os_family'] == "Debian"
    # note that all variables can be used directly in conditionals without double curly braces
- hosts: web_group
  tasks:
    - name: Install CentOS Httpd
      yum:
        name: httpd
        state: present
    #官方
      when: ansible_facts['os_family'] == "CentOS"
    #非官方
      when: ansible_distribution == "CentOS"

    - name: Install Ubuntu Httpd
      yum:
        name: apache2
        state: present
      when: ansible_facts['os_family'] == "Ubuntu"      

2、使用括号对条件进行分组

tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
          (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7"      

3、指定多条件为列表

tasks:
  - name: "shut down CentOS 6 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_facts['distribution'] == "CentOS"
      - ansible_facts['distribution_major_version'] == "6"      

4、条件运算

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6      

5、rsync(剧本)

1)#服务端推送配置文件
[root@m01 ~]# cat rsyncd/rsyncd.yaml
- hosts: rsync
  tasks:
    - name: Install Rsyncd Server
      yum:
        name: rsync
        state: present

    - name: Create www Group
      group:
        name: www
        gid: 1000
        
    - name: Create www User
      user:
        name: www
        group: www
        uid: 1000
        create_home: false
        shell: /sbin/nologin

    - name: Scp Rsync Config
      copy:
        src: ./rsyncd.j2
        dest: /etc/rsyncd.conf
        owner: root
        group: root
        mode: 644
      when: ansible_hostname == "backup"

    - name: Create Passwd File
      copy:
        content: 'rsync_backup:123'
        dest: /etc/rsync.passwd
        owner: root
        group: root
        mode: 0600
      when: ansible_hostname == "backup"

    - name: Create backup Directory
      file:
        path: /backup
        state: directory
        mode: 0755
        owner: www
        group: www
        recurse: yes
      when: ansible_hostname == "backup"

    - name: Start Rsyncd Server
      systemd:
        name: rsyncd
        state: started
      when: ansible_hostname == "backup"
      


2)#rsync客户端推送脚本

[root@m01 ~]# vim rsync.yml
- hosts: rsync_server
  tasks:
    - name: SCP Backup Shell
      copy:
        src: ./backup.sh
        dest: /root/backup.sh
      when: ansible_hostname is match "web*"

#执行结果
PLAY [rsync_server] **************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [web02]
ok: [backup]
ok: [web01]

TASK [SCP Backup Shell] **********************************************************************************************************************************************************************************************************************
skipping: [backup]
changed: [web01]
changed: [web02]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
backup                     : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
web01                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web02                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0      

6、register命令(执行结果保存变量,通过when语句进行判断)

- hosts: web_group
  tasks:
    - name: Check Httpd Server
      command: systemctl is-active httpd
      ignore_errors: yes
      register: check_httpd

    - name: debug outprint
      debug: var=check_httpd

    - name: Httpd Restart
      service:
        name: httpd
        state: restarted
      when: check_httpd.rc == 0      

二、playbook循环语句

当我们创建目录之类的操作时,创建2个目录就要写两个file模块来创建,如果要创建100个,就需要写100个file模块!!!!害----- 当然不是,只要用循环即可,就可减少代码的重复性

1、启动多个服务

- hosts: web_group
  tasks:
    - name: start service
      systemd:
        name: "{{ item }}"      

2、定义变量(循环)

#方式一
- name: ensure a list of packages installed
  yum:
    name: "{{ packages }}"  #定义变量名
  vars:
    packages:
    - httpd
    - httpd-tools
    
#方式二    
- hosts: web_group
  tasks:
    - name: ensure a list of packages installed
      yum: name= "{{ item }}" state=present
      with_items:
        - httpd
        - httpd-tools      

3、字典循环

1.#创建用户

[root@m01 ~]# cat loop.yml
- hosts: web_group
  tasks:
    - name: Add Users
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
        state: present
      with_items:
        - { name: 'zls', groups: 'linux' }
        - { name: 'egon', groups: 'python' }
2.#拷贝文件

- hosts: web_group
  tasks:
    - name: copy conf and code
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        mode: "{{ item.mode }}"
      with_items:
        - { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
        - { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }      

三、playbook——handlers

handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可
#剧本编写
[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present

    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify:     #使用触发器
        - Restart Httpd Server
        - Restart PHP Server

    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes

  handlers:     #触发器剧本编写
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

    - name: Restart PHP Server
      systemd:
        name: php-fpm
        state: restarted
        


#注:
1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。

2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。

3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。

4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。

5.不能使用handlers替代tasks      

四、playbook任务标签

默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签(tag)功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务

1、标签方式

1.#对一个task打一个标签
2.#对一个task打多个标签
3.#对多个task打一个标签      

2、标签的使用

#标签如何使用      

3、使用标签(-t)

[root@m01 m01]# cat tag.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present
      tags: 
        - install_httpd
        - httpd_server

    - name: configure httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf/httpd.conf
      notify: Restart Httpd Server
      tags: 
        - config_httpd
        - httpd_server

    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes
      tags: service_httpd

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

[root@m01 m01]# ansible-playbook tag.yml --list-tags
[root@m01 m01]# ansible-playbook tag.yml -t httpd_server
[root@m01 m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd
[root@m01 m01]# ansible-playbook tag.yml --skip-tags httpd_server      

五、playbook(文件复用)

在编写playbook的过程中,写多个playbook没有办法一键执行,这样我们需要单个playbook去执行,很鸡肋,所以在playbook中有一个功能,叫做​

​include​

​用来动态调用task任务列表
04@ansible playbook语句详解
表示rolse头文件
只调用task:include_tasks
调用整个task文件:include (新版本:import_playbook)
在saltstack中,叫做top file入口文件      

1、示例一

[root@m01 m01]# cat task.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:                           #包含的剧本
    - include_tasks: task_install.yml
    - include_tasks: task_configure.yml
    - include_tasks: task_start.yml

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted


[root@m01 m01]# cat task_install.yml   #剧本一
- name: Install Http Server
  yum:
    name: httpd
    state: present

[root@m01 m01]# cat task_configure.yml  #剧本二
- name: configure httpd server
  template:
    src: ./httpd.j2
    dest: /etc/httpd/conf/httpd.conf
  notify: Restart Httpd Server

[root@m01 m01]# cat task_start.yml      #剧本三
- name: start httpd server
  service:
    name: httpd
    state: started
    enabled: yes      

2、示例二

- include: httpd.yml
- include: nfs.yml
- include: rsync.yml      

3、示例三

- import_playbook: httpd.yml
- import_playbook: nfs.yml
- import_playbook: rsync.yml      

六、playbook(忽略错误)

默认playbook会检测tasks执行的返回状态,如果遇到错误则会立即终止playbook的后续tasks执行,然鹅有些时候playbook即使执行错误了也要让其继续执行

playbook加入参数:ignore_errors: yes 表忽略错误

[root@m01 ~]# cat ignore.yml
---
- hosts: web_group
  tasks:
    - name: Ignore False
      command: /bin/false
      ignore_errors: yes   #错误忽略
      
    - name: touch new file
      file:
        path: /tmp/zls.txt
        state: touch      

六、playbook(错误处理)

如上所述,当task执行失败时,playbook将不再继续执行,包括如果在task中设置了handler也不会被执行

1、强制调用handler

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  force_handlers: yes         #强制调用handler
  tasks:

    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify: 
        - Restart Httpd Server
        - Restart PHP Server

    - name: Install Http Server
      yum:
        name: htttpd
        state: present

    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes


  handlers:        #触发器      

2、抑制changed

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  force_handlers: yes      
  tasks:
    - name: shell
      shell: netstat -lntup|grep httpd
      register: check_httpd
      changed_when: false

    - name: debug
      debug: msg={{ check_httpd.stdout.lines }}
      
      
      
      
      
      
[root@m01 project2]# cat changed_when.yml 
- hosts: webservers
  vars:
    - http_port: 8080
  tasks:
    - name: configure httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf/httpd.conf
      notify: Restart Httpd Server

    - name: Check HTTPD
      shell: /usr/sbin/httpd -t
      register: httpd_check
      changed_when: 
        - httpd_check.stdout.find('OK')
        - false

    - name: start httpd server
      service:
        name: httpd
        state: started
        enabled: yes      

继续阅读