YAML:能够将你打算对多机器的批量操做放到一个文件中,顺序执行,能够根据机器作到根据机器信息判断执行,其余命令执行结果判断执行。linux
YAML有着严格的层级要求,稍微有个缩进问题就会没法运行,因此学习过程当中,须要细心观察。nginx
命令 指定hosts文件位置 剧本文件 参数shell
-C 调试模式,调试剧本是否能够正常运行(这个模式中,任何更改的操做都不会执行)centos
ansible-playbook -i hosts yaml.file ansible-playbook -i hosts yaml.file -C
剧本开始语法bash
--- #一个标识符,相似#!/bin/bash - hosts: all #此剧本做用域 remote_user: root #使用什么用户运行此剧本 gather_facts: True #在远程主机运行setup模块,并将收集的信息记录起来(等于命令ansible all -m setup#查看系统信息),能够经过系统信息来判断是否执行 vars: #定义变量 variable: values tasks: #任务开始标签 - name: task_name model_name: values
每个任务,能够指定必定的操做,定义一个任务基础参数以下服务器
#一个用name模块被'命名'任务下只容许有一个同级的模块存在(不包括辅助功能,后面会讲)学习
- name: task_name
model_name: values
yaml语法中结构:测试
[ { 'name': 'task_name', 'model_name': 'values' } ]
如下这种状况,命名任务与模块是同级的状况下,能够正常执行,只是不在命名任务模块下的模块执行起来显示的是是模块名称,而不是任务名称(例子1-1),任务多了没法判断url
- model_name: values
- name: task_name
model_name: values
- model_name: values
yaml语法中结构:centos7
[ {'model_name': 'values'}, { 'name': 'task_name', 'model_name': 'values' }, {'model_name': 'values'} ]
例子1-1
[root@host1 [10:02:30]/yaml/test]#cat test.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping: - ping: [root@host1 [10:02:32]/yaml/test]#ansible-playbook -i hosts test.yaml PLAY [all] *********************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************** ok: [192.168.100.3] TASK [ping test] ***************************************************************************************************************************************************** ok: [192.168.100.3] TASK [ping] ********************************************************************************************************************************************************** ok: [192.168.100.3] PLAY RECAP *********************************************************************************************************************************************************** 192.168.100.3 : ok=3 changed=0 unreachable=0 failed=0 [root@host1 [10:02:41]/yaml/test]#
实际状况演练
新建下方文件:
[root@host1 [18:32:56]/yaml/test]#cat test.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping:
上方意思是新建ping test的任务,并执行ping模块,测试连通性,看下方结果,能够看到任务标签,而且状态也是成功的。(Gathering Facts 表明或许系统信息,也是成功的)
#如下以"状况"的形式,向你们讲解如何使用经常使用方法
状况1:你的环境中有多台机器,分别有CentOS6系统和CentOS7系列系统,两类系统在某些方面多是不同的,你如今两台机器上执行不一样的操做,让咱们来看看怎么实现。
hosts文件内容
100.3为centos6 秘钥对认证,能够免密链接
100.7为centos7 没作过密钥对认证,经过密码认证
192.168.100.3 192.168.100.7 ansible_user=root ansible_password=nihao123!
执行下方命令
ansible all -m setup
返回的是主机的信息,如系统类型,ip地址等,ansible能够根据这些作过滤
在此状况下,咱们能够经过 ansible_distribution和ansible_distribution_major_version进行匹配(如下是两台主机的信息组合,由于我使用的grep过滤的我须要的字段)
[root@host1 [14:30:55]/yaml/test]#ansible -i hosts all -m setup |grep "ansible_distribution" "ansible_distribution": "CentOS", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "7", "ansible_distribution_release": "Core", "ansible_distribution_version": "7.2.1511", "ansible_distribution": "CentOS", "ansible_distribution_file_parsed": true, "ansible_distribution_file_path": "/etc/redhat-release", "ansible_distribution_file_variety": "RedHat", "ansible_distribution_major_version": "6", "ansible_distribution_release": "Final", "ansible_distribution_version": "6.5",
编写下方剧本。
根据when执行判断条件,当系统版本为6时执行对应的任务,为7时执行对应的任务。
[root@host1 [15:37:42]/yaml/test]#cat test2.yaml --- - hosts: all remote_user: root gather_facts: True tasks: - name: "ping test" ping: - name: "only on Centos6" shell: "echo 'ON THE Centos6'" when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6' - name: "only on Centos7" shell: "echo 'ON THE Centos7'" when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
执行测试,能够看到,任务执行时,都执行了对应的匹配条件,只有条件经过才执行对应的shell模块指定的命令,不经过时跳过执行。
when匹配方式有多种,除了咱们使用的a=a and b=b以外,大体经常使用的以下
when: (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') or (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '5') #等同于and,匹配多个条件 when: -ansible_distribution== "CentOS" -ansible_distribution_major_version== "6" #对数字作大于小于的判断 when:ansible_distribution_major_version|int >= 6 #定义变量,并根据变量来判断对应任务是不是否执行 vars: epic: true when: epic when not epic #经过上个模块执行结果来判断此模块是否执行(result|failed 能够替换为result is failed ),此方法使用方法详见例子1-2 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
例子1-2
新建下方剧本,
剧本含义:当cat /etc/fapweifjapewijfapwejfpawjf成立时,判断"when: result is success"才成立
(须要配合
register: result #将执行结果记录到result变量上,给when提供判断条件
ignore_errors: True #跳过错误,错误时继续执行,给when提供判断机会
使用)
--- - hosts: all remote_user: root gather_facts: True tasks: - shell: "cat /etc/fapweifjapewijfapwejfpawjf" register: result ignore_errors: True - shell: "head -10 /etc/fapweifjapewijfapwejfpawjf" when: result is success
执行结果
状况2:须要给多台机器添加yum源配置
像这种问题,就是须要使用echo "" >> ..repo 到文件中去,可是,yum仓库的配置可不是只是一项,有什么能写的更简洁的方法呢。
with_items 一个迭代器,你能够在里面定义不少的东西,而后在某处引用时,里面的东西会循环的输出,直到定义的值输出完。
相似下方例子
items=[1,2,3,4,5,6,7,8] for i in items: print(i)
新建下方剧本
gather_facts: no 在不须要获取机器信息时,根据信息作判断时,将其关闭,避免影响执行速度。
定义名称:with_items,调用名称:item都是固定的,不能更改.
{{variable}} 调用变量的方法,也是调用迭代器的方法。
--- - hosts: all remote_user: root gather_facts: no tasks: - name: "setting yum" shell: "echo {{ item }} >> /etc/yum.repos.d/base.repo" with_items: - "[base]" - "name=base" - "baseurl=ftp://10.124.164.114/pub/Server" - "enabled=1" - "gpgcheck=0"
在客户端上查看结果,已经正常写入。
状况3:你须要一次操做多个服务,如启动,重启等。
你可使用状况2中的,定义with_items方法,可是你须要去with_items字段中定义,代码量多了不免有点麻烦,咱们能够结合变量使用(在文首就直接定义了),定义一个列表,而后将列表传给with_items,交由它来作一个迭代器,当引用item时引用多个值。
问:为何不直接在{{}}中引用变量,而要引用迭代器
由于变量没法在引用时被循环,就算列表里面有多个值,它引用时也只会识别一个列表,就是[nginx,ntpd]。
--- - hosts: all remote_user: root gather_facts: no vars: service_list: [nginx,ntpd] service_state: restarted tasks: - service: name="{{item}}" state="{{service_state}}" with_items: '{{ service_list }}'
状况4:你的剧本文件中,定义了不少功能,可是此次,你只想运行某个功能,该如何实现呢。
debug模块,只是一个功能,在此状况中,能够用任何模块替换,此模块是将msg定义的消息回显到终端,供咱们调试。
tags标签,定义在模块下,标签名称建议有意义,无难输入的特殊字符,无空格
--- - hosts: all remote_user: root gather_facts: no tasks: - debug: msg="task 1" tags: task1 - debug: msg="task two" tags: task2
执行测试
此状况重点来了,单独运行某个标签。使用以下命令
只运行task1标签的任务
[root@host1 [18:17:53]/yaml/test]#ansible-playbook -i hosts --tags=task1 test5.yaml
学习了上面的使用状况,你已经能够写一个属于你的yaml剧本,使用什么模块实现什么功能,这个你能够边学边用,你能够试着完成下方我根据我工做环境自制的精简版ansible yaml剧本练习做业,巩固你的学习。
如下要求须要在你写时,写在同一剧本中
1.新建用户 admin,deployer,并定义密码
2.设置用户永不过时
3.备份/home/admin/ 的全部文件(包括隐藏文件) ,(假设你有一个叫/dev/vdb的磁盘),判断/dev/vdb是否挂载,若是挂载了,就不用管,若是没有挂载,将其挂载到/home/admin/ ,恢复你备份的文件至/home/admin/
4.同步服务器的时间,将时间同步服务设置为自启动
5.先零时,后永久的增长ulimit ("max user processes", "open files", "pending signals")这三个值的大小,具体大小自定义,达到更改效果便可。
6.先零时关闭防火墙,selinux,后设置永久关闭。
7.将hostname 和本机ip的对应关系增长至/etc/hosts文件中
8.设置yum仓库,让其能正常下载软件,
9,支持运行此剧本时,指定值运行[同步时间]任务,而不设置时间同步服务自启动