一、roles
ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
一个roles的案例如下所示:
site.yml
webservers.yml
fooservers.yml
roles/
common/ 一级目录角色名
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
而在playbook中,可以这样使用roles:
---
- hosts: webservers
roles:
- common
- webservers
也可以向roles传递参数,例如:
---
- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/opt/a', port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', port: 5001 }
甚至也可以条件式地使用roles,例如:
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" }
1.1 创建role的步骤
(1) 创建以roles命名的目录;
(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;
(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;
(4) 在playbook文件中,调用各角色;
1.2 role内各目录中可用的文件
tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件;
files目录:存放由copy或script等模块调用的文件;
templates目录:template模块会自动在此目录中寻找Jinja2模板文件;
handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中;
vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;
default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;
二、Tags
tags用于让用户选择运行或路过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断。
创建一个httpd角色,其中的任务有安装httpd,开机启动和启动它,当本地httpd配置文件发生改变后,把本地的httpd配置文件复制到远程主机上,通过指定tags,如果安装了httpd,则先让其开机不启动和关闭服务后再删除。
创建一个httpd目录
[root@node1 ~]# mkdir httpd
[root@node1 ~]# cp /etc/httpd/conf/httpd.conf httpd/ 提供要复制到远程主机的配置文件
[root@node1 httpd]# ls -l
total 8
-rw-r--r-- 1 root root 75 Mar 30 06:29 apache.yml
drwxr-xr-x 3 root root 4096 Mar 30 06:26 roles
创建角色需要的目录
[root@node1 ~]# mkdir httpd/roles/web/{files,handles,tasks} -pv
mkdir: created directory `httpd/roles'
mkdir: created directory `httpd/roles/web'
mkdir: created directory `httpd/roles/web/files'
mkdir: created directory `httpd/roles/web/handles'
mkdir: created directory `httpd/roles/web/tasks'
[root@node1 ~]# cd httpd/
[root@node1 httpd]# yum install -y tree 安装tree
[root@node1 httpd]# vim apache.yml
编辑apache.yml添加角色,这里需要注意的是路径问题,apache.yml是在和roles在同一个目录层级的
[root@node1 httpd]# cat apache.yml
- hosts: constrol
remote_user: root
hosts: constrol
roles:
- web
[root@node1 httpd]# pwd
/root/httpd
[root@node1 httpd]# tree . 查看提供的目录树
.
├── apache.yml
├── httpd.conf
└── roles
└── web
├── files
├── handles
└── tasks
5 directories, 2 files
[root@node1 httpd]# mv httpd.conf roles/web/files/
[root@node1 httpd]# vim roles/web/handles/main.yml
[root@node1 httpd]# cat roles/web/handles/main.yml 提供handlers
- name: restart httpd
service: name=httpd state=restarted
[root@node1 httpd]# vim roles/web/tasks/main.yml
[root@node1 httpd]# cat roles/web/tasks/main.yml 提供任务tasks
- name: Install httpd 安装httpd
yum: name=httpd
tags: install 提供的一个标签
- name: start httpd 启动httpd
service: name=httpd enabled=yes state=started
- name: copy configuration file 复制配置文件
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: copy
notify: restart httpd
- command: /bin/false 下面是判断httpd是否安装了,如已经安装则先停止后卸载,这里存在问题没有考虑到幂等性,后面会修正
register: result
ignore_errors: True
tags: remove
- name: reinstall httpd
yum: name=httpd
when: result|failed
- name: stop httpd
service: name=httpd enabled=no state=stopped
- name: remove httpd
yum: name=httpd state=absent
[root@node1 httpd]# ansible constrol -m ping ping后面显示为pong,说明他们都在线
192.168.21.230 | success >> {
"changed": false,
"ping": "pong"
}
192.168.21.234 | success >> {
"changed": false,
"ping": "pong"
}
[root@node1 httpd]# ansible constrol -m command -a 'service httpd status' 正常启动了
192.168.21.230 | success | rc=0 >>
httpd (pid 27646) is running...
192.168.21.234 | success | rc=0 >>
httpd (pid 10379) is running...
[root@node1 httpd]# ansible-playbook apache.yml -t remove 指定remove标签出执行,这里也是存在问题的,指定tags后,只会对和tags在同一级别的任务最近的任务做执行,这里只执行了- command: /bin/false任务,下面都没执行
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [web | command /bin/false] **********************************************
failed: [192.168.21.234] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001795", "end": "2015-04-15 09:54:11.437250", "rc": 1, "start": "2015-04-15 09:54:11.435455", "warnings": []}
...ignoring
failed: [192.168.21.230] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001614", "end": "2015-04-15 09:54:11.487340", "rc": 1, "start": "2015-04-15 09:54:11.485726", "warnings": []}
...ignoring
PLAY RECAP ********************************************************************
192.168.21.230 : ok=2 changed=1 unreachable=0 failed=0
192.168.21.234 : ok=2 changed=1 unreachable=0 failed=0
[root@node1 httpd]# ansible constrol -m command -a 'service httpd status'这里就可以发现httpd没有被停止的
192.168.21.234 | success | rc=0 >>
httpd (pid 10379) is running...
192.168.21.230 | success | rc=0 >>
httpd (pid 27646) is running...
[root@node1 httpd]# ansible constrol -m command -a 'chkconfig --list httpd'
192.168.21.230 | success | rc=0 >>
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
192.168.21.234 | success | rc=0 >>
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@node1 httpd]# vim /etc/ansible/ansible.cfg 这里是通过修改配置查看一下错误原因,刚开始了解的是不很详细,所以想通过生成日志看看上面执行的过程
# logging is off by default unless this path is defined
# if so defined, consider logrotate
#log_path = /var/log/ansible.log
改为
log_path = /var/log/ansible.log
[root@node1 httpd]# ansible-playbook apache.yml -t remove 重新执行生成日志,其实也可以通过使用选项-vvv查看详细的执行过程的
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [web | command /bin/false] **********************************************
failed: [192.168.21.234] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001798", "end": "2015-04-15 10:16:08.181279", "rc": 1, "start": "2015-04-15 10:16:08.179481", "warnings": []}
...ignoring
failed: [192.168.21.230] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002055", "end": "2015-04-15 10:16:08.295655", "rc": 1, "start": "2015-04-15 10:16:08.293600", "warnings": []}
...ignoring
PLAY RECAP ********************************************************************
192.168.21.230 : ok=2 changed=1 unreachable=0 failed=0
192.168.21.234 : ok=2 changed=1 unreachable=0 failed=0
[root@node1 httpd]# cat /var/log/ansible.log 查看日志发现这里找不到什么有用的信息
2015-03-30 07:19:18,577 p=31389 u=root |
2015-03-30 07:19:18,578 p=31389 u=root | /usr/bin/ansible-playbook apache.yml -t remove
2015-03-30 07:19:18,578 p=31389 u=root |
2015-03-30 07:19:18,631 p=31389 u=root | PLAY [constrol] ***************************************************************
2015-03-30 07:19:18,638 p=31389 u=root | GATHERING FACTS ***************************************************************
2015-03-30 07:19:29,839 p=31389 u=root | ok: [192.168.21.230]
2015-03-30 07:19:30,007 p=31389 u=root | ok: [192.168.21.234]
2015-03-30 07:19:30,021 p=31389 u=root | TASK: [web | command /bin/false] **********************************************
2015-03-30 07:19:30,991 p=31389 u=root | failed: [192.168.21.234] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001798", "end": "2015-04-15 10:16:08.181279", "rc": 1, "start": "2015-04-15 10:16:08.179481", "warnings": []}
2015-03-30 07:19:30,991 p=31389 u=root | ...ignoring
2015-03-30 07:19:31,009 p=31389 u=root | failed: [192.168.21.230] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002055", "end": "2015-04-15 10:16:08.295655", "rc": 1, "start": "2015-04-15 10:16:08.293600", "warnings": []}
2015-03-30 07:19:31,010 p=31389 u=root | ...ignoring
2015-03-30 07:19:31,023 p=31389 u=root | PLAY RECAP ********************************************************************
2015-03-30 07:19:31,024 p=31389 u=root | 192.168.21.230 : ok=2 changed=1 unreachable=0 failed=0
2015-03-30 07:19:31,024 p=31389 u=root | 192.168.21.234 : ok=2 changed=1 unreachable=0 failed=0
[root@node1 ~]# cat web.yaml 这个是上次使用过的yaml,因为上次正常执行了,没考虑到这里是没有指定标签的,所以会按顺序全部执行完
- name: web server
remote_user: root
hosts: constrol
tasks:
- command: /bin/false
register: result
ignore_errors: True
- name: reinstall httpd
yum: name=httpd
when: result|failed
- name: stop httpd
service: name=httpd enabled=no state=stopped
- name: remove httpd
yum: name=httpd state=absent
[root@node1 ~]# ansible-playbook web.yaml 执行yaml
PLAY [web server] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [command /bin/false] ****************************************************
failed: [192.168.21.230] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001673", "end": "2015-04-15 10:21:59.205132", "rc": 1, "start": "2015-04-15 10:21:59.203459", "warnings": []}
...ignoring
failed: [192.168.21.234] => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002264", "end": "2015-04-15 10:22:04.076287", "rc": 1, "start": "2015-04-15 10:22:04.074023", "warnings": []}
...ignoring
TASK: [reinstall httpd] *******************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [stop httpd] ************************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [remove httpd] **********************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=5 changed=3 unreachable=0 failed=0
192.168.21.234 : ok=5 changed=3 unreachable=0 failed=0
[root@node1 ~]# ansible constrol -m command -a 'service httpd status' 是正常执行的,所以httpd被卸载了
192.168.21.234 | FAILED | rc=1 >>
httpd: unrecognized service
192.168.21.230 | FAILED | rc=1 >>
httpd: unrecognized service
[root@node1 ~]# ansible constrol -m command -a 'rpm -q httpd'
192.168.21.234 | FAILED | rc=1 >>
package httpd is not installed
192.168.21.230 | FAILED | rc=1 >>
package httpd is not installed
--skip-tags这个选项是跳过哪些标签,查看通过ansible-playbook --help|less查看帮助信息,这里就是安装httpd了
[root@node1 httpd]# ansible-playbook apache.yml --skip-tags=copy,remove
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [web | Install httpd] ***************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [web | start httpd] *****************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [web | reinstall httpd] *************************************************
fatal: [192.168.21.230] => |failed expects a dictionary
fatal: [192.168.21.234] => |failed expects a dictionary
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/apache.retry
192.168.21.230 : ok=3 changed=2 unreachable=1 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=1 failed=0
[root@node1 httpd]# ansible constrol -m command -a 'service httpd status' 查看信息,安装和启动都ok
192.168.21.230 | success | rc=0 >>
httpd (pid 29495) is running...
192.168.21.234 | success | rc=0 >>
httpd (pid 13317) is running...
[root@node1 httpd]# ansible constrol -m command -a 'rpm -q httpd'
192.168.21.230 | success | rc=0 >>
httpd-2.2.15-39.el6.centos.x86_64
192.168.21.234 | success | rc=0 >>
httpd-2.2.15-39.el6.centos.x86_64
[root@node1 ~]# cat web.yaml 修改web.yaml后的内容如下,还是存在幂等性问题
- name: web server
remote_user: root
hosts: constrol
tasks:
- name: reinstall httpd
yum: name=httpd state=present
register: result
- name: stop httpd
service: name=httpd enabled=no state=stopped
when: result|failed
- name: remove httpd
yum: name=httpd state=absent
[root@node1 ~]# ansible-playbook web.yaml
PLAY [web server] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [reinstall httpd] *******************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [stop httpd] ************************************************************
skipping: [192.168.21.234]
skipping: [192.168.21.230]
TASK: [remove httpd] **********************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=1 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=1 unreachable=0 failed=0
[root@node1 ~]# ansible constrol -m command -a 'rpm -q httpd'
192.168.21.234 | FAILED | rc=1 >>
package httpd is not installed
192.168.21.230 | FAILED | rc=1 >>
package httpd is not installed
[root@node1 ~]# ansible constrol -m command -a 'service httpd status'
192.168.21.234 | FAILED | rc=1 >>
httpd: unrecognized service
192.168.21.230 | FAILED | rc=1 >>
httpd: unrecognized service
[root@node1 httpd]# cat roles/web/tasks/main.yml 修改main.yml也是存在幂等性问题
- name: Install httpd
yum: name=httpd
tags: install
- name: start httpd
service: name=httpd enabled=yes state=started
- name: copy configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: copy
notify: restart httpd
- name: reinstall httpd
yum: name=httpd
register: result
tags: remove
- name: stop httpd
service: name=httpd enabled=no state=stopped
when: result|failed
- name: remove httpd
yum: name=httpd state=absent
[root@node1 httpd]# ansible-playbook apache.yml --skip-tags=copy,remove
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [web | Install httpd] ***************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
TASK: [web | start httpd] *****************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
TASK: [web | stop httpd] ******************************************************
fatal: [192.168.21.230] => |failed expects a dictionary
fatal: [192.168.21.234] => |failed expects a dictionary
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/apache.retry
192.168.21.230 : ok=3 changed=2 unreachable=1 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=1 failed=0
[root@node1 httpd]# ansible constrol -m command -a 'service httpd status'
192.168.21.230 | success | rc=0 >>
httpd (pid 30191) is running...
192.168.21.234 | success | rc=0 >>
httpd (pid 14020) is running...
[root@node1 httpd]# cat roles/web/tasks/main.yml 修改还是一样存在问题
- name: Install httpd
yum: name=httpd
tags: install
- name: start httpd
service: name=httpd enabled=yes state=started
- name: copy configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: copy
notify: restart httpd
- name: reinstall httpd
yum: name=httpd
register: result
- name: stop httpd
service: name=httpd enabled=no state=stopped
when: result|failed
- name: remove httpd
yum: name=httpd state=absent
tags: remove
[root@node1 httpd]# ansible-playbook apache.yml -t remove
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [web | remove httpd] ****************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=2 changed=1 unreachable=0 failed=0
192.168.21.234 : ok=2 changed=1 unreachable=0 failed=0
[root@node1 httpd]# ansible constrol -m command -a 'rpm -q httpd'
192.168.21.230 | FAILED | rc=1 >>
package httpd is not installed
192.168.21.234 | FAILED | rc=1 >>
package httpd is not installed
这里还有一个选项可以用来测试语法的--syntax-check
[root@node1 ~]# ansible-playbook web.yaml --syntax-check
playbook: web.yaml
ERROR: multiple actions specified in task: 'service' and 'stop httpd'
[root@node1 ~]# cat web.yaml 再次修改web.yml
- name: web server
remote_user: root
hosts: constrol
tasks:
- name: reinstall httpd
yum: name=httpd state=present
register: result
- name: stop httpd
service: name=httpd enabled=no state=stopped
yum: name=httpd state=absent
when: result|failed
[root@node1 ~]# cat web.yaml 修改都提供了标签,进行测试,执行多个任务就可以把tags和任务对齐
- name: web server
remote_user: root
hosts: constrol
tasks:
- name: stop httpd
service: name=httpd enabled=no state=stopped
- name: remove httpd
yum: name=httpd state=absent
tags: remove
tasks:
- name: Install httpd
yum: name=httpd
- name: start httpd
service: name=httpd enabled=yes state=started
tags: install
[root@node1 ~]# ansible constrol -m command -a 'service httpd status'
192.168.21.234 | FAILED | rc=1 >>
httpd: unrecognized service
192.168.21.230 | FAILED | rc=1 >>
httpd: unrecognized service
[root@node1 ~]# ansible-playbook web.yaml --syntax-check
playbook: web.yaml
[root@node1 ~]# ansible-playbook web.yaml -t install
PLAY [web server] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [Install httpd] *********************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
TASK: [start httpd] ***********************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=2 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
[root@node1 ~]# ansible constrol -m command -a 'service httpd status'
192.168.21.230 | success | rc=0 >>
httpd (pid 30814) is running...
192.168.21.234 | success | rc=0 >>
httpd (pid 14670) is running...
http://docs.ansible.com/YAMLSyntax.html下面有yaml语法,可以查看一下
对roles/web/tasks/main.yml做切分,其他内容未修改,如下:
roles/web/tasks/main.yml内容如下:
---
#file: main.yml
- include: install.yml
tags: install 通过在包含的yml文件处指定tags,这样tags就可以在前一个include包含的文件中的内容都生效
- include: remove.yml
tags: remove
- include: copy.yml
tags: copy
目录为:roles/web/tasks/
文件install.yml内容如下:
---
#file: install.yml
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd enabled=yes state=started
文件remove.yml内容如下: 幂等性问题已经剔除了
---
#file remove.yml
- name: stop httpd
service: name=httpd enabled=no state=stopped
- name: remove httpd
yum: name=httpd state=absent
文件copy.yml内容如下:
---
#file copy.yml
- name: copy configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
[root@node1 httpd]# ansible-playbook apache.yml -t remove 执行删除httpd
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [web | stop httpd] ******************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [web | remove httpd] ****************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=2 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
修改一下配置文件httpd.conf端口进行测试有80到8080
[root@node1 httpd]# vim roles/web/files/httpd.conf
[root@node1 httpd]# ansible-playbook apache.yml -t copy
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [web | copy cofiguration file] ******************************************
changed: [192.168.21.234] 这里只把文件复制过去了
changed: [192.168.21.230]
ERROR: change handler (restart httpd) is not defined
[root@node1 httpd]# mv roles/web/handles roles/web/handlers 原因是少了一handles少了一个r是handlers
[root@node1 httpd]# cat roles/web/handlers/main.yml
---
#file: handlers.yml
- name: restart httpd
service: name=httpd state=restarted
[root@node1 httpd]# ansible-playbook apache.yml -t copy 需要修改一下httpd.conf文件而后再执行
PLAY [constrol] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.230]
ok: [192.168.21.234]
TASK: [web | copy cofiguration file] ******************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
NOTIFIED: [web | restart httpd] ***********************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=2 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
发现ok了
案列通过role的方式定义安装配置LAMP平台,一个部署web和php,一台部署db,并且通过脚本测试可以连上mysql服务器。架构图如下所示:
在node1上,创建3个角色httpd、mysql、php,在/etc/ansible/hosts文件中定义两个组,内容如下所示:
[root@node1 ~]# cat /etc/ansible/hosts 修改hosts内容
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
# Ex 1: Ungrouped hosts, specify before any group headers.
[lamp]
192.168.21.234
[dbserver]
192.168.21.234
192.168.21.230
[root@node1 ~]# mkdir program 创建项目目录
[root@node1 ~]# mkdir -pv program/roles/{httpd/{handlers,tasks},mysql/{handlers,tasks},php/{handlers,tasks}}创建需要使用的目录
mkdir: created directory `program/roles'
mkdir: created directory `program/roles/httpd'
mkdir: created directory `program/roles/httpd/handlers'
mkdir: created directory `program/roles/httpd/tasks'
mkdir: created directory `program/roles/mysql'
mkdir: created directory `program/roles/mysql/handlers'
mkdir: created directory `program/roles/mysql/tasks'
mkdir: created directory `program/roles/php'
mkdir: created directory `program/roles/php/handlers'
mkdir: created directory `program/roles/php/tasks'
[root@node1 ~]# tree program/ 查看创建的目录树
program/
└── roles
├── httpd
│?? ├── handlers
│?? └── tasks
├── mysql
│?? ├── handlers
│?? └── tasks
└── php
├── handlers
└── tasks
10 directories, 0 files
[root@node1 ~]# cd program/
[root@node1 program]# vim program.yml
[root@node1 program]# cat program.yml 创建program.yml,提供了3个角色,用了2个hosts
---
#file: program.yml
- hosts: lamp
remote_user: root
roles:
- apache
- php
- hosts: dbserver
remote_user: root
roles:
- mysql
[root@node1 program]# vim roles/httpd/tasks/main.yml
[root@node1 program]# cat roles/httpd/tasks/main.yml 提供各角色所需的文件,在此不解释了,前面也有相关的内容
---
#file main.yml
- include: install.yml
tags: inshttpd
- include: copy.yml
tags: cyhttpd
- include: remove.yml
tags: remhttpd
[root@node1 program]# vim roles/httpd/tasks/install.yml
[root@node1 program]# cat roles/httpd/tasks/install.yml
---
#file: install.yml
- name: Install httpd
yum: name=httpd
- name: start httpd
service: name=httpd enabled=yes state=started
[root@node1 program]# cat roles/httpd/tasks/copy.yml
---
#file: copy.yml
- name: copy configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
[root@node1 program]# vim roles/httpd/tasks/remove.yml
[root@node1 program]# cat roles/httpd/tasks/remove.yml
---
#file: remove.yml
- name: httpd stop
service: name=httpd enabled=no state=stopped
- name: remove httpd
yum: name=httpd state=absent
[root@node1 program]# vim roles/mysql/tasks/main.yml
[root@node1 program]# cat roles/mysql/tasks/main.yml
---
#file: main.yml
- include: install.yml
tags: insmysql
- include: remove.yml
tags: remmysql
[root@node1 program]# vim roles/mysql/tasks/install.yml
[root@node1 program]# cat roles/mysql/tasks/install.yml
---
#file: install.yml
- name: Install mysql
yum: name=mysql-server
- name: start mysql
service: name=mysqld enabled=yes state=started
[root@node1 program]# vim roles/mysql/tasks/remove.yml
[root@node1 program]# cat roles/mysql/tasks/remove.yml
---
#file: remove.yml
- name: stopped mysql
service: name=mysqld enabled=no state=stopped
- name: remove mysql
yum: name=mysql-server state=absent
[root@node1 program]# vim roles/httpd/handlers/main.yml
[root@node1 program]# cat roles/httpd/handlers/main.yml
---
#file: main.yml
- name: restart httpd
service: name=httpd state=restarted
[root@node1 program]# vim roles/php/tasks/main.yml
[root@node1 program]# cat roles/php/tasks/main.yml
---
#file: main.yml
- include: install.yml
tags: insphp
- include: remove.yml
tags: remphp
[root@node1 program]# vim roles/php/tasks/install.yml
[root@node1 program]# cat roles/php/tasks/install.yml
---
#file: install.yml
- name: Install php
yum: name=php
- name: Install php-mysql
yum: name=php-mysql
[root@node1 program]# vim roles/php/tasks/remove.yml
[root@node1 program]# cat roles/php/tasks/remove.yml
---
#file: remove.yml
- name: remove php
yum: name=php state=absent
- name: remove php-mysql
yum: name=php-mysql state=absent
[root@node1 program]# tree .
.
├── program.yml
└── roles
├── httpd
│?? ├── handlers
│?? │?? └── main.yml
│?? └── tasks
│?? ├── copy.yml
│?? ├── install.yml
│?? ├── main.yml
│?? └── remove.yml
├── mysql
│?? ├── handlers
│?? └── tasks
│?? ├── install.yml
│?? ├── main.yml
│?? └── remove.yml
└── php
├── handlers
└── tasks
├── install.yml
├── main.yml
└── remove.yml
10 directories, 12 files
[root@node1 program]# mkdir roles/httpd/files
[root@node1 program]# cp /etc/httpd/conf/httpd.conf roles/httpd/files
最近的目录和文件树如下:
[root@node1 program]# tree .
.
├── program.yml
└── roles
├── httpd
│?? ├── files
│?? │?? └── httpd.conf
│?? ├── handlers
│?? │?? └── main.yml
│?? └── tasks
│?? ├── copy.yml
│?? ├── install.yml
│?? ├── main.yml
│?? └── remove.yml
├── mysql
│?? ├── handlers
│?? └── tasks
│?? ├── install.yml
│?? ├── main.yml
│?? └── remove.yml
└── php
├── handlers
└── tasks
├── install.yml
├── main.yml
└── remove.yml
11 directories, 13 files
[root@node1 program]# ansible-playbook program.yml --syntax-check 测试语法是否有误
playbook: program.yml
ERROR: cannot find role in /root/program/roles/apache or /root/program/apache or /etc/ansible/roles/apache
[root@node1 program]# vim program.yml
[root@node1 program]# cat program.yml
---
#file: program.yml
- hosts: lamp
remote_user: root
roles:
- httpd 修改此处有原来的apache -> httpd,因为没有apache角色
- php
- hosts: dbserver
remote_user: root
roles:
- mysql
[root@node1 program]# ansible-playbook program.yml --syntax-check 再次进行测试语法ok了
playbook: program.yml
清楚node3上的httpd
[root@node1 program]# ansible-playbook program.yml -t remhttpd
PLAY [lamp] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
TASK: [httpd | httpd stop] ****************************************************
changed: [192.168.21.234]
TASK: [httpd | remove httpd] **************************************************
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
安装httpd
[root@node1 program]# ansible-playbook program.yml -t inshttpd
PLAY [lamp] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
TASK: [httpd | Install httpd] *************************************************
changed: [192.168.21.234]
TASK: [httpd | start httpd] ***************************************************
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
安装php
[root@node1 program]# ansible-playbook program.yml -t insphp
PLAY [lamp] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
TASK: [php | Install php] *****************************************************
changed: [192.168.21.234]
TASK: [php | Install php-mysql] ***********************************************
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
安装mysql
[root@node1 program]# ansible-playbook program.yml -t insmysql
PLAY [dbserver] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [mysql | Install mysql] *************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [mysql | start mysql] ***************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=2 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
查看端口启用正常与否
[root@node1 program]# ansible lamp -m shell -a 'ss -tnlp|grep -E "80|3306"'
192.168.21.234 | success | rc=0 >>
LISTEN 0 50 *:3306 *:* users:(("mysqld",17964,11))
LISTEN 0 128 :::80 :::* users:(("httpd",17433,5),("httpd",17436,5),("httpd",17437,5),("httpd",17438,5),("httpd",17439,5),("httpd",17440,5),("httpd",17441,5),("httpd",17442,5),("httpd",17443,5))
[root@node1 program]# ansible dbserver -m shell -a 'ss -tnlp|grep 3306'
192.168.21.234 | success | rc=0 >>
LISTEN 0 50 *:3306 *:* users:(("mysqld",17964,11))
192.168.21.230 | success | rc=0 >>
LISTEN 0 50 *:3306 *:* users:(("mysqld",33420,11))
清除两台机器上刚安装的服务
[root@node1 program]# ansible-playbook program.yml -t remhttpd
PLAY [lamp] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
TASK: [httpd | httpd stop] ****************************************************
changed: [192.168.21.234]
TASK: [httpd | remove httpd] **************************************************
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
[root@node1 program]# ansible-playbook program.yml -t remphp
PLAY [lamp] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
TASK: [php | remove php] ******************************************************
ok: [192.168.21.234]
TASK: [php | remove php-mysql] ************************************************
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.234 : ok=3 changed=1 unreachable=0 failed=0
[root@node1 program]# ansible-playbook program.yml -t remmysql
PLAY [dbserver] ***************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.21.234]
ok: [192.168.21.230]
TASK: [mysql | stopped mysql] *************************************************
changed: [192.168.21.234]
changed: [192.168.21.230]
TASK: [mysql | remove mysql] **************************************************
changed: [192.168.21.230]
changed: [192.168.21.234]
PLAY RECAP ********************************************************************
192.168.21.230 : ok=3 changed=2 unreachable=0 failed=0
192.168.21.234 : ok=3 changed=2 unreachable=0 failed=0
发现都ok
安装和启动各远程节点的服务,此处不再演示
[root@node1 program]# vim index.php
[root@node1 program]# cat index.php
<?php
phpinfo();
?>
[root@node1 program]# ansible lamp -m copy -a 'src=index.php dest=/var/www/html/'
192.168.21.234 | success >> {
"changed": true,
"checksum": "26af88945e23289d15e128606a29932b3d78787c",
"dest": "/var/www/html/index.php",
"gid": 0,
"group": "root",
"md5sum": "62210a938d0199092c2d3976a45bf86d",
"mode": "0644",
"owner": "root",
"size": 22,
"src": "/root/.ansible/tmp/ansible-tmp-1427707616.78-214058087338938/source",
"state": "file",
"uid": 0
}
重启一下httpd,在客户端访问192.168.21.234/index.php显示
转载于:https://blog.51cto.com/wdllife/1633093