介绍

playbook  是用 yaml的文件形式写的

    yaml 是一个可读性高,用来表达数据序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。当前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。 

  YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。

yaml  的写法参考

https://yaml.org

 

spouse

 

playbook的 变量

playbook的 组成结构:

            Inventory

            Modules

           Ad  hum commands

           Playbooks:

                   Tasks:     任务  即将调用的模块操作

                   Variables: 变量

                   Templates: 模板

                   Handlers: 处理器, 由有时间触发的执行操作

                   Roles:     角色

 

基本结构



- host: webservs
  remote_user:
  tasks:
  - take1
    module_name: module_args
  - task2



 

 

写个简单的playbook



[root@localhost yaml]# cat createuser.yaml 
- hosts: web
  remote_user: root
  tasks:
  - name: create  hahaha group                                          # 任务名称  没有实际执行意义
    group: name=hahaha system=yes gid=655                               # 执行内容  调用了 group模块
  - name: create hahaha user                                            # 任务名称  
    user: name=hahaha  uid=655 system=yes group=hahaha                  # 创建用户,使用了user 模块



 

 

 

然后使用指令进行操作



ansible-playbook createuser.yaml



 

 进行查看。完成

 

ansible_host变量 ansible playbook hosts变量_配置文件

 

 



192.168.144.171            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.144.172            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
                             ok 这里的ok只是表示有执行数据类型,并不能代表结果
                                     changed 这里的changed表示相关数据发生变化



 

 

当我们再执行一遍的时候  changed就不会发生变化了,因为已经执行过一次了。  所以相关的数据内容都不会发生改变。

 

ansible_host变量 ansible playbook hosts变量_配置文件_02

 

 

 

 

安装httpd 的 palybook

 以下文件 



[root@localhost yaml]# cat httpd.yaml 
- hosts: web
  remote_user: root
  tasks:
  - name : install  httpd service                                                     # 第一个任务 安装httpds
    yum : name=httpd  state=latest                                                    # 使用yum模块,使用最新版本 
  - name : Edit configuration for httpd # 修改配置文件 copy : src=/home/project/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf # 使用了copy模块。可以将本地复制到远程.本地配置文件已经已经过修改 。 - name : start httpd service # 启动服务
 service : name=httpd state=started # 使用了service模块 如果需要开机启动 可以加 enabled=true



 

 查看本地的配置文件,将监听的端口 ,改为8008.

 

ansible_host变量 ansible playbook hosts变量_运维_03

 

 

然后执行



ansible-playbook  httpd.yaml



 

 

查看执行结果,执行完成。

ansible_host变量 ansible playbook hosts变量_ansible_host变量_04

 

 验证,程序安装完成。程序也启动起来了。 端口是经过修改的 8008。

 

ansible_host变量 ansible playbook hosts变量_ansible_host变量_05

 

 完成。

 

 

handlers

相当于当资源发生变化是,采取一定的操作。
比如:修改配置文件,程序进行重启

需要写一个 notify 来触发这个 handler

 

看以下



[root@localhost conf]# cat /etc/ansible/yaml/httpd.yaml 
- hosts: web
  remote_user: root
  tasks:
  - name : install  httpd service
    yum : name=httpd  state=latest
  - name : Edit configuration for  httpd                    
    copy : src=/home/project/conf/httpd.conf  dest=/etc/httpd/conf/httpd.conf
    notify:                                                                      # 这边定义一个notify,只要配置文件有修改,就触发那个handlers。
    - restart htttpd                                                             # 这边是定义handler的名字的 
  - name : start httpd service
    service : name=httpd  state=started
  handlers:                                                                      # 使用handlers  和tasks  是同级的
    - name: restart htttpd                                                       # 这边使用名字   必须和上面 notify 里面的定义的名字 一样 
      service: name=httpd  state=restarted                                         # 这边其实就是在写个service  重启下。



 

这边修改下 httpd  conf的配置。  修改下监听端口为8088

 

 

ansible_host变量 ansible playbook hosts变量_运维_06

 

再次执行yaml文件。



ansible-playbook httpd.yaml



 

 查看以下,  修改配置的task 和 handler 都执行了

ansible_host变量 ansible playbook hosts变量_shell_07

 

 再次查看。发现监听的端口,已经改了。 所以只要配置文件发生变化。就会触发handler。配置文件没变化。bandler就不会执行。

ansible_host变量 ansible playbook hosts变量_shell_08

 

 

 vars

ansible支持变量

 



- hosts: web
  remote_user: root
  vars:                                   ##  定义变量
  - packages: httpd                       ##  变量名是 packages
  - soft: httpd                           ##  变量名是 soft
  tasks:
  - name : install  httpd service
    yum : name= {{ packages }}  state=latest      ##  使用变量
  - name : Edit configuration for  httpd
    copy : src=/home/project/conf/httpd.conf  dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart htttpd
  - name : start httpd service
    service : name= {{ soft }}  state=started       ## 使用变量
  handlers:
  - name: restart htttpd
    service: name= {{ soft }} state=restarted       ## 使用变量



 

然后我们还可以使用ansible本生的变量

使用setup 模块。 可以看到有许多ansible的 变量



ansible   192.168.249.152  -m  setup



 

 我们可以看到本机的ip在ansible里面可以用以下变量名。



ansible_all_ipv4_addresses



 

ansible_host变量 ansible playbook hosts变量_配置文件_09

 

 

看以下



[root@master yaml]# cat var1.yaml 
- hosts: webser
  remote_user: root
  tasks:
  - name: write file
    shell: 'echo {{ ansible_all_ipv4_addresses  }} >> /tmp/anip.txt'              # 使用 shell模块。使用ansible本身的变量,  就是将本机ip写到一个文件里面



 

执行完成

ansible_host变量 ansible playbook hosts变量_数据库_10

 

进行查看。已经写进去了。 前面的u 是 unicode的意思。

ansible_host变量 ansible playbook hosts变量_shell_11

 

 我们也可以将变量写在  inventory  的 hosts文件中,也可以使用ansible直接调

看以下。我们在hosts文件中写变量 。



[root@master ansible]# cat  /etc/ansible/hosts
[webser]
192.168.249.152     vartest="249.152"                     #   变量名一样, 值不一样
192.168.249.153     vattest="249.153"                     #   变量名一样, 值不一样

[daser]
192.168.249.154



 

 修改 yaml文件



[root@master yaml]# cat var1.yaml 
- hosts: webser
  remote_user: root
  tasks:
  - name: write file
    shell: 'echo  -e  "{{ ansible_all_ipv4_addresses }} \n  {{vartest}}"  > /tmp/anip.txt'                  #  直接调用在hosts里面写的变量vartest



 

执行完成

ansible_host变量 ansible playbook hosts变量_配置文件_12

 

查看结果, 可以看到新的变量生效了。同样的变量名。值不一样。因为执行的机器不一样 。

 

ansible_host变量 ansible playbook hosts变量_shell_13

 

 

 条件测试

使用when,就是当触发了某些条件之后,才执行某些模块。
注意 这个和 hanler不一样 。  handler是当模块发生变化之后,才会触发。   when是有触发条件的。

看以下

我们写一个palybook。 条件触发时,在某一台机器才创建某个用户。

 

事先在hosts文件中定义变量



[root@master ansible]# cat hosts
[webser]
192.168.249.152     vartest="249.152"   var="hahaha"
192.168.249.153     vartest="249.153"   var="yayaya"

[daser]
192.168.249.154



 

写playbook,就是在192.168.249.153  的机器上面创建 tes153



[root@master ansible]# cat yaml/condition.yaml 
- hosts: webser
  remote_user: root
  vars:                                                  # 使用变量
  - username: tes153
  tasks:                                                 # 创建task
  - name: create {{ username }}   user                             
    user: name={{ username }}                         
    when: var == "yayaya"                                # 触发条件。  但是这边的条件貌似只能是字母。  ip的好像不能触发。



 

执行。 我们看到只有153 执行了。

ansible_host变量 ansible playbook hosts变量_数据库_14

 

 

 验证一下。我们看到 152 是空值。 153才有这个用户。  

ansible_host变量 ansible playbook hosts变量_shell_15

 

迭代循环

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

     就是类似于 循环执行



[root@master yaml]# cat items.yaml 
- hosts: webser
  remote_user: root
  tasks:
  - name: create user and  use   items
    user: name="{{ item }}"  state=present                       ## 等号后面不能有空格,
    with_items:                                                  ## 循环创建2个用户。
       - wheel1
       - wheel2



 

执行结果

ansible_host变量 ansible playbook hosts变量_ansible_host变量_16

 

验证,这样2个用户就都创建了。

ansible_host变量 ansible playbook hosts变量_ansible_host变量_17

 

 

Templates

当同一组机器中,需要使用不同的变量时。我们可以使用tomplates 模块。 然后在hosts和 有区别的配置中使用变量。

这边有1台webservice。  现在我们webserer需要启动不同的端口。

我们进行以下操作。

准备配置文件 ,我们将模板使用httpd的配置文件的监听端口进行修改成变量



cat /home/template/httpd.conf.ansible # 这个是本机的httpd 配置模板文件。 路径自定义。



 

ansible_host变量 ansible playbook hosts变量_数据库_18

 

 然后我们把这个变量写到ansible的hosts里面

 



[root@master yaml]# cat /etc/ansible/hosts
[webser]
192.168.249.152     httpd_port=8008    
192.168.249.153     httpd_port=8009

[daser]
192.168.249.154



 

 然后我们写playbook,使用template模块。其他的和之前的那个差不多 。

 



[root@master template]# cat  /etc/ansible/yaml/httpd.yaml 
- hosts: webser
  remote_user: root
  tasks:
  - name : install  httpd service
    yum : name=httpd  state=latest
  - name : Edit configuration for  httpd                    
    template: src=/home/template/httpd.conf.ansible   dest=/etc/httpd/conf/httpd.conf        # 注意这边使用了template模块。而不是之前的copy模块
    notify:                                                                     
    - restart htttpd                                                            
  - name : start httpd service
    service : name=httpd  state=started
  handlers:                                                                     
    - name: restart htttpd                                                      
      service: name=httpd  state=restarted



 

 执行完成

ansible_host变量 ansible playbook hosts变量_数据库_19

 

 查看验证,2台主机使用了不一样的监听端口。

 

ansible_host变量 ansible playbook hosts变量_数据库_20

 

tags

可以给你要运行的任务打上tag。这样 有的任务就不会重复执行了。

看下面的playbook。  我们只运行修改配置文件的tasks(这个tasks包含重启的 handler)。 其他的都不运行。

 



[root@localhost yaml]# cat httpd.yaml 
- hosts: web
  remote_user: root
  vars: 
  - packages: httpd
  - soft: httpd
  tasks:
  - name : install  httpd service
    yum : name={{ packages }}  state=latest
  - name : Edit configuration for  httpd
    copy : src=/home/project/conf/httpd.conf  dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart htttpd
    tags:                                                                                     ##  使用tags
    - conf                                                                                    ##  这个是tags的名字
  - name : start httpd service
    service : name={{ soft }}  state=started
  handlers:
  - name: restart htttpd
    service: name={{ soft }} state=restarted



 

修改/home/project/conf/httpd.conf  这个http的 模块配置文件。   修改他的监听端口

 

ansible_host变量 ansible playbook hosts变量_运维_21

 

运行playbook



ansible-playbook  httpd.yaml   --tags='conf' 
                                 ##  指令tag。 这个tag的名字是我们在playbook中定义好的



 

执行,我们看到只有修改配置文件的tasks 运行了。 其他的tasks没有运行。

ansible_host变量 ansible playbook hosts变量_运维_22

 

 

 验证一下,就完成了。

 

ansible_host变量 ansible playbook hosts变量_运维_23

 

 

 roles

Playbook 同样可以使用 include 引用其他 playbook 文件中的 play。这时被引用的 play 会被插入到当前的 playbook 中,当前的 playbook 中就有了一个更长的的 play 列表。

我们使用一些目录在规范playbooks里面的参数 

 

 

创建相关目录



 mkdir  -pv  /home/ansible_playbook/roles/{webser,dbser}/{defaults,tasks,files,templates,meta,handlers,vars}



 

 



[root@localhost ansible_playbook]# tree  /home/ansible_playbook/roles/
/home/ansible_playbook/roles/
├── dbser                      ##  角色  1 
│   ├── defaults               ##  放静态文件的。比如config文件
│   ├── files                  ##  ansible中unarchive、copy等模块会自动来这里找文件,从而我们不必写绝对路径,只需写文件名     
│   ├── handlers               ##  存放tasks中的notify指定的内容
│   ├── meta                   ##  定义各种依赖关系等信息。
│   ├── tasks                  ## 存放playbook的目录,其中main.yml是主入口文件,在main.yml中导入其他yml文件,要采用import_tasks关键字,include要弃用了  
│   ├── templates              ## 存放模板文件。template模块会将模板文件中的变量替换为实际值,然后覆盖到客户机指定路径上
│   └── vars                   ## 存放变量的    
└── webser                     ##  角色 2 
    ├── defaults          
    ├── files
    ├── handlers
    ├── meta
    ├── tasks
    ├── templates
    └── vars



 

我们写一个简单的roles

准备本地的配置文件



cp  -rp   /etc/httpd/conf/httpd.conf    ansible_playbook/roles/webser/files/                        #  将httpd的配置当做本地文件使用,ansible里面的copy会自动在file目录下找文件



 

写tasks,单独写playbook的 tasks就可以 。



[root@localhost ansible_playbook]# cat   /home/ansible_playbook/roles/webser/tasks/main.yml 
- name: install httpd package                                                   ## 安装http
  yum: name=httpd
- name: install configuration file                                              ## 修改文件
  copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
  tags:                                                                         ##  定义tag
  - conf
  notify:                                                                       ## 定义 notify
  - restart httpd
- name: start httpd                                                             ##  重启
  service: name=httpd state=started



 

因为写了notify,所以要写 handler



[root@localhost ansible_playbook]# cat   /home/ansible_playbook/roles/webser/handlers/main.yml 
- name: restart httpd
  service: name=httpd state=started



 

然后写主要的 playbook文件



[root@localhost ansible_playbook]# cat  /home/ansible_playbook/site.yml                       ##  注意 这里的路径,一定是在ansible_playbook 这个下面。
- hosts: web                                             ##  这里hosts 是 ansible的hosts定义的文件
  remote_user: root
  roles:
  - webser                                               ##  这里的 role名字 是我们role 目录结构中定义的角色目录的名字



 

至此,我们就可以运行了



[root@localhost ansible_playbook]# pwd
/home/ansible_playbook
[root@localhost ansible_playbook]# ansible-playbook site.yml



 

查看结果。  完成。

ansible_host变量 ansible playbook hosts变量_数据库_24

 

然后我们写一个多role的 playbook

之前我们有分webser和 dbser的role。 可以写到一起执行



sudo cp -rp /etc/my.cnf /home/ansible_playbook/roles/dbser/files/ ## 配置配置文件,到相关目录下



 

写task文件,就是web的类似。 安装mysql。 修改配置,重启服务



[root@localhost yum.repos.d]# cat   /home/ansible_playbook/roles/dbser/tasks/main.yml 
- name: install  mysql-server
  yum: name=mysql-community-server  state=present
- name: install configuration file
  copy: src=my.cnf dest=/etc/my.cnf
  tags:
  - myconf
  notify:                                                         ## 需要notify
  - restart mysqld
- name: start mysqld service
  service: name=mysqld   state=started



 

写handler文件



[root@localhost yum.repos.d]# cat   /home/ansible_playbook/roles/dbser/handlers/main.yml 
- name: restart mysqld
  service: name=mysqld  state=restarted



 

然后写site文件



[root@localhost yum.repos.d]# cat  /home/ansible_playbook/site.yml 
- hosts: web                                                               ##  第一个 host  web用户 
  remote_user: root
  roles:                                                                   ##  使用webser的role
  - webser
- hosts: 192.168.144.173                                                   ##  第二个 可以直接写ip   
  remote_user: root
  roles:                                                                   ##  可以使用 多个role。 这样这个ip 就拥有多个role的角色了。
  - dbser
  - webser



 

然后执行



ansible-playbook site.yml



 

查看结果,完成。

ansible_host变量 ansible playbook hosts变量_配置文件_25

 

 

在Centos7 中 ,默认是没有mysql,是madiaDB。 如果要装mysql的话。  需要手动下载repo文件。

 



cd  /etc/yum.repos.d
wget 'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'
rpm -Uvh mysql57-community-release-el7-11.noarch.rpm
yum install -y mysql-community-server
rpm -qa  | grep   mysql



 

然后我们的db的tasks可以这个写 。



[root@localhost tasks]# cat /home/ansible_playbook/roles/dbser/tasks/main.yml 
- name: download rpm package                                                                                             ##  手动下载rpm文件
  shell: wget -P /etc/yum.repos.d/  'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'
- name: install rpm                                                                                                      ##  安装这个rpm。 安装完后,就有了mysql的repo文件。 就能yum了。
  shell: rpm -ivh /etc/yum.repos.d/mysql57-community-release-el7-11.noarch.rpm  
- name: install  mysql-server
  yum: name=mysql-community-server  state=present
- name: install configuration file
  copy: src=my.cnf dest=/etc/my.cnf
  tags:
  - myconf
  notify:
  - restart mysqld
- name: start mysqld service
  service: name=mysqld   state=started