3.2.2 运维自动化之ansible-playbook和roles

playbook

    play 的主要功能在于将事先归并为一组的主机装扮成事先通过 ansible 中的 task 定义好的角色。从根本上来讲,所谓 task 无非是调用 ansible 的一个 module。将多个 play 组织在一个 playbook 中,即可以让它们联同起来按事先编排的机制同唱一台大戏。

先来看一个简单的 playbook:

---                   #以三个"-"开头
- hosts: group1       #作用的主机列表
  remote_user: root   #在远程以哪个用户的身份执行

  tasks:              #任务集   
  - name: test        #任务的名字
    shell: echo "hello world"   #执行的操作

1、列表以"- "开头,键值对":"后有空格

2、同一级别缩进必须一致,且不能空格与 tab 混用

3、元素:

    Hosts:执行的远程主机列表
    Tasks:任务集
    Varniables:内置变量或自定义变量在playbook中调用
    Templates:模板,可替换模板文件中的变量并实现一些简单逻辑的文件
    Handlersnotity:由特定条件触发的操作,满足条件方才执行,否则不执行

    tags:标签指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

    playbook 核心元素

hosts:playbook 中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts 用于指定要执行指定任务的主机,需要事先定义在主机清单中

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务。

[root@CentOS7 .ansible]# cat first.yml 
---
- hosts: group1
  remote_user: jiangbowen

  tasks: 
  - name: create file
    file: name=/data/TestFile state=touch
task列表和action
    play 的主体部分是 task list。task list 中的各任务按次序逐个在 hosts 中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自下而下某 playbook 时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正 playbook 后重新执行一次即可
    task 的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致,shell 模块除外
    每个 task 都应该有其 name,用于 playbook 的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供 name,则 action 的结果将用于输出
---
- hosts: group1
  remote_user: root

  tasks: 
  - name: disable SELinux
    shell: setenforce 0
    ignore_errors: True   #忽略错误,69主机上的selinux为disabled,如果执行setenforce 0的话会报错
  - name: install httpd
    yum: name=httpd state=installed
  - name: start httpd
    service: name=httpd state=started
[root@CentOS7 .ansible]# ansible-playbook install.yml


PLAY [group1] *******************************************************************************************************************************************************************************


TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.69]
ok: [192.168.30.75]


TASK [disable SELinux] **********************************************************************************************************************************************************************
fatal: [192.168.30.69]: FAILED! => {"changed": true, "cmd": "setenforce 0", "delta": "0:00:00.003807", "end": "2018-05-31 17:25:44.820715", "msg": "non-zero return code", "rc": 1, "start": "2018-05-31 17:25:44.816908", "stderr": "setenforce: SELinux is disabled", "stderr_lines": ["setenforce: SELinux is disabled"], "stdout": "", "stdout_lines": []}
...ignoring     #忽略错误,继续执行
changed: [192.168.30.75]


TASK [install httpd] ************************************************************************************************************************************************************************
changed: [192.168.30.75]
changed: [192.168.30.69]


TASK [start httpd] **************************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.75]


PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=4    changed=3    unreachable=0    failed=0   
192.168.30.75              : ok=4    changed=3    unreachable=0    failed=0   

Handlers:是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作

notify
    这个 action 可用于在每个 play 的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在 notify 中列出的操作称为 handler,也即 notify 中调用 handler 中定义的操作。

[root@CentOS7 .ansible]# cat handler.yml    #因为幂等性的原因,所以当服务启动的情况下,修改配置文件再次执行playbook,并不会
---                                         #重启服务去读取文件,所以需要一种方法监控条件的改变,当发生改变时触发一些动作。
- hosts: 192.168.30.75
  remote_user: root

  tasks:
  - name: install package
    yum: name=httpd state=installed
  - name: copy config         
    copy: src=/etc/httpd/conf/httpd.conf  dest=/etc/httpd/conf/ backup=yes
    notify: restart service     #当copy动作执行完毕,且返回changed状态,则触发restart service
  - name: start httpd service
    service: name=httpd state=started

  handlers:
  - name: restart service    #restart service的动作
    service: name=httpd state=restarted
[root@CentOS7 .ansible]# ansible-playbook handler.yml 

PLAY [192.168.30.75] ************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]

TASK [install package] **********************************************************************************************************************************************************************
ok: [192.168.30.75]

TASK [copy config] **************************************************************************************************************************************************************************
changed: [192.168.30.75]

TASK [start httpd service] ******************************************************************************************************************************************************************
ok: [192.168.30.75]

RUNNING HANDLER [restart service] ***********************************************************************************************************************************************************
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.75              : ok=5    changed=2    unreachable=0    failed=0   

tags:为 task 打上标签,通过 -t 指定标签,能够只执行个别 task。

[root@CentOS7 .ansible]# cat handler.yml
---
- hosts: 192.168.30.75
  remote_user: root

  tasks:
  - name: install package
    yum: name=httpd state=installed
    tags: install
  - name: copy config
    copy: src=/etc/httpd/conf/httpd.conf  dest=/etc/httpd/conf/ backup=yes
    notify: restart service
    tags: copy_conf
  - name: start httpd service
    service: name=httpd state=started
    tags: start

  handlers:
  - name: restart service
    service: name=httpd state=restarted
[root@CentOS7 .ansible]# ansible-playbook -t copy_conf  handler.yml 


PLAY [192.168.30.75] ************************************************************************************************************************************************************************


TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]


TASK [copy config] **************************************************************************************************************************************************************************
ok: [192.168.30.75]


PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.75              : ok=2    changed=0    unreachable=0    failed=0   

变量与 templates

变量也遵循 YAML 语法,使用键值对表示。

    语法:变量名=值

变量名:仅能由字母、数字和下划线组成,且只能以字母开头

变量来源:优先级由小到大

    ansible 用户 -m setup 中的变量(无需声明,可以直接调用)

    /etc/ansible/hosts 中的变量

        私有变量:对单个主机单独定义

        公共变量:对主机组中的所有主机定义

    在 playbook 或 role 中定义

    通过 ansible -e 临时定义的变量

查看 ansible setup 中的变量,支持通配符 * 。

[root@CentOS7 .ansible]# ansible group1 -m setup -a 'filter=ansible_hostname'   #默认显示所有变量,使用filter进行过滤
192.168.30.69 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "CentOS6"
    }, 
    "changed": false
}
192.168.30.75 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "CentOS75"
    }, 
    "changed": false
}

调式变量时通过"{{ 变量名 }}"使用变量:变量名前后有空格

[root@CentOS7 .ansible]# cat Var.yml 
---
- hosts: group2
  remote_user: root

  tasks:
  - name: touch VarFile
    file: name=/data/{{ testVar }} state=touch

查看变量的优先级,在 /etc/ansible/hosts、playbook、命令行中定义 testVar 变量,赋予不同的值

[root@CentOS7 .ansible]# ansible-playbook '-e testVar=commandVar' Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/commandVar                #当命令行中定义同名变量时,优先使用命令行中的变量

192.168.30.75 | SUCCESS | rc=0 >>
/data/commandVar

[root@CentOS7 .ansible]# ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/playbookVar              #不在命令行中定义变量后,使用了playbook中的变量

192.168.30.75 | SUCCESS | rc=0 >>
/data/playbookVar

[root@CentOS7 .ansible]# ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible] ansible group2 -m shell -a 'ls /data/*Var*'
192.168.30.174 | SUCCESS | rc=0 >>
/data/hostVar74                #再次删除playbook中的变量,/etc/ansible/hosts中的主机变量生效
                               #且能够作用与不同组中的相同主机
192.168.30.75 | SUCCESS | rc=0 >>
/data/hostVar75
[root@CentOS7 .ansible]#⮀⮀ansible-playbook Var.yml

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [touch VarFile] ************************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.75              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS7 .ansible]# ansible group2 -m shell -a 'ls /data/*Var'
192.168.30.174 | SUCCESS | rc=0 >>
/data/GroupVar                 #删除主机变量后,组变量生效

192.168.30.75 | SUCCESS | rc=0 >>
/data/GroupVar

为了方便管理,建议将所有变量存放在文件中,形成模块化

[root@CentOS7 .ansible]# cat vars1.yml vars2.yml    #在不同的文件中定义变量
package: httpd
package: bind
[root@CentOS7 .ansible]# cat install.yml            #在使用时,读取不同的文件就可以调用变量
---
- hosts: group2
  remote_user: root
  vars_files:      #声明读取文件中的变量
  - vars1.yml      #指定读取的文件

  tasks: 
  - name: install httpd
    yum: name={{ package }} state=installed
  - name: start httpd
  service: name={{ package }} state=started
[root@CentOS7 .ansible]# ansible-playbook install.yml 

PLAY [group2] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.75]
ok: [192.168.30.174]

TASK [install software] *********************************************************************************************************************************************************************
changed: [192.168.30.174]
changed: [192.168.30.75]

TASK [start service] ************************************************************************************************************************************************************************
changed: [192.168.30.75]
changed: [192.168.30.174]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.174             : ok=2    changed=2    unreachable=0    failed=0   
192.168.30.75              : ok=3    changed=2    unreachable=0    failed=0   

templates 模块用于以特定模板复制文件。

    选项

src:指定源文件路径
dest:指定目标文件路径和文件名
mode:对端文件的权限
owner:对端文件的所有者
group:所属组
backup:复制到对端时对原文件进行备份

模板文件使用 jinja2 语言,其中可以使用:

    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
    算术运算:+, -, *, /, //, %, **
    比较操作:==, !=, >, >=, <, <=
    逻辑运算:and, or, not
    流表达式:For If When    

模板文件必须以”.j2“为后缀,建议将模板文件放在 ~/.ansible 目录中,但是路径没有限制,也可以放在其他路径中,使用时指定路径即可。

.
├── naginxVar.yml
├── nginx.yml
└── templates
    └── nginx.conf.j2

1 directory, 3 files

template 模块不能用于 adhoc,只能用于 playbook 和 roles 中

[root@CentOS7 .ansible]# cat nginx.yml 
---
- hosts: group2
  remote_user: root

  tasks:
  - name: install nginx
    yum: name=nginx state=installed
  - name: setup config
    template: src=/root/.ansible/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf   #使用template模块
  - name: start nginx
    service: name=nginx state=started

查看 nginx.conf.j2 文件

[root@CentOS7 templates]# cat nginx.conf.j2 
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes {{ ansible_processor_vcpus*2 }};   #修改进程数为:调用ansible setup中变量,并且乘2
error_log /var/log/nginx/error.log; 
pid /run/nginx.pid;
...

    由此可见在 template 中,可以使用各种方式来表达想要修改的文本。

执行 nginx.yml 后查看进程个数

[root@CentOS174 yum.repos.d]# ps aux | grep nginx
root       4975  0.0  0.1 122908  2256 ?        Ss   09:59   0:00 nginx: master process /usr/sbin/nginx
nginx      4976  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process   #worker process确实为内核个数的两倍
nginx      4977  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
nginx      4978  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
nginx      4979  0.0  0.1 125380  3564 ?        S    09:59   0:00 nginx: worker process
root       4997  0.0  0.0 112660   964 pts/0    S+   10:00   0:00 grep --color=auto nginx

判断、迭代

when

在 task 后添加 when 语句即可使用条件测试;when语句支持 Jinja2 表达式语法。

    如果需要根据变量、facts 或此前任务的执行结果来做为某 task 执行与否的前提时要用到条件测试,通过 when 语句实现,在 task 中使用,jinja2的语法格式

    创建一个playbook,实现 centos6/7 不同版本使用不同的 template

[root@CentOS174 .ansible]# cat testwhen.yml 
---
- hosts: group1
  remote_user: root
  vars:
  - port1: 88    #声明变量
  - port2: 99

  tasks:
  - name: copy tempale for centos6
    template: src=apache2.2.conf.j2 dest=/etc/httpd/conf/httpd.conf
    when: ansible_distribution_major_version == "6"     #判断系统版本
  - name: copy tempale for centos7
    template: src=apache2.4.conf.j2 dest=/etc/httpd/conf/httpd.conf
    when: ansible_distribution_major_version == "7"
  - name: start service
    service: name=httpd state=restarted

    在 template 中,对 httpd 服务的监听端口进行修改,分别应用 port1 和 port2,执行playbook

[root@CentOS174 .ansible]# ansible-playbook testwhen.yml 

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.69]
ok: [192.168.30.74]

TASK [copy tempale for centos6] *************************************************************************************************************************************************************
skipping: [192.168.30.74]    #这项task跳过了centos7主机
ok: [192.168.30.69]

TASK [copy tempale for centos7] *************************************************************************************************************************************************************
skipping: [192.168.30.69]   #同上
ok: [192.168.30.74]

TASK [start service] ************************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=3    changed=1    unreachable=0    failed=0   
192.168.30.74              : ok=3    changed=1    unreachable=0    failed=0   

    查看两台主机上 httpd 服务监听的端口

[root@CentOS69 ~]# ss -ntlp | grep httpd   #监听在88端口上,与port1对应
LISTEN     0      128                      :::88                      :::*      users:(("httpd",4038,6),("httpd",4050,6),("httpd",4051,6),("httpd",4052,6),("httpd",4053,6),("httpd",4054,6),("httpd",4055,6),("httpd",4056,6),("httpd",4057,6))
[root@CentOS74 ~]# ss -ntlp | grep httpd   #监听在99端口上,与port2对应
LISTEN     0      128         :::99                      :::*                   users:(("httpd",pid=11761,fd=4),("httpd",pid=11760,fd=4),("httpd",pid=11759,fd=4),("httpd",pid=11758,fd=4),(httpd",pid=11757,fd=4),("httpd",pid=11756,fd=4))

with_item

    当有需要重复性执行的任务时,可以使用迭代机制,对迭代项的引用,固定变量名为"item"。

    创建多个用户,并且自定义指定UID

[root@CentOS174 .ansible]# cat addUser.yml
---
- hosts: group1
  remote_user: root

  tasks:
  - name: add some user
    user: name={{ item.name }} uid={{ item.uid }} state=present
    with_items:                          #迭代项
      - { name: 'user1', uid: 1111 }     #使用字典的格式,也可以是变量
      - { name: 'user2', uid: 2222 }
      - { name: 'user3', uid: 3333 }

    执行 playbook 后查看结果

[root@CentOS174 .ansible]# ansible-playbook addUser.yml 

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [add some user] ************************************************************************************************************************************************************************
changed: [192.168.30.74] => (item={u'name': u'user1', u'uid': 1111})
changed: [192.168.30.69] => (item={u'name': u'user1', u'uid': 1111})
changed: [192.168.30.74] => (item={u'name': u'user2', u'uid': 2222})
changed: [192.168.30.69] => (item={u'name': u'user2', u'uid': 2222})
changed: [192.168.30.74] => (item={u'name': u'user3', u'uid': 3333})
changed: [192.168.30.69] => (item={u'name': u'user3', u'uid': 3333})

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=2    changed=1    unreachable=0    failed=0   
192.168.30.74              : ok=2    changed=1    unreachable=0    failed=0   

[root@CentOS69 ~]# id user1
uid=1111(user1) gid=1111(user1) groups=1111(user1)   #创建了对应的三个用户
[root@CentOS69 ~]# id user2
uid=2222(user2) gid=2222(user2) groups=2222(user2)
[root@CentOS69 ~]# id user3
uid=3333(user3) gid=3333(user3) groups=3333(user3)

for 与 if

    使用 for 循环语句和 if 判断语句,可以更灵活的使用 template

    查看 playbook

[root@CentOS174 .ansible]# cat test.yml 
---
- hosts: group1
  remote_user: root
  vars:
    apache_vhosts:
    - web1:
      listen: 8080
      root: "/var/www/apache/web1/"
    - web2:
      listen: 80
      server_name: "web2.magedu.com"
      root: "/var/www/apache/web2/"
    - web3:
      listen: 88
      server_name: "web3.magedu.com"
      root: "/var/www/apache/web3/"

  tasks:
  - name: template configto
    template: src=apache.conf.j2 dest=/data/apache.conf

    查看 template

[root@CentOS174 .ansible]# cat templates/apache.conf.j2 
{% for vhost in apache_vhosts %}       #从apache_vhosts中循环,赋值给vhost
server {
	listen {{ vhost.listen }}
{% if vhost.server_name is defined %}  #判断vhost字典中是否存在server_name
	server_name {{ vhost.server_name }}  #若果有server_name则引用
{% endif %}
	root {{ vhost.root }}
}
{% endfor %}   #结束循环

    执行 playbook 后根据 template 生成了 apache.conf 文件

[root@CentOS69 ~]#??cat /data/apache.conf 
server {                    #web1中没有server_name,所以没有生成
	listen 8080       
	root /var/www/apache/web1/
}
server {
	listen 80           #根据playbook中的定义,对应的listen键值对不同
	server_name web2.magedu.com
	root /var/www/apache/web2/
}
server {
	listen 88
	server_name web3.magedu.com
	root /var/www/apache/web3/
}

roles

    ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置於单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

    角色目录建议存放在 /etc/ansible/roles 中,查看一个角色的目录结构

[root@CentOS174 roles]# tree
.
└── apache
    ├── default         #设定默认变量时使用此目录中的main.yml文件
    ├── files           #存放由copy或script模块等调用的文件
    │   └── index.html
    ├── handlers        #至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   └── main.yml    #若需要handler,则必须有一个main.yml
    ├── meta            #定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
    ├── tasks           #定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    │   ├── copy.yml
    │   ├── install.yml
    │   ├── main.yml    #必须有一个main.yml
    │   ├── start.yml
    │   ├── template2.2.yml
    │   ├── template2.4.yml
    │   └── user.yml
    ├── templates       #template模块查找所需要模板文件的目录
    │   ├── apache2.2.conf.j2
    │   └── apache2.4.conf.j2
    └── vars           #定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
        └── main.yml    #必须有一个main.yml

8 directories, 12 files

 查看 tasks 中每个角色,其中调用文件可以写相对路径,ansible 会自动在 /etc/ansible/roles/project 中查找

- name: copy index
  copy: src=index.html dest=/var/www/html
- name: install apache
  yum: name=httpd state=installed
- name: start apache
  service: name=httpd state=started
- name: copy conf for centos6
  template: src=apache2.2.conf.j2 dest=/etc/httpd/conf/httpd.conf
  when: ansible_distribution_major_version == "6"
  notify: restart httpd
- name: copy conf for centos7
  template: src=apache2.4.conf.j2 dest=/etc/httpd/conf/httpd.conf
  when: ansible_distribution_major_version == "7"
  notify: restart httpd
- name: create user
  user: name=apache system=yes shell=/sbin/nologin

查看 tasks 中文件 main.yml

- include: user.yml      #当执行时按照当前排列顺序执行
- include: install.yml
- include: copy.yml
- include: start.yml
- include: template2.2.yml
- include: template2.4.yml

查看 handler 中文件 main.yml

[root@CentOS174 roles]# cat apache/handlers/*
- name: restart httpd
  service: name=httpd state=restarted
查看 vars 中文件 main.yml
[root@CentOS174 roles]# cat apache/vars/*
port1: 88
port2: 99

    按照需求创建各个 roles 后,使用 playbook 执行即可

[root@CentOS174 ~]# cat /etc/ansible/apache_roles.yml 
- hosts: group1
  remote_user: root
  
  roles:
  - apache

执行后查看结果  

[root@CentOS174 ansible]# ansible-playbook apache_roles.yml

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [apache : create user] *****************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

TASK [apache : install apache] **************************************************************************************************************************************************************
changed: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy index] ******************************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

TASK [apache : start apache] ****************************************************************************************************************************************************************
changed: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos6] *******************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos7] *******************************************************************************************************************************************************
skipping: [192.168.30.69]
changed: [192.168.30.74]

RUNNING HANDLER [apache : restart httpd] ****************************************************************************************************************************************************
changed: [192.168.30.69]
changed: [192.168.30.74]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=7    changed=6    unreachable=0    failed=0   
192.168.30.74              : ok=7    changed=6    unreachable=0    failed=0   

    甚至,可以在 roles 中应用标签判断语句,和变量

[root@CentOS174 ansible]# cat apache_roles.yml
- hosts: group1
  remote_user: root
  
  roles:
  - { role: apache, tags: ['httpd', 'web'], when: ansible_distribution_major_version == "6" }

    查看执行结果

[root@CentOS174 ansible]# ansible-playbook -t web apache_roles.yml

PLAY [group1] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.30.74]
ok: [192.168.30.69]

TASK [apache : create user] *****************************************************************************************************************************************************************
skipping: [192.168.30.74]   #所有操作都跳过了centos6
changed: [192.168.30.69]    

TASK [apache : install apache] **************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy index] ******************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : start apache] ****************************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos6] *******************************************************************************************************************************************************
skipping: [192.168.30.74]
changed: [192.168.30.69]

TASK [apache : copy conf for centos7] *******************************************************************************************************************************************************
skipping: [192.168.30.69]   #复制apache2.4的配置文件,所以跳过了所有主机
skipping: [192.168.30.74]

RUNNING HANDLER [apache : restart httpd] ****************************************************************************************************************************************************
changed: [192.168.30.69]

PLAY RECAP **********************************************************************************************************************************************************************************
192.168.30.69              : ok=7    changed=6    unreachable=0    failed=0   
192.168.30.74              : ok=1    changed=0    unreachable=0    failed=0   





发布了75 篇原创文章 · 获赞 11 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章