第二十九章 playbook的相关使用

一、playbook 任务标签

1.标签的作用

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

2.打标签的方式

1.对一个task下面的一个name打一个标签
2.对一个task下面的一个name打多个标签
3.对task下面的多个name打一个标签

3.打标签

1)对一个task打一个标签
.. ... ...
    - name: Config nginx Server
      copy:
        src: /root/conf/linux.wp.com.conf
        dest: /etc/nginx/conf.d/
      notify:
        - restart_web_nginx
        - get_nginx_status
      when: ansible_fqdn is match "web*"
      tags: config_web
... ... ...
2)对一个task下面的一个name打多个标签
    - name: Config nginx Server
      copy:
        src: /root/conf/linux.wp.com.conf
        dest: /etc/nginx/conf.d/
      notify:
        - restart_web_nginx
        - get_nginx_status
      when: ansible_fqdn is match "web*"
      tags: 
        - config_web
        - config_nginx
3)对task下面的多个name打一个标签
    - name: Config slb Server
      copy:
        src: /root/conf/proxy.conf
        dest: /etc/nginx/conf.d
      notify: restart_slb
      when: ansible_fqdn == "lb01"
      tags: config_nginx

    - name: Config nginx Server
      copy:
        src: /root/conf/linux.wp.com.conf
        dest: /etc/nginx/conf.d/
      notify:
        - restart_web_nginx
        - get_nginx_status
      when: ansible_fqdn is match "web*"
      tags: 
        - config_web
        - config_nginx

4.标签的使用

#查看所有的标签(也可以查看该剧本有多少 hosts )
[root@m01 ~]# ansible-playbook lnmp6.yml --list-tags

#执行标签指定的动作
[root@m01 ~]# ansible-playbook lnmp2.yml -t config_web

#执行指定多个标签的动作
[root@m01 ~]# ansible-playbook lnmp2.yml -t config_nginx,config_web

#跳过指定的标签动作
[root@m01 ~]# ansible-playbook lnmp2.yml --skip-tags config_nginx

二、playbook的复用

在之前写playbook的过程中,我们发现,写多个playbook没有办法,一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。所以在playbook中有一个功能,叫做include用来动态调用task任务列表。

1600997717527

1.只调用tasks

1)编写安装nginx
[root@m01 ~]# cat nginx.yml 
- name: Install Nginx Server
  yum:
    name: nginx
    state: present
2)编写启动nginx
[root@m01 ~]# cat start.yml 
- name: Start Nginx Server
  systemd:
    name: nginx
    state: started
    enabled: yes
3)编写调用的剧本
[root@m01 ~]# cat main.yml 
- hosts: nfs
  tasks:
    - include_tasks: nginx.yml
    - include_tasks: start.yml
4)直接调用写好的playbook
[root@m01 ~]# cat main.yml 
- import_playbook: lnmp1.yml
- import_playbook: lnmp2.yml

三、playbook忽略错误

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

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

1.一般使用

    - name: Get PHP Install status
      shell: "rpm -qa | grep php"
      ignore_errors: yes
      register: get_php_install_status

    - name: Install PHP Server
      shell: yum localinstall -y /tmp/*.rpm
      when:
        - ansible_fqdn is match "web*"
        - get_php_install_status.rc != 0

四、playbook错误处理

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

1.强制调用handlers

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  force_handlers: yes
  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:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

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

2.抑制changed

#被管理主机没有发生变化,可以使用参数将change状态改为ok
    - name: Get PHP Install status
      shell: "rpm -qa | grep php"
      ignore_errors: yes
      changed_when: false
      register: get_php_install_status

五、Ansible的jinja2

1.什么是jinja2

jinja2是Python的全功能模板引擎
就是一个配置文件的模板,支持变量

#Jinja2与Ansible啥关系
Ansible通常会使用jinja2模板来修改被管理主机的配置文件等...在saltstack中同样会使用到jinja2
如果在100台主机上安装nginx,每台nginx的端口都不一样,如何解决?

#Ansible如何使用Jinja2
	使用Ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。
	之前我们在推送rsync的backup脚本时,想把脚本中的变量名改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名
	
#Ansible使用Jinja2注意事项
Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。
注意:不是每个管理员都需要这个特性,但是有些时候jinja2模块能大大提高效率。

六、jinja2的使用

​```bash
{{ EXPR }} 输出变量值,会输出自定义的变量值或facts
1.playbook文件使用template模块
2.模板文件里面变量使用{{名称}},比如{{PORT}}或使用facts

2.Jinja2模板逻辑判断

1)循环
#shell脚本的循环
[root@m01 ~]# vim xh.sh
#!/bin/bash
for i in `seq 10`
do
    echo $i
done
#Jinja2的循环表达式
{% for i in range(10) %}
echo $i
{% endfor %}
2)判断
#shell脚本的判断
[root@m01 ~]# vim pd.sh 
#!/bin/bash
age=$1
if [ $age -lt 18 ];then
    echo "小姐姐"
else
    echo "大妈"
fi
#Jinja2的条件判断
{% if EXPR %}
{% elif EXPR %}
{% else %}
{% endif %}

#注释
{# COMMENT #}

3.jinja2模板测试

1)登录文件测试
#编写j2模板
[root@m01 ~]# vim motd.j2
欢迎来到 {{ ansible_fqdn }}
该服务器总内存: {{ ansible_memtotal_mb }} MB
该服务器剩余内存: {{ ansible_memfree_mb }} MB

#编写剧本
[root@m01 ~]# vim motd.yml 
- hosts: all
  tasks:
    - name: Config motd
      template:
        src: /root/motd.j2
        dest: /etc/motd

#执行剧本
[root@m01 ~]# ansible-playbook motd.yml

#查看远端服务器内容
[root@backup ~]# cat /etc/motd 
欢迎来到 backup
该服务器总内存: 972 MB
该服务器剩余内存: 582 MB

[root@db01 ~]# cat /etc/motd
欢迎来到 db01
该服务器总内存: 972 MB
该服务器剩余内存: 582 MB
2)使用jinja2模板管理mysql
#配置模板
[root@m01 ~]# vim /etc/my.j2
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0

{% if ansible_memtotal_mb == 972  %}
innodb_log_buffer_poll_size= 800M
{% elif ansible_memtotal_mb == 1980 %}
innodb_log_buffer_poll_size= 1600M
{% endif %}

... ...

#配置剧本
[root@m01 ~]# vim mysql.yml 
- hosts: db_group
  tasks:
    - name: Config mysql
      template:
        src: /etc/my.cnf
        dest: /etc/

#执行
[root@m01 ~]# ansible-playbook mysql.yml

#查看
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
innodb_log_buffer_poll_size= 800M

[root@db03 ~]# vim /etc/my.cnf
[mysqld]
innodb_log_buffer_poll_size= 1600M

4.配置负载均衡的jinja2模板

1)正经的配置
[root@m01 ~]# cat conf/proxy_new.conf 
upstream web {
	server 172.16.1.7;
	server 172.16.1.8;
}

server {
	listen 80;
	server_name linux.wp.com;

	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
2)不正经的配置
[root@m01 ~]# vim conf/proxy.j2
upstream {{ server_name }} {
{% for i in range(7,9) %}
    server {{ ip }}.{{ i }};
{% endfor %}
}

server {
    listen {{ port }};
    server_name {{ server_name }};

    location / {
        proxy_pass http://{{ server_name }};
        include proxy_params;
    }
}
3)配置额外变量
[root@m01 ~]# vim upstream_vars.yml 
ip: 172.16.1
web: web
port: 80
server_name: linux.wp.com
4)配置剧本推送
[root@m01 ~]# vim proxy.yml 
- hosts: lb01
  vars_files: upstream_vars.yml
  tasks:
    - name: Config SLB
      template:
        src: /root/conf/proxy.j2
        dest: /etc/nginx/conf.d/proxy.conf

    - name: Restart SLB Nginx
      systemd:
        name: nginx
        state: restarted

5.使用jinja2模板配置keepalived

1)配置keepalived配置文件(正经配置)
#keepalived master 配置文件
global_defs {
    router_id lb01
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {         
        10.0.0.3
    }
}


#keepalived backup配置文件
global_defs {
    router_id lb02
}

vrrp_instance VI_1 {
    state BACKUP        
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}
2)配置keepalived配置文件(不正经配置)
[root@m01 ~]# vim conf/keepalived.j2
global_defs {
    router_id {{ ansible_fqdn }}
}

vrrp_instance VI_1 {
	{% if ansible_fqdn == "lb01" %}
    state MASTER
    priority 100
    {% else %}
    state BACKUP
    priority 90
    {% endif %}
    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        {{ vip }}
    }
}
3)配置变量
[root@m01 ~]# vim upstream_vars.yml 
ip: 172.16.1
web: web
port: 80
server_name: linux.wp.com
vip: 10.0.0.3
4)配置主机清单
#配置主机清单
[root@m01 ~]# vim /etc/ansible/hosts 
[slb]
lb01 ansible_ssh_pass='1'
lb02 ansible_ssh_pass='1'

#配置hosts
[root@m01 ~]# vim /etc/hosts
....
172.16.1.5 lb02
5)编写keepalived剧本
[root@m01 ~]# cat keepalived.yml 
- hosts: slb
  vars_files: upstream_vars.yml
  tasks:
    - name: Install keepalived
      yum:
        name: keepalived
        state: present

    - name: Config keepalive
      template:
        src: /root/conf/keepalived.j2
        dest: /etc/keepalived/keepalived.conf

    - name: Start keepalived
      systemd:
        name: keepalived
        state: restarted

6.整合剧本,一件部署wordpress

1)配置主机清单
[root@m01 ~]# cat /etc/ansible/hosts 
[web_group]
web01 ansible_ssh_pass='1'
web02 ansible_ssh_pass='1'
#web03 ansible_ssh_pass='1'

[slb]
lb01 ansible_ssh_pass='1'
lb02 ansible_ssh_pass='1'

[db_group]
db01 ansible_ssh_pass='1'
db03 ansible_ssh_pass='1'

[nfs_server]
nfs ansible_ssh_pass='1'

[backup_server]
backup ansible_ssh_pass='1'

[nginx_group:children]
web_group
slb

[nfs_group:children]
nfs_server
web_group

[nginx_group:vars]
web=host_vars
2)配置keepalived剧本
[root@m01 ~]# cat keepalived.yml 
- hosts: slb
  vars_files: upstream_vars.yml
  tasks:
    - name: Install keepalived
      yum:
        name: keepalived
        state: present

    - name: Config keepalive
      template:
        src: /root/conf/keepalived.j2
        dest: /etc/keepalived/keepalived.conf

    - name: Start keepalived
      systemd:
        name: keepalived
        state: restarted
3)配置wordpress剧本
[root@m01 ~]# cat lnmp.yml 
- hosts: all
  vars_files: upstream_vars.yml
  tasks:
    - name: Stop selinux
      selinux:
        state: disabled

    - name: Stop Firewalld
      systemd:
        name: firewalld
        state: stopped
        enabled: no

    - name: Install unzip
      yum:
        name: unzip
        state: present

    - name: Create www Group
      group:
        name: www
        gid: 666

    - name: Create www User
      user:
        name: www
        uid: 666
        group: www
        shell: /sbin/nologin
        create_home: no

    - name: Copy nginx.repo
      copy:
        src: /root/conf/nginx.repo
        dest: /etc/yum.repos.d/
      when: (ansible_fqdn is match "lb*") or (ansible_fqdn is match "web*")

    - name: Install Nginx Server
      yum:
        name: nginx
        state: present
      when: (ansible_fqdn is match "lb*") or (ansible_fqdn is match "web*")

    - name: Config Nginx Server
      copy:
        src: /root/conf/nginx.conf
        dest: /etc/nginx/
      when: (ansible_fqdn is match "lb*") or (ansible_fqdn is match "web*")
      notify: restart_all_nginx

    - name: Config slb Server
      template:
        src: /root/conf/proxy.j2
        dest: /etc/nginx/conf.d/proxy.conf
      when: ansible_fqdn is match "lb*"
      notify: restart_slb

    - name: Copy proxy_params
      copy:
        src: /root/conf/proxy_params
        dest: /etc/nginx/
      when: ansible_fqdn is match "lb*"
    
    - name: Start slb Server
      systemd:
        name: nginx
        state: started
      when: ansible_fqdn is match "lb*"

    - name: Config nginx Server
      copy:
        src: /root/conf/linux.wp.com.conf
        dest: /etc/nginx/conf.d/
      when: ansible_fqdn is match "web*"
      notify: restart_code_nginx      

    - name: Mkdir Code
      file:
        path: /code
        state: directory
      when: ansible_fqdn is match "web*"

    - name: Tar wordpress and php
      unarchive:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      with_items:
        - { src: /root/package/wordpress-5.0.3-zh_CN.tar.gz, dest: /code/ }
        - { src: /root/package/php.tar.gz, dest: /tmp/ }
      when: ansible_fqdn is match "web*"

    - name: Grant Code Dir
      file:
        path: /code
        owner: www
        group: www
        recurse: yes
      when: ansible_fqdn is match "web*"

    - name: Start Web Nginx Server
      systemd:
        name: nginx
        state: started
        enabled: yes
      when: (ansible_fqdn is match "web*") or (ansible_fqdn is match "lb*")

    - name: Get PHP Install status
      shell: "rpm -qa | grep php"
      ignore_errors: yes
      register: get_php_install_status

    - name: Install PHP Server
      shell: yum localinstall -y /tmp/*.rpm
      when: 
        - ansible_fqdn is match "web*"
        - get_php_install_status.rc != 0

    - name: Config php Server
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      with_items:
        - { src: /root/conf/php.ini, dest: /etc/ }
        - { src: /root/conf/www.conf, dest: /etc/php-fpm.d/ }
      when: ansible_fqdn is match "web*"
      notify: restart_php

    - name: Start php and nginx Server
      systemd:
        name: "{{ item.name }}"
        state: started
        enabled: yes
      with_items:
        - { name: php-fpm }
        - { name: nginx }
      when: ansible_fqdn is match "web*"

    - name: Install Mariadb Server
      yum:
        name: "{{ db }}"
        state: present
      vars:
        db:
          - mariadb-server
          - MySQL-python
      when: ansible_fqdn == "db01"
    
    - name: Start Mariadb Server
      systemd:
        name: mariadb
        state: started
        enabled: yes
      when: ansible_fqdn == "db01"

    - name: Create wordpress Database
      mysql_db:
        name: wordpress
        state: present
      when: ansible_fqdn == "db01"

    - name: Create wordpress Database User
      mysql_user:
        name: "wp"
        host: "172.16.1.%"
        password: '123456'
        priv: "wordpress.*:ALL"
        state: present
      when: ansible_fqdn == "db01" 
        
    - name: Install nfs Server
      yum:
        name: "{{ nfs_server }}"
        state: present
      vars:
        nfs_server:
          - nfs-utils
          - rpcbind
      when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")

    - name: Config nfs Server
      copy:
        content: /data/wp-content 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
        dest: /etc/exports      
      when: ansible_fqdn == "nfs"

    - name: Mkdir data
      file:
        path: /data
        state: directory
        owner: www
        group: www
      when: ansible_fqdn == "nfs"

    - name: Start nfs Server
      systemd:
        name: nfs
        state: started
      when: ansible_fqdn == "nfs" 

    - name: Copy wp-content to NFS
      copy:
        src: /root/package/wp-content
        dest: /data
        owner: www
        group: www
      when: ansible_fqdn == "nfs"
    
    - name: Start rpcbind Server
      systemd:
        name: rpcbind
        state: started
      when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")

    - name: Mount nfs
      mount:
        src: 172.16.1.31:/data/wp-content
        path: /code/wordpress/wp-content/
        fstype: nfs
        opts: defaults
        state: mounted
      when: ansible_fqdn is match "web*"

    - name: Install rsync Server
      yum:
        name: rsync
        state: present
      when: ansible_fqdn == "backup"

    - name: Config Rsync Server
      copy:
        src: /root/conf/rsyncd.conf
        dest: /etc/
      when: ansible_fqdn == "backup"

    - name: Config rsync.passwd
      copy:
        content: rsync_backup:123456
        dest: /etc/rsync.passwd
        mode: 0600
      when: ansible_fqdn == "backup"

    - name: Mkdir backup Dir
      file:
        path: /backup
        state: directory
        owner: www
        group: www
      when: ansible_fqdn == "backup"

    - name: Start rsync Server
      systemd:
        name: rsyncd
        state: started
      when: ansible_fqdn == "backup"

    - name: Install rsync and Inotify-tools Server
      yum:
        name: 
          - rsync
          - inotify-tools
        state: present
      when: ansible_fqdn == "nfs"

    - name: Install sersync Server
      copy:
        src: /root/package/sersync
        dest: /usr/local/
        mode: 0755
      when: ansible_fqdn == "nfs"

    - name: Config rsync.pass
      copy:
        content: 123456
        dest: /etc/rsync.pass
        mode: 0600
      when: ansible_fqdn == "nfs"

    - name: Start sersync
      script: /root/start_rsync.sh
      when: ansible_fqdn == "nfs"

  handlers:
    - name: restart_slb
      systemd:
        name: nginx
        state: restarted
      when: ansible_fqdn is match "lb*"

    - name: restart_code_nginx
      systemd:
        name: nginx
        state: restarted
      when: ansible_fqdn is match "web*"

    - name: restart_php
      systemd:
        name: php-fpm
        state: restarted
      when: ansible_fqdn is match "web*"

    - name: restart_all_nginx
      systemd:
        name: nginx
        state: restarted
      when: (ansible_fqdn is match "lb*") or (ansible_fqdn is match "web*")
4)使用到的变量文件
[root@m01 ~]# cat upstream_vars.yml 
ip: 172.16.1
web: web
nginx_port: 80
server_name: linux.wp.com
5)使用的jinja2模板
[root@m01 ~]# cat conf/proxy.j2 
upstream {{ server_name }} {
{% for i in range(7,9) %}
    server {{ ip }}.{{ i }};
{% endfor %}
}

server {
	listen {{ nginx_port }};
	server_name {{ server_name }};

	location / {
		proxy_pass http://{{ server_name }};
		include proxy_params;
	}
}

[root@m01 ~]# cat conf/keepalived.j2 
global_defs {
    router_id {{ ansible_fqdn }}
}

vrrp_instance VI_1 {
	{% if ansible_fqdn == "lb01" %}
    state MASTER
    priority 100
    {% else %}
    state BACKUP
    priority 90
    {% endif %}
    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

原文地址:https://www.cnblogs.com/jhno1/p/13884971.html