ansible剧本---playbook的介绍与应用

1.YAML概述

1.1 YAML相关介绍

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

1.2 基本语法规则

  • 大小写敏感;
  • 使用缩进表示层级关系;
  • 缩进时不允许使用Tab键,只允许使用空格;
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。

1.3 YAML支持的数据结构

1.对象:键值对的集合,又称为映射(mapping) /哈希(hashes) /字典(dictionary)
例如: name:Test Developer
     变量名:对象名  属性

2.数组: 一组按次序排列的值,又称为序列(sequence) / 列表(list)
例如: -Apple
     -Green

3.纯量: 单个的,不可再分的值
例如: number: 17.50
     变量名:数值

2. playbooks 简介

2.1 playbook 剧本

  • 剧本是Ansible的配置、部署语言,由它对描述你想要远程机器执行的策略或步骤
  • 使用剧本不仅可以简单的对远程机器进行管理,还有很多更强大的功能

2.2 playbooks 组成部分

  • 通过task调用ansible的模板将多个play组织在一 个playbook中运行。
  • playbooks本身由以下各部分组成:
1)Tasks:任务,即调用模块完成的某操作
2)Variables:变量
3)Templates:模板
4)Handlers:处理器,当某条件满足时,触发执行的操作
5)Roles:角色
  • playbooks 核心组成:
    hosts:主机信息
    tasks:任务信息
    remote_user: root:指定远程主机执行的用户名

2.3 剧本三要素

剧本 playbook
场地 主机组hosts
演员 授权执行的用户 remote_user
故事情节 执行的任务 tasks(调用的是各种ansible模块)

2.4 playbook 的补充命令

ansible-playbook nginx.yaml --syntax-check  //检查 yaml 文件的语法是否正确
ansible-playbook nginx.yaml --list-task     //检查 tasks 任务
ansible-playbook nginx.yaml --list-hosts    //检查生效的主机
ansible-playbook nginx.yaml --start-at-task='Copy Nginx.conf’ //指定从某个task开始运行

3. playbook 的应用与操作

hosts和users差别
hosts: webserver    指定主机组,可以是-一个或多个组。
remote user: root   指定远程主机执行的用户名
这里ansible主机清单如下:
[webserver]
192.168.140.21 --》对应node1
[mysql]
192.168.140.22 --》对应node2

3.1 编写测试连通性剧本

  • 首先在node1节点上创建用户 lisi,并设置密码
[root@node1 ~]# useradd lisi
[root@node1 ~]# passwd lisi
[root@node1 ~]# id lisi
uid=1001(lisi) gid=1001(lisi) 组=1001(lisi)
  • 在主节点上编写剧本
[root@master ~]# vi test01.yaml
- hosts: webserver
  remote_user: root
  tasks:
  - name: test connection
    ping:
    remote_user: lisi
    
[root@master ~]# ansible-playbook test01.yaml --syntax-check		//检查语法

playbook: test01.yaml
[root@master ~]# ansible-playbook test01.yaml			//运行脚本
  • 出现报错,权限被拒绝
    在这里插入图片描述
  • 解决方法:更改权限
[root@master ~]# vi test01.yaml
- hosts: webserver
  remote_user: root
  tasks:
  - name: test connection
    ping:
    remote_user: root		//指定远程主机执行tasks的运行用户为root
    
[root@master ~]# ansible-playbook test01.yaml

在这里插入图片描述

3.2 指定远程用户切换用户执行任务

  • 指定远程主机sudo切换用户指定远程主机sudo切换用户
  • 编写执行任务
[root@master ~]# vi test02.yaml
- hosts: webserver
  remote_user: root
  become: yes			//切换用户运行
  become_user: lisi		//指定远程用户为lisi
  tasks:				//执行任务
  - name: copy text		//复制文本测试
    copy: src=/etc/fstab dest=/home/lisi/fstab.bak	//src表示原文件位置,dest表示目标位置

[root@master ~]# ansible-playbook test02.yaml --syntax-check
[root@master ~]# ansible-playbook test02.yaml

在这里插入图片描述

  • 验证
[root@node1 ~]# cd /home/lisi/
[root@node1 lisi]# ll
总用量 4
-rw-r--r--. 1 lisi lisi 690 1月  21 00:10 fstab.bak

3.3 httpd服务的剧本应用

  • 要求:安装 apache 服务并开启服务,创建测试网页,关闭防火墙
  • 编写剧本任务
[root@master ~]# vim test03.yaml
- hosts: webserver
  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 server1" dest=/var/www/html/index.html

[root@master ~]# ansible-playbook test03.yaml --syntax-check
[root@master ~]# ansible-playbook test03.yaml

在这里插入图片描述

  • 验证
[root@node1 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64

在这里插入图片描述
在这里插入图片描述
注意:

  • 不管操作命令多少,标题name都不可以缺少

3.4 剧本的回滚操作

3.4.1 tasks列表和action

1.Play的主体部分是task列表, task列表中的各任务按次序逐个在hosts中指定的主机上执行。
即在所有主机上完成第一个任务后再开始第二个任务,在运行playbook时(从上到下执行) 。
如果一个host执行task失败,tasks会回滚到报错前的状态,即在报错前的操作命令会执行,但报错后的命令不会执行;
在修正playbook中的错误后,重新执行即可。

2.Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的。这意味着多次执行是安全的,
因为其结果一致。

3.每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。 

4.定义一个task, 常见的格式:”module: options" 例如: yum: name=httpd

5.ansible的自带模块中,command模块和shell模块无需使用key=value格式

3.4.2 编写带有错误任务的剧本

[root@master ~]# vi test04.yaml 
- hosts: mysql
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd
  - name: start httpd
    service: name=httpd state=start		//开启服务状态写错,应该是started
  - name: stop firewalld
    service: name=firewalld state=stopped

[root@master ~]# ansible-playbook test04.yaml --syntax-check
[root@master ~]# ansible-playbook test04.yaml
//执行脚本会报错

在这里插入图片描述

  • 查看任务的执行结果
    在这里插入图片描述
  • 总结:当任务正确执行change完后,任务已经执行完成;
    当执行错误任务的时候,执行的任务会进行回滚,后面的任务也不再执行,执行的任务和后面的任务都不在执行

3.4.3 修改文件,添加忽略内容

[root@master ~]# vi test04.yaml		//修改剧本配置
- hosts: mysql
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd
  - name: start httpd
    service: name=httpd state=start
    ignore_errors: True		//添加:忽略错误,强制返回成功
  - name: stop firewalld
    service: name=firewalld state=stopped

[root@master ~]# ansible-playbook test04.yaml --syntax-check
[root@master ~]# ansible-playbook test04.yaml		//重新执行任务

在这里插入图片描述

  • 验证防火墙是否关闭
[root@node2 ~]# systemctl status firewalld

在这里插入图片描述

3.5 多个节点用户分别进行执行对应不同的任务

  • 编写任务
[root@master ~]# vi test05.yaml
- hosts: webserver   
  remote_user: root
  tasks:
  - name: create nginx group     
    group: name=nginx system=yes gid=300  
  - name: create nginx user
    user: name=nginx system=yes uid=300 group=nginx  
- hosts: mysql   
  remote_user: root
  tasks:
  - name: copy file to mysql   
    copy: src=/etc/inittab dest=/opt/inittab.bak

[root@master ~]# ansible-playbook test05.yaml --syntax-check
[root@master ~]# ansible-playbook test05.yaml
  • 验证结果
[root@node1 ~]# cat /etc/group | grep nginx
nginx:x:300:
[root@node1 ~]# cat /etc/passwd | grep nginx
nginx:x:300:300::/home/nginx:/bin/bash

[root@node2 ~]# cd /opt/
[root@node2 opt]# ll
...
-rw-r--r--. 1 root root 511 12月 14 20:31 inittab.bak

4.变量配置

4.1 Handlers介绍

1) Handlers也是一些task的列表,和一般的task并没有什么区别。
2) 是由通知者进行的notify,如果没有被notify, 则Handlers不会执行,假如被notify了, 则Handlers被执行
3) 不管有多少个通知者进行了notify, 等到play中的所有task执行完成之后,handlers也只会被执行一次
  • 应用示例
首先在node1节点上移除httpd服务
yum -y remove httpd

[root@node1 ~]# rpm -q httpd
未安装软件包 httpd
编写运行任务
[root@master ~]# vi test06.yaml
- hosts: webserver
  remote_user: root
  tasks:        
  - name: install httpd package        
    yum: name=httpd state=latest   
  - name: install configuration file for httpd      
    copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf	//注意复制时,需要确保src源文件存在
    notify:
    - restart httpd 
  - name: start httpd service
    service: enabled=true name=httpd state=started
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted
    
//拷贝完后文件需要重启服务,notify用了restart httpd, handlers 搜索到了restart httpd 就会自动去执行,
然后再执行 start httpd service;若是没有搜索到 restart httpd,则不会执行 start httpd service

[root@master ~]# ansible-playbook test06.yaml --syntax-check
[root@master ~]# ansible-playbook test06.yaml

4.2 引入变量

  • 在playlook中设置变量,执行
首先在node1节点上移除httpd服务
yum -y remove httpd

[root@node1 ~]# rpm -q httpd
未安装软件包 httpd
[root@node1 ~]# cd /var/www/html/
[root@node1 html]# ls
index.html
[root@node1 html]# rm -rf *
在master上设置剧本
[root@master ~]# vi test07.yaml
- hosts: webserver
  remote_user: root
  vars:
  - apple: httpd		//apple表示变量,httpd表示数值
  tasks:
  - name: install httpd
    yum: name={
   
   {apple}}
  - name: start httpd
    service: name={
   
   {apple}} state=started
  - name: stop firewalld
    service: name=firewalld state=stopped
    ignore_errors: True
  - name: touch index
    copy: content="This is a server2" dest=/var/www/html/index.html
    
[root@master ~]# ansible-playbook test07.yaml --syntax-check
[root@master ~]# ansible-playbook test07.yaml
  • 验证
[root@node1 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node1 ~]# cd /var/www/html/
[root@node1 html]# ls
index.html

在这里插入图片描述

4.3 playbooks 使用变量的方法

4.3.1 通过 ansible 命令传递

  • 编写任务
[root@master ~]# vi example1.yaml
- hosts: webserver
  remote_user: root
  vars:
  - user: 		//引用变量为空
  tasks:
  - name: add user
    user: name={
   
   {user}}
  • 执行任务的时候加上变量名
[root@master ~]# ansible-playbook example1.yaml -e "user=zhaoyun"

在这里插入图片描述

  • 验证
[root@node1 ~]# id zhaoyun
uid=1002(zhaoyun) gid=1002(zhaoyun) 组=1002(zhaoyun)

4.3.2 直接引用一些变量

  • 系统固定变量,为ansible自带的系统变量
  • 编写任务
[root@master ~]# vi example2.yaml
- hosts: all
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{
   
   {ansible_all_ipv4_addresses}}" dest=/opt/addr1.txt
  • 运行剧本
[root@master ~]# ansible-playbook example2.yaml
  • 验证
[root@node1 ~]# cat /opt/addr1.txt
["192.168.122.1", "192.168.140.21"]

[root@node2 ~]# cat /opt/addr1.txt
["192.168.122.1", "192.168.140.22"]

4.3.3 引用主机变量

  • 设置主机变量
[root@master ~]# vi /etc/ansible/hosts
[webserver]
192.168.140.21 number="777"		//number 的值为777
  • 编写剧本任务
[root@master ~]# vi example3.yaml
- hosts: webserver
  remote_user: root
  tasks:
  - name: copy file
    copy: content="{
   
   {ansible_all_ipv4_addresses}},{
   
   {number}}" dest=/opt/addr2.txt
  • 执行剧本
[root@master ~]# ansible-playbook example3.yaml 
  • 验证
[root@node1 ~]# cat /opt/addr2.txt
([u'192.168.122.1', u'192.168.140.21'], 777)

5.条件测试

  • 如果需要根据变量、facts (setup) 或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试
1.在Playbook中条件测试使用when
2.在task后添加when子句即可使用条件测试: when子句支持 jinjia2 表达式或语法

5.1 单条件判断

  • 在node1上查看系统版本
[root@node1 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
  • 编写剧本
[root@master ~]# vi ce1.yaml
- hosts: webserver
  remote_user: root
  tasks:
  - name: "shutdown CentOS"    
    command: /sbin/shutdown -h now    
    when: ansible_distribution == "CentOS"		//当ansible分配系统为CentOS时关闭系统
  • 运行剧本
[root@master ~]# ansible-playbook ce1.yaml

在这里插入图片描述

  • 出现报错,原因node1系统关闭
[root@node1 ~]# cat /etc/redhat-release 
Connection closed by foreign host.

5.2 多条件判断

  • 编写剧本
[root@master ~]# vim ce2.yaml
- hosts: mysql
  remote_user: root
  tasks:
  - name: "shutdown CentOS 7 systems"
    command: /sbin/shutdown -h now
    when:
    - ansible_distribution == "CentOS"           
    - ansible_distribution_major_version == "7"
	//满足以上条件才执行以上模块操作

  • 运行剧本
[root@master ~]# ansible-playbook ce2.yaml
  • 出现报错,原因node1系统关闭

5.3 组条件判断

  • 编写剧本
[root@master ~]# vim ce3.yaml
- hosts: mysql
  remote_user: root
  tasks:
  - name: "shutdown CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
          (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
  • 运行剧本
[root@master ~]# ansible-playbook ce3.yaml

在这里插入图片描述

  • skipped:跳过

6.迭代

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

  • 语法解析

for  item(变量) in  with_items(集合)
do
    命令
done

6.1 安装软件

  • 准备环境,在node2上
[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node2 ~]# yum -y remove httpd		//移除httpd服务
[root@node2 ~]# rpm -q tomcat
未安装软件包 tomcat
  • 编写剧本
[root@master ~]# vi update.yaml
- hosts: mysql
  remote_user: root
  tasks:
  - name: install apache tomcat
    yum: name={
   
   {item}}
    with_items:
      - httpd
      - tomcat
  • 检查语法并运行
[root@master ~]# ansible-playbook update.yaml --syntax-check
[root@master ~]# ansible-playbook update.yaml

在这里插入图片描述

  • 验证
[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node2 ~]# rpm -q tomcat
tomcat-7.0.76-2.el7.noarch

6.2 添加用户到组

  • 首先创建用户和组
在node2节点上创建
[root@node2 ~]# useradd pl1
[root@node2 ~]# passwd pl1
[root@node2 ~]# useradd pl2
[root@node2 ~]# passwd pl2

[root@node2 ~]# groupadd yang
[root@node2 ~]# groupadd feng
  • 编辑剧本
[root@master ~]# vi user1.yaml
- hosts: mysql
  remote_user: root
  tasks:
  - name: "Add users"
    user: name={
   
   {item.name}} state=present groups={
   
   {item.groups}}
    with_items:
     - { name: 'pl1',groups: 'yang'}
     - { name: 'pl2',groups: 'feng'}
  • 检查语法并运行
[root@master ~]# ansible-playbook user1.yaml --syntax-check
[root@master ~]# ansible-playbook user1.yaml

在这里插入图片描述

  • 验证
[root@node2 ~]# cat /etc/group | grep pl1
pl1:x:1008:
yang:x:1010:pl1
[root@node2 ~]# cat /etc/group | grep pl2
pl2:x:1009:
feng:x:1011:pl2

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42449832/article/details/112856557