ansible之playbook

一、playbook介绍

playbook是ansible的配置、部署、编排语言。他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组ansible模块程序运行的命令集合

二、YAML语法详解

YAML(Yet Another Markup Language)语言是一种用来表达数据序列的编程语言,他的主要特点包括:可读性强,语法简单明了,支持丰富的语言解析库,通用性强。

ansible中的配置文件都以YAML格式存在,所以必须要熟悉YAML格式来配置管理ansible。

yaml与json的转化

列表

使用"- "(减号加一个或多个空格)作为列表项,也就是json中的数组。yaml的列表在playbook中极重要,必须得搞清楚它的写法。

例如:

 - zhangsan
 - lisi
 - wangwu

它们等价于json格式的:

[
    "zhangsan",
    "lisi",
    "wangwu"
]

字典

使用"冒号+空格"分隔,即key: value,作为字典的形式。它一般当作列表项的属性。

例如

alice:
	hp: 34
	sp: 8
	level: 4

它们等价于json格式的:

{
	'alice':
	{
		'hp':34,
		'sp':8,
		'level':4
	}
}

列表和字典两种混合

例如

bob:
	hp:
		- 12
		- 30
	sp:
		- 10
		- 20
	level: 4

它们等价于json格式的:

{
	'bob':
	{
		'hp':[12,30],
		'sp':[10,20],
		'level':4
	}
}

三、playbook的YMAL格式

---
- hosts: test
  remote_user: root

  tasks: 
  - name: install nginx
    yum: name=nginx state=present
    tags: install 

  - name: start nginx service
    service: name=nginx state=start

格式

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

基础组成

hosts:运行指定任务的目标主机

remote_user:在远程主机以哪个用户执行

tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

四、playbook核心组件

1、Tasks

Play的主体是任务列表。任务列表中的任务按照次序逐个在hosts中指定的所有主机上执行

示例

- hosts: abc
  remote_user: root
  tasks:
   - name: disable selinux
     command: '/sbin/setenforce 0'    ##关闭selinux
   - name: make sure apache is running
     service: name=httpd state=started    ##开启httpd服务

##play中只要执行命令的返回值不为0,就会报错,tasks停止
加上下面这句话 可以强制执行
ignore_errors: True             ##忽略错误,强制返回成功

2、Variables

当我们需要定制一些模板时,我们需要从外部传入变量来配置playbook

示例

方法1(命令行传入参数)

[root@ansible_center tmp]# cat ~/install_nginx.yaml 
- hosts: webservers
  remote_user: root

  tasks: 
  - name: install {{ pkgname }}
    yum: name={{ pkgname }} state=present
    tags: install 

  - name: start {{ pkgname }} service
    service: name={{ pkgname }} state=start
    
#命令行传入参数    
[root@ansible_center tmp]# ansible-playbook -e pkgame=nginx ~/install_nginx.yaml 

方法2(playbook内部定义)

[root@ansible_center tmp]# cat ~/install_nginx.yaml 
- hosts: webservers
  remote_user: root
  vars: 
   - pkgname: nginx

  tasks: 
  - name: install {{ pkgname }}
    yum: name={{ pkgname }} state=present
    tags: install 

  - name: start {{ pkgname }} service
    service: name={{ pkgname }} state=start

3、Templates

Jinja2是基于 Python的模板引擎。 Templates使用Jinjia2格式作为文件模版,进行文档内变量的替换,可以看作是一个编译过的模板文件,用来产生目标文本,传递 Python的变量给模板去替换模板中的标记。

示例

从被管理端复制一份httpd.conf到管理端
并做如下修改

vim templates/httpd.conf      

Listen {{ http_port }}
ServerName {{ server_name }}
MaxClients {{ access_num }}

vi /etc/ansible/hosts
[aaa]
192.168.x.x http_port=192.168.x.x:80 access_num=100 server_name="www.aaa.com:80"
## 在hosts文件为主机配置变量

vi httpd.yml

- hosts: aaa
  remote_user: root
  vars:
    - package: httpd
    - service: httpd
  tasks:
    - name: install httpd package
      yum: name={{ package }} state=latest   ##安装最新版本的httpd
    - name: install configure file
      template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf  ##使用模板并根据变量进行配置
      notify:
        - restart httpd   ##调用handler
    - name: start httpd server
      service: name={{ service }} enabled=true state=started     ##开启服务
  handlers:
    - name: restart httpd
      service: name={{ service }} state=restarted

4、Handlers

Handlers用于当关注的资源发生变化时所采取的操作。在 notify中列出的操作便称为 handler,也就是在notify中需要调用 handler中定义的操作。而 notify这个动作在每个play的最后被触发,仅在所有的变化发生完成后一次性地执行指定操作。

示例

- hosts: abc
  remote_user: root
  tasks:
   - name: install httpd package
     yum: name=httpd state=latest    ##按照最新版本的httpd服务
   - name: install configuration file for httpd
     copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf   ##配置文件
     notify:
      -restart httpd    ##调用名字为 restart httpd 的handler
   - name: start httpd service
     service: enabled=true name=httpd state=started   ## 开启httpd服务
  handlers:
   - name: restart httpd
     service: name=httpd state=restarted

5、Tags

如果多次执行修改 Playbook 会涉及到一些没有变化的代码,可以使用tags让 用户选择跳过没有变化的代码。只运行Playbook中发生变化的部分代码。可以在Playbook中为某个或某些任务定义“标签”,在执行此Playbook时通过 ansible-playbook命令 使用 --tags 选项能实现仅运行指定的tasks。

示例

vi hosts.yml

- hosts: aaa
  remote_user: root
  tasks:
    - name: Copy hosts file
      copy: src=/etc/hosts dest=/etc/hosts
      tags:
      - only
    - name: touch file
      file: path=/opt/hosts state=touch

执行命令:ansible-playbook hosts.yml -t only
会只执行标签为 only的任务

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

如果在上面的yaml文件中添加
- name: touch file
      file: path=/opt/hosts state=touch
      tags:
      - always

执行命令:ansible-playbook hosts.yml -tags only
会将两个task都执行

6、Roles

Ansible为了层次化、结构化地组织 Playbook,使用了角色( roles),可以根据层次结构自动装载变量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include指令即可使用 roles。简单来讲, roles就是通过分别将变量、文件、任务、模块及处理器设置於单独的目录中,便捷地使用他们。

roles内各目录含义解释

rolename/: 角色名命名的目录

​ —files/:用来存放由copy模块或script模块调用的文件。

​ —templates/:用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。

​ —tasks/:此目录应当包含一个main.yml文件,用于定义此角色的任务列表。

​ —handlers:此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。

​ —vars:此目录应当包含一个main.yml文件,用于定义此角色用到的变量。

​ —defaults:此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。

​ —meta:此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。

在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,但不可以不创建

五、roles实战部署nginx

1、创建角色目录及相关子目录

[root@ansible_center roles]# cd /etc/ansible/roles/
[root@ansible_center roles]# mkdir -pv nginx/{files,templates,vars,handlers,meta,default,tasks}
mkdir: created directory ‘nginx’
mkdir: created directory ‘nginx/files’
mkdir: created directory ‘nginx/templates’
mkdir: created directory ‘nginx/vars’
mkdir: created directory ‘nginx/handlers’
mkdir: created directory ‘nginx/meta’
mkdir: created directory ‘nginx/default’
mkdir: created directory ‘nginx/tasks’

2、在task定义任务

[root@ansible_center roles]# cat nginx/tasks/main.yaml
- name: mkdir /data/www
  file: path=/data/www state=directory
- name: create user nginx
  user: name=nginx
- name: copy nginx html to remote host
  copy: src=index.html dest=usr/local/nginx/html/
- name: copy nginx package to remote host
  copy: src=nginx-1.12.2.tar.gz dest=/opt/nginx-1.12.2.tar.gz
  tags: cppkg
- name: tar nginx
  shell: cd /opt; tar -xf nginx-1.12.2.tar.gz
- name: install pkg
  yum: name={{ item }} state=latest
  with_items:
  - openssl-devel
  - pcre-devel
  - gcc
- name: install nginx
  shell: cd /opt/nginx-1.12.2;./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre;make&&make install
- name: copy conf file nginx.conf
  template: src=nginx.conf dest=/usr/local/nginx/nginx.conf
  tags: naxconf
  notify: reload nginx service

3、相关文件准备

#nginx源码安装文件
[root@ansible_center roles]# cd nginx/files/
[root@ansible_center files]# wget http://nginx.org/download/nginx-1.12.2.tar.gz

#nginx首页html文件
[root@ansible_center files]# cat index.html 
<h1>test page</h1>

#nginx配置模板文件
[root@ansible_center files]# cd ../templates/
[root@ansible_center templates]# cat nginx.conf 
#user  nobody;
worker_processes  1;

events {
    worker_connections  {{ con_counts }};
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   {{ html_dir }};
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }


}

4、在vars中定义变量

[root@ansible_center templates]# cd /etc/ansible/roles/nginx/vars/
[root@ansible_center vars]# vim main.yaml
[root@ansible_center vars]# cat main.yaml 
con_counts: "65535"
html_dir: "/data/www"

5、在handlers中定义触发器

[root@ansible_center vars]# cd /etc/ansible/roles/nginx/handlers/
[root@ansible_center handlers]# vim main.yaml
[root@ansible_center handlers]# cat main.yaml 
name: reload nginx service
shell: /usr/local/nginx/sbin/nginx

6、创建nginx.yaml引导文件

[root@ansible_center handlers]# cd /etc/ansible/roles/
[root@ansible_center roles]# vim nginx.yaml
[root@ansible_center roles]# cat nginx.yaml 
- host: 192.168.189.134
  remote_user: root
  roles:
  - nginx

运行结果

ansible-playbook /etc/ansible/roles/nginx.yaml 

在这里插入图片描述在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章