ansible-Playbook

一、YAML语言概述

1.YAML介绍(playbook采用YAML格式配置文件)

  • YAML:是一种非标记语言。用来配置文件的语言,非常简洁和强大
  • YAML语法和其他语言类似,也可以表达散列表、标量等数据结构
  • 结构通过空格来展示;序列里配置项通过-来代表;Map里键值用:来分隔
  • YAML的扩展名为yaml

2.YAML基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • ’#’.表示注释

3.YAML支持的数据类型

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分

二、Playbook剧本

1.Playbook介绍

通过task调用ansible的模块将多个play组织在一个playbook中运行。playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。

2.Playbook核心元素

  • Tasks:任务,即调用模块完成的某操作
  • Variables:变量
  • Templates:模板
  • Handlers:处理器,当某条件满足时,触发执行的操作
  • Roles:角色

3.一个完整的playbook主要构成

  • 1.主机组hosts
  • 2.授权执行的用户remote_user
  • 3.执行的任务tasks(调用的是各种ansible模块)

4.横杆的作用

短横杠(-):
表示一个整体关系,通常用于一段完整的playbook开头、定义的变量名前、单条任务的开头(任务名name前)
一个playbook脚本内可同时有多个剧本,以开头的短横杠定义为一个剧本,例:

- hosts: webservers
  ...
- hosts: mysql
  ...

若使用三个短横杠(—)独占一行,则表示以上内容为一个单独文件,以下内容为另一个单独文件,互不干扰,例:

- hosts:webservers
  ...
---
- hosts:mysql
  ...

5 playbook脚本执行

语法格式

ansible-playbook [yaml文件名]

示例

ansible-playbook httpd.yaml

参数
-k(-ask-pass):用来交互输入ssh密码
-k(-ask-become-pass):用来交互输入sudo密码
-u:指定用户
–syntax-check:检查yaml文件的语法是否正确
–list-task:检查tasks任务
–list-hosts:检查生效的主机
–start-at-task=’ 任务名(name)’:指定从某个task开始运行

三、 hosts和users介绍

在playbook中的每一个play都可以选择在哪些服务器和以什么用户完成,hosts一行可以是一个主机组、主机、多个主机,中间以冒号分隔,可使用通配模式。其中remote_user表示执行的用户账号。

[root@ansible ~]# vivi demo.yaml 
- hosts: apache		#指定主机组,可以是一个或多个组。
  remote_user: root		#指定远程主机执行的用户名
  tasks:
   - name: test connection
     ping:
     remote_user: root

[root@ansible ~]# ansible-playbook demo.yaml -k  ## 执行playbook-k(–ask-pass) 用来交互输入ssh密码
SSH password: 

PLAY [apache] ************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [192.168.10.20]

TASK [test connection] ***************************************************************************************
ok: [192.168.10.20]

PLAY RECAP ***************************************************************************************************
192.168.10.20              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

指定远程主机sudo切换

[root@ansible ~]# cat sudo.yaml 
- hosts: apache
  remote_user: root
  become: yes		#2.6版本以后的参数,之前是sudo,意思为切换用户运行
  become_user: apache		 #指定sudo用户为apache

ansible-playbook sudo.yaml -k  ## 执行playbook -k(–ask-pass) 用来交互输入ssh密码

四、tasks列表和action

1:Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务。
在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。
Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为其结果一致。
2:每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。如果没有定义name,‘action’的值将会用作输出信息中标记特定的task。
3:定义一个task,常见的格式:”module: options” 例如:yum: name=httpd
4:ansible的自带模块中,command模块和shell模块无需使用key=value格式

[root@ansible ~]# vi http.yaml    ## yum安装apache服务并为其提供一个主页
- hosts: apache
  remote_user: root
  tasks:
   - name: install httpd
     yum: name=httpd
   - name: start httpd
     service: name=httpd state=started
   - name: stop firewalld
     service: name=firewalld state=stopped
   - name: touch index
     copy: content="this is my apache" dest=/var/www/html/index.html

[root@ansible ~]# ansible-playbook apache.yaml 

PLAY [apache] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.10.20]

TASK [install httpd] ***********************************************************
changed: [192.168.10.20]

TASK [start httpd] *************************************************************
changed: [192.168.10.20]

TASK [stop firewalld] **********************************************************
ok: [192.168.10.20]

TASK [touch index] *************************************************************
ok: [192.168.10.20]

PLAY RECAP *********************************************************************
192.168.10.20              : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

回滚举例:

Firewalld写为Firewall来模拟错误,验证回滚,若发生错误,将会回滚到错误发生前,和游戏中的回档类似
执行到stop Firewalld的时候会反馈报错信息,并停止下一步操作,回滚到错误发生之前,访问网页也是没有主页展示的
play中只要执行命令的返回值不为0,就会报错,tasks停止,可以添加下面
ignore_errors: True #忽略错误,强制返回成功

[root@ansible ~]# vi http.yaml
- hosts: apache
  remote_user: root
  tasks:
   - name: install httpd
     yum: name=httpd
   - name: start httpd
     service: name=httpd state=started
   - name: stop firewalld
     service: name=firewall state=stoppped
     ignore_errors: True  	#忽略错误,强制返回成功
   - name: touch index
     copy: content="this is my apache" dest=/var/www/html/index.html
[root@ansible ~]# ansible-playbook apache.yaml 

PLAY [apache] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.10.20]

TASK [install httpd] ***********************************************************
changed: [192.168.10.20]

TASK [start httpd] *************************************************************
changed: [192.168.10.20]

TASK [stop firewalld] **********************************************************
fatal: [192.168.10.20]: FAILED! => {"changed": false, "msg": "Could not find the requested service firewall: host"}
...ignoring

TASK [touch index] *************************************************************
ok: [192.168.10.20]

PLAY RECAP *********************************************************************
192.168.10.20              : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   
## 成功了五个,修改了两个,跳过了一个

五、Handlers和notify介绍

  • andlers也是一些task的列表,和一般的task并没有什么区别。
  • 是由通知者进行的notify,如果没有被notify,则Handlers不会执行,假如被notify了,则Handlers被执行
  • 不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次
[root@ansible ~]# vi http.yaml
- hosts: apache
  remote_user: root
  tasks:
   - name: install httpd
     yum: name=httpd
   - name: install configuration file for httpd
     copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
     notify:
      - restart httpd
   - name: restart httpd
     service: name=httpd state=started
   handlers:
    - name: restart httpd
      service: name=httpd state=restarted
## 执行到notify的restart httpd时会先执行下面的handlers,handlers执行完了会返回notify继续执行,并且下面的handlers不会再执行了

六、引用变量

1.vars: 添加变量

[root@ansible ~]# vi http.yaml 
- hosts: apache
  remote_user: root
  vars:
   - package: httpd   ## vars下方可以添加变量
   - service: httpd
  tasks:
   - name: install httpd
     yum: name={{package}}  ## {{}}引用变量
   - name: start httpd
     service: name={{service}} enabled=true state=started

2.直接引用Ansible变量,ansible自带的固有变量

ansible_all_ipv4_addresses 获取IP

[root@ansible ~]# vi ipadress.yaml 
- hosts: apache
  remote_user: root
  tasks:
   - name: copy file
     copy: content="{{ansible_all_ipv4_addresses}}" dest=/opt/ip.txt

常用ansible固定变量:

ansible_all_ipv4_addresses:ipv4地址
ansible_distribution:系统类型
ansible_distribution_major_version:系统版本

3.引用主机变量

在组的主机后面添加变量

[root@ansible ~]# vi /etc/ansible/hosts
[apache]
192.168.10.20 test="this is a test file"
[mysql]
192.168.10.30

- hosts: apache
  remote_user: root
  tasks:
   - name: copy file
     copy: content="{{test}}" dest=/opt/test.txt

[root@ansible ~]# ansible apache -a 'cat /opt/test.txt'
192.168.10.20 | CHANGED | rc=0 >>
this is a test file

4.条件语句跟变量

执行playbook的时候可以用-e 来引用变量

- hosts: apache
  remote_user: root
  tasks:
   - name: copy file
     copy: content="{{test2}}" dest=/opt/test2.txt

[root@ansible ~]# ansible-playbook ipadress.yaml -e test2="anotherone"

[root@ansible ~]# ansible apache -a 'cat /opt/test2.txt'
192.168.10.20 | CHANGED | rc=0 >>
anotherone

七、 条件判断

when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行
如果需要根据变量、facts(setup)或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when子句。

1.普通条件判断

在task后添加when子句即可使用条件测试:when子句支持jinjia2表达式或语法,例如:

- hosts: apache
  remote_user: root
  tasks:
   - name: shutdown
     command: /sbin/shutdown -h now
     when: ansible_distribution=="Centos"
## 当系统是Centos系统时就会执行关机指令

2.多条件判断

- hosts: apache
  remote_user: root
  tasks:
   - name: shutdown
     command: /sbin/shutdown -h now
     when: 
       - ansible_distribution=="Centos"
       - ansible_distribution_major_version=="7"
## 当系统是CentOS系统,并且版本号为7才会执行关机语句,两项都满足

3.组条件判断

- hosts: apache
  remote_user: root
  tasks:
   - name: shutdown Centos6 Centos7
     command: /sbin/shutdown -h now
     when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or (ansible_distribution == "CentOS" ansible_distribution_major_version == "7")

八、迭代

有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素列表即可。

1.单个需要迭代的内容

- hosts: apache
  remote_user: root
  tasks:
   - name: install packages
     yum: name={{ item }} state=latest
     with_items:
      - httpd
      - php
## 依次安装httpd 和php这两服务

2.多个需要迭代的内容(自己定义item变量)

- hosts: webservers
  remote_user: root
  tasks:
   - name: add user
     user: name={{item.name}} uid={{item.uid}}
     with_items:
      - {name:'zhangsan' uid:'1001'}
      - {name:'lisi' uid:'1002'}
      - {name:'wangwu' uid:'1003'}

九、tags模块

在一个playbook中,如果我们只想执行某一个task或多个task时可使用tags标签,执行playbook时只执行定义tags标签的任务

示例:
只执行了copy hosts任务,copy log任务未执行

[root@ansible ~]# vi cpfile.yaml
- hosts: 192.168.20.10
  remote_user: root
  tasks:
  - name: copy hosts
    copy: src=/etc/hosts dest=/opt/hosts.bak
    tags:
    - only		#自定义标签名
  - name: copy log
    copy: src=/var/log/messages dest=/opt/log.bak

ansible-playbook cpfile.yaml --tags="only"	   ##执行playbook,加上tags参数并指定执行的tags标签,将只执行带有此标签的任务

特定标签名:always
当tags的标签名为always时,无论执行哪一个tags时,定义为always的任务都必须被执行

[root@ansible ~]# vi cpfile.yaml
- hosts: 192.168.20.10
  remote_user: root
  tasks:
  - name: copy hosts
    copy: src=/etc/hosts dest=/opt/hosts.bak
    tags:
    - only		#自定义标签名
  - name: copy log
    copy: src=/var/log/messages dest=/opt/log.bak
    tags:
    - always

[root@ansible ~]# ansible-playbook cpfile.yaml --tags="only"
##此时所有任务都被执行

十、roles

roles能够根据层次性结构自动装载变量文件、task以及handlers等。简单说,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷的include它

在/etc/ansible/中默认存在一个空目录roles,可在里面创建各种需要装载的文件

1.roles内各目录含义

  • files: 用来存放由copy模块或script模块调用的文件
  • templates: 用来存放jinjia2模板,templates模块会自动在此目录中寻找jinjia2模板文件
  • tasks: 此目录包含一个main.yaml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件
  • handlers: 此目录包含一个main.yaml文件,用于定义此角色中触发条件时执行的动作
  • vars: 此目录包含一个main.yaml文件,用于定义此角色用到的变量
  • defaults: 此目录包含一个main.yaml文件,用于为当前角色设定默认变量
  • meta: 此目录包含一个main.yaml文件,用于定义此角色的特殊设定及其依赖关系
    角色目录: 在roles目录下的直接目录,自定义目录名,存放以上所有的功能目录

2.使用roles步骤

1.创建全局变量目录

[root@ansible ~]# mkdir -p /etc/ansible/group_vars
[root@ansible ~]# touch /etc/ansible/group_vars/all_vars		#文件名自定义,用于引用,里面可设置全局变量

2.创建角色目录

[root@ansible ~]# mkdir -p /etc/ansible/roles/httpd

3.在角色目录下创建所有功能目录

[root@ansible ~]# mkdir -p /etc/ansible/roles/httpd/{file,templates,tasks,handlers,vars,defaults,meta}

4.在需要main.yaml文件的目录下创建

[root@ansible ~]# touch etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yaml

5.按需要在功能目录内添加内容
如:
tasks在main.yaml内写入任务
templates内加入jinjia2模板

6. 编辑playbook并调用角色

[root@ansible ~]# vi server.yaml
- hosts: webservers
  remote_user: root
  roles:
   - httpd
   - mysql		#可调用多个角色目录

[root@ansible ~]# ansible-playbook server.yaml	#正常执行

十一、总结

playbook是由一个或多个模块组成的,使用多个不同的模块,完成一件事情。需要熟练掌握ansible中各个模块对应的功能以及YAML的语法规则。
缩进: YAML使用一个固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用tabs;
冒号: 以冒号结尾的除外,其他所有冒号后面所有必须有空格;
短横线: 表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值