Ansible playbook

一、Ansible playbook 简介和使用场景

1、简介

  • playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。
  • 通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list ,而被控节点必须要完成。
  • 也可以这么理解,playbook 字面意思,即剧本,现实中由演员按照剧本表演,在Ansible中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。

2、使用场景

  • 执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行的ad-hoc命令是不适合的,这时最好使用playbook。
  • 就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
  • 使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。在你使用Ansible的过程中,你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。

二、playbook格式

1、基本格式
playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。

YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。首先学习了解一下YMAL的格式,对我们后面书写playbook很有帮助。以下为playbook常用到的YMAL格式:

  • 文件的第一行应该以 “—” (三个连字符)开始,表明YMAL文件的开始。
  • 在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
  • YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。
  • 同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
  • play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":“分隔表示,”:"后面还要增加一个空格。

举例:

---
#安装与运行mysql服务
 - hosts: node1
   remote_user: root
   tasks:
  
    - name: install mysql-server package
      yum: name=mysql-server state=present
    - name: starting mysqld service
      service: name=mysql state=started

文件名称应该以.yml结尾,像我们上面的例子就是mysql.yml。其中,有三个部分组成:

  • host部分:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行 task 的过程中。
  • remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。
  • 指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

2、核心元素

  • Hosts:主机组;
  • Tasks:任务列表;
  • Variables:变量,设置方式有四种;
  • Templates:包含了模板语法的文本文件;
  • Handlers:由特定条件触发的任务;

3、基本组件

  • Hosts:运行指定任务的目标主机
  • remoute_user:在远程主机上执行任务的用户;
  • sudo_user:
  • tasks:任务列表
  • handlers:任务,在特定条件下触发;接收到其它任务的通知时被触发;
  任务格式:
    tasks:
      – name: TASK_NAME
       module: arguments
       notify: HANDLER_NAME
       handlers:
      – name: HANDLER_NAME
       module: arguments

(1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
(2) 任务可以通过“tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用;

三、例子

为websrvs组创建一个nginx组和用户,复制文件到dbsrvs组。

- hosts: websrvs
  remote_user: root
  tasks:
   - name: create nginx group
     group: name=nginx system=yes gid=2334
   - name: create nginx user
     user: name=nginx uid=2334 group=nginx system=yes

- hosts: dbsrvs
  remote_user: root
  tasks:
   - name: copy file to dbsrvs
     copy: src=/etc/inittab dest=/tmp/inittab.ansible

四、基础组件

1、Host和Users

playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户执行任务,hosts用于指定要执行任务的主机,其可以是一个或多个由冒号分隔主机组。remote_user则用于指定远程主机上的执行任务的用户。
不过,remote_user也可以用于各task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务,此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。

  • hosts:用于指定要执行指定任务的主机其可以是一个或多个,由逗号为分隔符分隔主机组
  • remote_user:用于指定远程主机上的执行任务的用户。不过remote_user也可用于各tasks中。也可以通过指定其通过sudo的方式在远程主机上执行任务其可用于play全局或某任务。此外甚至可以在sudo时使用sudo_user指定sudo时切换的用户
  • user:与remote_user相同
  • sudo:如果设置为yes,执行该任务组的用户在执行任务的时候,获取root权限
  • sudo_user:如果设置user为bob,sudo为yes,sudo_user为tom时,则bob用户在执行任务时会获得tom用户的权限
  • connection:通过什么方式连接到远程主机,默认为ssh
  • gather_facts:除非明确说明不需要在远程主机上执行setup模块,否则默认自动执行。如果确实不需要setup模块传递过来的变量,则可以将该选项设置为False
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: test connection
      ping: 
      remote_user: yourname
      sudo: yes

2、tasks 列表和 action
每一个play包含了一个tasks列表(任务列表)。

任务列表中的各任务按次序逐个在hosts中指定的所有主机上执行即在所有主机上完成第一个任务后再开始第二个。在自上而下运行某playbook时如果中途发生错误,所有已执行任务都将回滚,因此在更正playbook后重新执行即可。
每一个tasks必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个tasks的。如果没有定义name,“action”的值将会用作输出信息中标记特定的tasks。

tasks的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。每个task都应该有其name用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name则action的结果将用于输出。
如果要声明一个tasks,以前有一种格式:“action: module options”(可能在一些老的playbooks中还能见到)。现在推荐使用更常见的格式:“module: options”。
下面是一种基本的task的定义,service moudle使用key=value格式的参数,这也是大多数module使用的参数格式:

tasks:
 - name: make sure apache is running
   service: name=httpd state=running

# 在众多模块中,只有command和shell模块仅需要给定一个列表而无需使用“key=value”格式如下:
tasks:
 - name: disable selinux
   command: /sbin/setenforce 0

# 使用command module和shell module时,我们需要关心返回码信息,如果有一条命令,它的成功执行的返回码不是0,我们可以这样做:
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

# 如果action行看起来太长,可以使用space(空格)或者indent(缩进)隔开连续的一行:
tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
            owner=root group=root mode=0644

3、Handlers 在发生改变时执行的操作
用于当关注的资源发生变化时采取一定的操作。在执行playbook时如果返回的是OK则表示没有变化,如果返回的是changed则表示发生了改变。

module具有“幂等”性,所以当远程主机被人改动时,可以重放playbooks达到恢复的目的。playbooks本身可以识别这种改动,并且有一个基本的event system(事件系统),可以响应这种改动。
(当发生改动时)“notify”这个actions会在playbook的每一个tasks结束时被触发,而且即使有多个不同的tasks通知改动的发生,“notify” actions只会被触发一次。这样可以避免多次有改变发生时每次都执行指定的操作,取而代之仅在所有的变化发生完成后一次性地执行指定操作。
在“notify”中列出的操作称为handlers,即“notify”中调用handlers中定义的操作。

例子:复制配置文件到指定主机上,如果配置文件和原本主机上的不同,则覆盖然后触发操作。

[root@ansible-node1 ~]# vim apache.yml 
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd package
    yum: name=httpd state=present
  - name: install configuration file for httpd
    copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart httpd
  - name: start httpd service
    service: enabled=true name=httpd state=started
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted

4、variables变量名
(1)使用:vars: 添加变量
vars:

  • var1: value1
  • var2: value2
    {{ }}调用
    Ansible playbook_第1张图片
    Ansible playbook_第2张图片

(2)直接引用Ansible变量,这些变量在前面使用setup模块可以查看,例如:ansible_all_ipv4_addresses 获取IP
Ansible playbook_第3张图片

(3)引用主机变量,在组的主机后面添加变量
vim /etc/ansible/hosts
在这里插入图片描述
vim c.yml
Ansible playbook_第4张图片
5、条件判断
when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行

如果需要根据变量、facts(setup)或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when子句。

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

(1)单条件判断
Ansible playbook_第5张图片
(2)多条件判断
Ansible playbook_第6张图片
(3)组条件判断
Ansible playbook_第7张图片
(4)自定义条件判断
Ansible playbook_第8张图片
6、迭代

有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素列表即可。
Ansible playbook_第9张图片
Ansible playbook_第10张图片
7、Tags
(1)在一个playbook中,我们一般会定义很多个task,如果我们只想执行其中的某一个task或多个task时就可以使用tags标签功能。
任务可以通过“tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用
Ansible playbook_第11张图片

    # ansible-playbook hosts.yml --tags="only"   //只执行这个标签上面的任务

(2)事实上,不光可以为单个或多个task指定同一个tags。playbook还提供了一个特殊的tags为always。作用就是当使用always当tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
Ansible playbook_第12张图片

 ansible-playbook hosts.yml --tags="only"    //去被管理主机上查看文件创建情况 2个tags都会执行

五、template模块

1、简介
在实际应用中,我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同,template可以使用变量来接收远程主机上setup收集到的facts信息,针对不同配置的主机,定制配置文件。用法大致与copy模块相同

template_host包含模板机器的节点名称
template_uid所有者的数字用户标识
template_path是模板的路径
template_fullpath是模板的绝对路径
template_run_date是模板呈现的日期

2、参数

attributes(2.3后新增):文件或目录的属性
backup:如果原目标文件存在,则先备份目标文件
block_end_string(2.4后新增):标记块结束的字符串
block_start_string(2.4后新增):标记块的开始的字符串
dest:目标文件路径
follow(2.4后新增):是否遵循目标中的文件链接
force:是否强制覆盖,默认为yes
group:目标文件或目录的所属组
owner:目标文件或目录的所属主
mode:目标文件的权限。对于那些习惯于/usr/bin/chmod的记住,模式实际上是八进制数字(如0644or 01777)。离开前导零可能会有意想不到的结果。从版本1.8开始,可以将模式指定为符号模式(例如u+rwx或u=rw,g=r,o=r)
newline_sequence(2.4后新增):指定用于模板文件的换行符序列(\n、\r、\r\n)
src:源模板文件路径
trim_blocks(2.4后新增):如果这设置为True,则删除块后的第一个换行符
validate:在复制之前通过命令验证目标文件,如果验证通过则复制
variable_end_string(2.4后新增):标记打印语句结束的字符串
variable_start_string(2.4后新增):标记打印语句开头的字符串

3、示例

# 官方简单示例
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"
- template: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'

playbook的引用该模板配置文件的方法示例:
- name: Setup BIND
  host: all
  tasks:
    - name: configure BIND
      template: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=0644
# 或者是这样
- template:
    src: /etc/httpd/conf/httpd.conf
    dest: /etc/file.conf
    owner: root
group: root
mode: 0644

# 创建DOS样式文本文件
- template:
    src: config.ini.j2
    dest: /share/windows/config.ini
    newline_sequence: '\r\n'

转载:https://www.cnblogs.com/keerya/p/8004566.html
https://blog.51cto.com/13630803/2154192
https://blog.51cto.com/13525470/2112720

你可能感兴趣的:(ansible)