ansible工具之playbook

playbook简介

主要功能:将分组主机按照定义好的playbook执行。
play:定义好的角色task,task一般为ansible的模块。
playbook:将多个play组合在一起,就是playbook
playbook采用yaml语言编写,遵循yaml语法格式。

YAML介绍:

    YAML是一个可读性高的用来表达资料序列的格式。
    YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。
    Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者

YAML特性:

    - YAML的可读性好
    - YAML和脚本语言的交互性好
    - YAML使用实现语言的数据类型
    - YAML有一个一致的信息模型
    - YAML易于实现
    - YAML可以基于流来处理
    - YAML表达能力强,扩展性好

YAML语法:

    - 在单一档案中,可用连续三个连字号(---)区分多个档案。另外,还有选择性的连续三个点号( ... )用来表示档案结尾
    - 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
    - 使用#号注释代码
    - 缩进必须是统一的,不能空格和tab混用
    - 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
    - YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏感
    - k/v的值可同行写也可换行写。同行使用:分隔
    - v可是个字符串,也可是另一个列表
    - 一个完整的代码块功能需最少元素需包括 name: task
    - 一个name只能包括一个task
    - YAML文件扩展名通常为yml或yaml
    - Dictionary:字典,通常由多个key与value构成,也可以将key:value 放置于{}中进行表示,用,分隔多个 key:value

playbook基础组件

Hosts:用于指定要执行指定任务的主机,须事先定义在主机清单中。

示例:

- hosts: websrvs:dbsrvs

remote_user:执行身份

(1)可用于Host和task中。
(2)通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务。
(3)可以在sudo时使用sudo_user指定sudo时切换的用户

示例:

- hosts: websrvs
  remote_user: root
  tasks:
   - name: test connection
     ping:
     remote_user: fz.hou
     sudo: yes     默认sudo为root
     sudo_user:fl  sudo为fl

task:任务列表

格式:
(1) action: module arguments
(2) module: arguments 建议使用
注意:shell和command模块后面跟命令,而非key=value
示例:

tasks:
 - name: disable selinux
   command: /sbin/setenforce 0

notify与handlers:
某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers,继而执行handlers之后的命令。

tags:标签
任务可以通过”tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用
注意:如果多个任务标签相同,标签被调用时,任务都会被执行。

示例:安装httpd,修改httpd配置文件,并重启服务。

- hosts: webservers
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd
    - name: modify config
      copy: src=~/httpd.conf dest=/etc/httpd/conf/httpd.conf
      tags: modify
      notify: restart httpd
    - name: start httpd
      service: name=httpd state=started enabled=yes

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

示例结果:

注意:如果命令或脚本的退出码不为零,可以使用如下方式替代:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true

或者使用ignore_errors来忽略错误信息:

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True

运行playbook

运行playbook的方式

ansible-playbook <filename.yml> ... [options]

常见选项
–check 只检测可能会发生的改变,但不真正执行操作
–list-hosts 列出运行任务的主机
–limit 主机列表 只针对主机列表中的主机执行
-v 显示过程 -vv -vvv 更详细

playbook变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:

1、ansible setup facts 远程主机的所有变量都可直接调用

示例:

ansible myhosts -m setup -a 'filter=ansible_nodename'

filter是用来匹配后面的字符串,可以使用正则表达式。
也可以使用grep过滤,-C选项查看上下文三行。

示例结果:

2、在/etc/ansible/hosts中定义

普通变量:主机组中主机单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有主机定义统一变量
普通变量示例:在/etc/ansible/hosts文件中定义

[myhosts]
172.18.18.22 http_port=85 hname=nginx
172.18.18.23 http_port=86 hname=httpd

编写playbook:

cat /root/ansible/vars4.yml

  ---
  - hosts: myhosts
    remote_user: root

    tasks:
     - name: set hostname
       hostname: name={{ hname }}-{{ http_port }}

示例结果:

公共(组)变量示例:在/etc/ansible/hosts文件中定义

[myhosts:vars]
myh=HFZ

编写playbook:

cat /root/ansible/vars5.yml

  ---
  - hosts: myhosts
    remote_user: root

    tasks:
     - name: set hostname
       hostname: name={{ myh }}-{{ hname }}-{{ http_port }}

示例结果:

3、通过命令行指定变量,优先级最高

ansible-playbook –e varname=value

示例:

cat /root/ansible/vars.yml

  ---
  - hosts: myhosts
    remote_user: root

    tasks:
     - name: install package
       yum: name={{ pkname }}

示例结果:

4、在playbook中定义

示例:

cat cat vars2.yml

  ---
  - hosts: myhosts
    remote_user: root
    vars:
     - username: user1
     - groupname: group1

    tasks:
     - name: create group
       group: name={{ groupname }} state=present
     - name: create user
       user: name={{ username }} group{{ groupname }} home=/home/{{ username }}dir

示例结果:

5、可以在文件中定义变量,并在playbook中调用文件。

示例:在vars.yml文件中定义变量

hi: hello
wd: world

编写playbook:

- hosts: myhosts
  remote_user: root
  vars_files:
   - vars.yml

  tasks:
   - name: create file
     file: name=/root/{{ hi }}-{{ wd }}.log state=touch

示例结果:

6、在role中定义

playbook中的templates模板

templates特点:

基于Jinja2语言的文本文件,嵌套有脚本。

templates功能:

根据模块文件动态生成对应的配置文件

templates格式:

templates文件必须存放于templates目录下,且命名为 .j2 结尾。

yaml/yml 文件需和templates目录平级,目录结构如下:

./
 ├── temnginx.yml
 └── templates
   └── nginx.conf.j2

Jinja2语言:

使用字面量:

    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and, or, not
流表达式:for、if、when

示例:在centos6与centos7主机上安装httpd服务,并修改相应配置文件。

1、创建文件夹

mkdir ~/ansible/templats -pv

2、拷贝centos6与centos7主机上的httpd配置文件到主机。并修改文件名

ansible myhosts -m fetch -a 'src=/etc/httpd/conf/httpd.conf dest=~/ansible/'

3、复制文件到templats文件夹下并修改文件名,修改文件内容

mv ~/ansible/172.18.18.22/httpd.conf ~/ansible/templats/httpd-7.conf.j2
mv ~/ansible/172.18.18.22/httpd.conf ~/ansible/templats/httpd-6.conf.j2

4、编写playbook,注意httpd.yml与templats文件夹同级

cat httpd.yml 
    - hosts: myhosts
      remote_user: root

      tasks:
        - name: install httpd
          yum: name=httpd

        - name: templates-7
          template: src=httpd-7.conf.j2 dest=/etc/httpd/conf/httpd.conf
          when: ansible_distribution_major_version == "7"
          notify: restart httpd
          tags: conf

        - name: templates-6
          template: src=httpd-6.conf.j2 dest=/etc/httpd/conf/httpd.conf
          when: ansible_distribution_major_version == "6"
          notify: restart httpd
          tags: conf

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

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

示例演示:

playbook迭代

迭代:当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定变量名为”item”
要在task中使用with_items给定要迭代的元素列表
列表格式:
字符串
字典

示例:创建固定组,并把新建用户加入到固定组中。

cat items.yml:
    - hosts: myhosts
      remote_user: root

      tasks: 
        - name: create groups
          group: name={{item}}
          with_items:
            - itemgroup1
            - itemgroup2
            - itemgroup3
        - name: create users
          user: name={{item.username}} group={{item.groupname}}
          with_items:
            - {username: 'testuser1',groupname: 'itemgroup1'}
            - {username: 'testuser2',groupname: 'itemgroup2'}
            - {username: 'testuser3',groupname: 'itemgroup3'}

示例结果:

playbook中template for if

示例:利用for-if和templates编写playbook

cat for-if.yml 
    - hosts: myhosts
      remote_user: root
      vars:
        hosts:
          - {listen_prot: 8080,web: nginx1,name: web1.fz.com}
          - {listen_prot: 8081,web: nginx2,name: web2.fz.com}
          - {listen_prot: 8082,web: nginx3}

      tasks:
        - name: for-if
          template: src=for-if.j2 dest=/root/for-if

cat templates/for-if.j2
    {% for host in hosts %}
    server{
            listen: {{host.listen_prot}};
    {%if host.name is defined%}
            name: {{host.name}};
    {%endif%}
            web: {{host.web}};
    }
    {%endfor%}

示例结果:

playbook加密

    - ansible-vault:管理加密解密yml文件
    - ansible-vault encrypt hello.yml 加密
    - ansible-vault decrypt hello.yml 解密
    - ansible-vault view hello.yml 查看
    - ansible-vault edit hello.yml 编辑加密文件
    - ansible-vault rekey hello.yml 修改口令
    - ansible-vault create new.yml 创建新文件
标签:Ansible 发布于:2019-10-28 11:48:37