Ansible——playbook

那年仲夏 提交于 2020-02-08 09:44:03

1.ansible-playbook命令行参数
[root@ansible PlayBook]# ansible-playbook -h
#ansible-playbook常用选项:
–check or -C #只检测可能会发生的改变,但不真正执行操作
–list-hosts #列出运行任务的主机
–list-tags #列出playbook文件中定义所有的tags
–list-tasks #列出playbook文件中定义的所以任务集
–limit #主机列表 只针对主机列表中的某个主机或者某个组执行
-f #指定并发数,默认为5个
-t #指定tags运行,运行某一个或者多个tags。(前提playbook中有定义tags)
-v #显示过程 -vv -vvv更详细
2.playbook系统元素
hosts、remote_user、tasks、name、 sudo_user、sudo、handlers、notify、tags、template、when、with_items
hosts
执行的远程主机列表,hosts 行的内容是一个或多个组或主机的 patterns,以逗号为分隔符。
hosts: 192.168.1.71,master,webs
remote_use
可以在hosts下,定义远程执行用户,也可以在某一个tasks中定义要执行该任务的远程用户
tasks、name
task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很清楚的辨别是属于哪一个task的,如果没有定义 name,action的值将会用作输出信息中标记特定的task。每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks。
sudo_user、sudo
使用sudo授权用户执行该任务
handlers、notify
事件触发动作处理,handlers、notify中的name要一致。

基础学习示例

---
- hosts: 192.168.1.31
  remote_user: root

  tasks:
  - name: install httpd
    yum: name=httpd state=installed
  - name: config httpd
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
      - restart httpd
  - name: start httpd
    service: name=httpd state=started

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

3.模板系统元素
for、endfor 、if、else、endif
4.变量
命令行变量

[root@ansible PlayBook]# cat variables.yml 
---
- hosts: all
  remote_user: root

  tasks:
    - name: install pkg
      yum: name={{ pkg }}
[root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml

host变量
在/etc/ansible/hosts文件中定义变量,可以针对每个主机定义不同的变量,也可以定义一个组的变量,然后直接在playbook中直接调用。注意,组中定义的变量没有单个主机中的优先级高。

[root@ansible PlayBook]# vim /etc/ansible/hosts
[apache]
192.168.1.36 webdir=/opt/test     #定义单个主机的变量
192.168.1.33
[apache:vars]      #定义整个组的统一变量
webdir=/web/test

[nginx]
192.168.1.3[1:2]
[nginx:vars]
webdir=/opt/web
[root@ansible PlayBook]# cat variables.yml 

---
- hosts: all
  remote_user: root

  tasks:
    - name: create webdir
      file: name={{ webdir }} state=directory   #引用变量
[root@ansible PlayBook]# ansible-playbook variables.yml

playbook变量
编写playbook时,直接在里面定义变量,然后直接引用,可以定义多个变量;注意:如果在执行playbook时,又通过-e参数指定变量的值,那么会以-e参数指定的为准。

 [root@ansible PlayBook]# cat variables.yml 
---
- hosts: all
  remote_user: root
  vars:                #定义变量
    pkg: nginx         #变量1
    dir: /tmp/test1    #变量2

  tasks:
    - name: install pkg
      yum: name={{ pkg }} state=installed    #引用变量
    - name: create new dir
      file: name={{ dir }} state=directory   #引用变量
[root@ansible PlayBook]# ansible-playbook variables.yml

如果执行时候又重新指定了变量的值,那么会已重新指定的为准

[root@ansible PlayBook]# ansible-playbook -e "dir=/tmp/test2" variables.yml

setup模块变量

setup模块默认是获取主机信息的,有时候在playbook中需要用到,所以可以直接调用。常用的参数参考

[root@ansible PlayBook]# cat variables.yml 
---
- hosts: all
  remote_user: root

  tasks:
    - name: create file
      file: name={{ ansible_fqdn }}.log state=touch   #引用setup中的ansible_fqdn
[root@ansible PlayBook]# ansible-playbook variables.yml

YAML文件变量
为了管理将所有的变量统一放在一个独立的变量YAML文件中,laybook文件直接引用文件调用变量即可。

[root@ansible PlayBook]# cat var.yml 
var1: vsftpd
var2: httpd
[root@ansible PlayBook]# cat variables.yml 
---
- hosts: all
  remote_user: root
  vars_files:    #引用变量文件
    - ./var.yml   #指定变量文件的path(这里可以是绝对路径,也可以是相对路径)

  tasks:
    - name: install package
      yum: name={{ var1 }}   #引用变量
    - name: create file
      file: name=/tmp/{{ var2 }}.log state=touch   #引用变量
[root@ansible PlayBook]# ansible-playbook  variables.yml

5.Playbook标签

playbook文件可给任务集打标签,执行ansible-playbook通过-t选择标签执行,通过–skip-tags选择除了某个标签外的全部标签执行。

[root@ansible PlayBook]# cat httpd.yml 
---
- hosts: 192.168.1.31
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd state=installed
      tags: inhttpd

    - name: start httpd
      service: name=httpd state=started
      tags: sthttpd

    - name: restart httpd
      service: name=httpd state=restarted
      tags: 
        - rshttpd
        - rs_httpd

通过-t指定tags名称,多个tags用逗号隔开

[root@ansible PlayBook]# ansible-playbook -t rshttpd httpd.yml 

通过–skip-tags选项排除不执行的tags

[root@ansible PlayBook]# ansible-playbook --skip-tags inhttpd httpd.yml 

6.Playbook模板
template模板提供了动态配置服务,使用jinja2语言条件判断、循环、逻辑运算、比较操作等。将template文件放在和playbook文件同级的templates目录下(需手动创建),playbook可直接引用,自动寻找模板文件,也可以通过绝对路径去指定。模板文件后缀名为.j2。

[root@ansible PlayBook]# cat testtmp.yml 

---
- hosts: all
  remote_user: root
  vars:
    - listen_port: 88    #定义变量

  tasks:
    - name: Install Httpd
      yum: name=httpd state=installed
    - name: Config Httpd
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf    #使用模板
      notify: Restart Httpd
    - name: Start Httpd
      service: name=httpd state=started
      
  handlers:
    - name: Restart Httpd
      service: name=httpd state=restarted
[root@ansible PlayBook]# cat templates/httpd.conf.j2 |grep ^Listen
Listen {{ listen_port }}

目录结构

[root@ansible PlayBook]# tree .
├── templates
│   └── httpd.conf.j2
└── testtmp.yml
[root@ansible PlayBook]# ansible-playbook testtmp.yml 

when在template中使用
示例1

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

示例2
准备两个配置文件,一个centos6系统httpd配置文件,一个centos7系统httpd配置文件。

[root@ansible PlayBook]# tree templates/
templates/
├── httpd6.conf.j2     #6系统2.2.15版本httpd配置文件
└── httpd7.conf.j2     #7系统2.4.6版本httpd配置文件

修改playbook文件,通过setup模块获取系统版本判断。

[root@ansible PlayBook]# cat testtmp.yml 
---
- hosts: all
  remote_user: root
  vars:
    - listen_port: 88

  tasks:
    - name: Install Httpd
      yum: name=httpd state=installed
    - name: Config System6 Httpd
      template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
      when: ansible_distribution_major_version == "6"   #判断系统版本,为6便执行上面的template配置6的配置文件
      notify: Restart Httpd
    - name: Config System7 Httpd
      template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
      when: ansible_distribution_major_version == "7"   #判断系统版本,为7便执行上面的template配置7的配置文件
      notify: Restart Httpd
    - name: Start Httpd
      service: name=httpd state=started

  handlers:
    - name: Restart Httpd
      service: name=httpd state=restarted

示例3
**在这里插入图片描述**
示例4在这里插入图片描述
示例5 在这里插入图片描述示例6
在这里插入图片描述示例7
需要目标主机上安装lsb_release软件包,来返回ansible_lsb.major_release 事件

.tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

示例8
在playbooks 和 inventory中定义的变量都可以使用. 下面一个例子,就是基于布尔值来决定一个任务是否被执行:

vars:
  epic: true

一个条件选择执行也许看起来像这样:

tasks:
    - shell: echo "This certainly is epic!"
      when: epic

或者像这样:

tasks:
    - shell: echo "This certainly isn't epic!"
      when: not epic

示例8
如果一个变量不存在,可以使用Jinja2的defined命令跳过或略过.

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

示例9

tasks:
    - command: echo {{ item }}
      with_items: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5

示例10

加载客户事件,调用客户自己的事件,进而把所有的模块放在任务列表顶端, 变量的返回值今后就可以访问了:

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'

示例11
在roles 和 includes 上面应用’when’语句

- include: tasks/sometasks.yml
  when: "'reticulating splines' in output" 
- hosts: webservers
  roles:
     - { role: debian_stock_config, when: ansible_os_family == 'Debian' }

示例11
条件导入

---
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running

提醒一下,很多的不同的YAML文件只是包含键和值:

cat vars/CentOS.yml
--- 
apache: httpd
somethingelse: 42

示例12
注册变量
‘register’ 关键词决定了把结果存储在哪个变量中.结果参数可以用在模版中,动作条目,或者 when 语句

- 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

也可以调用 “home_dirs.stdout.split()” , 也可以用其它字段切割:

- 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()

with_items在playbook中使用

with_items迭代,当有需要重复性执行的任务时,可以使用迭代机制。对迭代项的引用,固定变量名为“item”,要在task中使用with_items给定要迭代的元素列表。
示例1

[root@ansible PlayBook]# cat testwith.yml 
 
---
- hosts: all
  remote_user: root

  tasks:
    - name: Install Package
      yum: name={{ item }} state=installed   #引用item获取值
      with_items:     #定义with_items
        - httpd
        - vsftpd
        - nginx

示例2

[root@ansible PlayBook]# cat testwith01.yml 
 ---
- hosts: all
  remote_user: root

  tasks:
    - name: Create New Group
      group: name={{ item }} state=present
      with_items: 
        - group1
        - group2
        - group3 

    - name: Create New User
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'user1', group: 'group1' } 
        - { name: 'user2', group: 'group2' } 
        - { name: 'user3', group: 'group3' }

for、if在template中使用

通过使用for,if可以更加灵活的生成配置文件等需求,还可以在里面根据各种条件进行判断,然后生成不同的配置文件、或者服务器配置相关等。
示例1

[root@ansible PlayBook]# cat testfor01.yml 
---
- hosts: all
  remote_user: root
  vars:
    nginx_vhost_port:
      - 81
      - 82
      - 83

  tasks:
    - name: Templage Nginx Config
      template: src=nginx.conf.j2 dest=/tmp/nginx_test.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2 
{% for port in nginx_vhost_port %}
server{
     listen: {{ port }};
     server_name: localhost;
}
{% endfor %}

示例2

[root@ansible PlayBook]# cat testfor02.yml 
---
- hosts: all
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8081
        server_name: "web1.example.com"
        root: "/var/www/nginx/web1"
      - web2:
        listen: 8082
        server_name: "web2.example.com"
        root: "/var/www/nginx/web2"
      - web3:
        listen: 8083
        server_name: "web3.example.com"
        root: "/var/www/nginx/web3"

  tasks:
    - name: Templage Nginx Config
      template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2 
{% for vhost in nginx_vhosts %}
server{
     listen:    {{ vhost.listen }};
     server_name:    {{ vhost.server_name }};
     root:   {{ vhost.root }}; 
}
{% endfor %}

示例3

[root@ansible PlayBook]# cat testfor03.yml 
---
- hosts: all
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8081
        root: "/var/www/nginx/web1"
      - web2:
        server_name: "web2.example.com"
        root: "/var/www/nginx/web2"
      - web3:
        listen: 8083
        server_name: "web3.example.com"
        root: "/var/www/nginx/web3"

  tasks:
    - name: Templage Nginx Config
      template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2 
{% for vhost in nginx_vhosts %}
server{
     {% if vhost.listen is defined %}
     listen:    {{ vhost.listen }};
     {% else %}
     listen: 8888;
     {% endif %}
     {% if vhost.server_name is defined %}
     server_name:    {{ vhost.server_name }};
     {% endif %}
     root:   {{ vhost.root }}; 
}
{% endfor %}

7.ignore_errors
play中只要执行命令的返回值不为0,就会报错,tasks停止,可以添加
ignore_errors: True ,忽略错误。
在这里插入图片描述

Ansible之Playbook详解、案例

————Blueicex 2020/2/2 12:20 blueice1980@126.com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!