Operations-ansible-02-playbook
playbook组织结构
- host {hostname|inventory_name|ip} #表示远程主机标识
remote_user:remote_user_name #表示远程主机上执行任务的身份
vars: #定义变量
Key1:Value1 #这种变量的应用方法为 {{Keyx}}
Key2:Value2
Keyn:Valuen
tasks: #表示一个任务组,用列表表示
- name:task_name1 #具有标识性质的字符串比如:task useradd
module_name:module_args #比如:user:name={{var_name}} state=present或者user:name=username state=present,args中的变量还可以是item中的
when:condition #比如条件为facts即:ansible_os_family=="RedHat"
notify:handlers_name #表示发生改变才触发的任务,handlers_name表示handlers条目中的名称
with_items:
- item_name1 #这种形式的item在args中使用 {{ item }} 应用
- item_name2
- item_namen
- {var_name:'content',var_name2:'content',var_namen:'content'} #这种形式的item在args中使用 {{ item.var_name }} 应用
- {var_name:'content',var_name2:'content',var_namen:'content'}
template:template_args #这里显示使用template模块,其参数主要是 src 和 dest,一般用于配置文件的修改使用,src的配置文件应该使用jinja2模板的语法,使用{{tempalte_name}}定义,而其应用可以使用主机变量、自定义变量和vars变量
tags:tags_name #定义tasks的TAGS,这个tags可用于ansible-playbook -tags=tags_name playname.yml来调用特定的tasks
- name:task_namex... #表示可以定义多个tasks
handlers:
- name:handlers_name1
module_name:module_args #表示handlers同样也使用模块来定义任务
- name:handlers_name2... #表示可以定义多个handlers
使用playbook在远程主机上添加用户aaa、bbb、ccc、ddd并且密码与用户名相同
[root@localhost work]# vim useradd.yml
- hosts: all
remote_user: root
tasks:
- name: add users
user: name={{ item }} state='present'
with_items:
- aaa
- bbb
- ccc
- name: passwd users
shell: echo {{ item }} | passwd --stdin {{ item }}
with_items:
- aaa
- bbb
- ccc
[root@localhost work]# ansible-playbook useradd.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [add users] *************************************************************
changed: [172.16.11.102] => (item=aaa)
changed: [172.16.11.101] => (item=aaa)
changed: [172.16.11.102] => (item=bbb)
changed: [172.16.11.101] => (item=bbb)
changed: [172.16.11.102] => (item=ccc)
changed: [172.16.11.101] => (item=ccc)
TASK: [passwd users] **********************************************************
changed: [172.16.11.101] => (item=aaa)
changed: [172.16.11.102] => (item=aaa)
changed: [172.16.11.101] => (item=bbb)
changed: [172.16.11.102] => (item=bbb)
changed: [172.16.11.101] => (item=ccc)
changed: [172.16.11.102] => (item=ccc)
PLAY RECAP ********************************************************************
172.16.11.101 : ok=3 changed=2 unreachable=0 failed=0
172.16.11.102 : ok=3 changed=2 unreachable=0 failed=0
注意playbook的缩进,这可能会造成任务的失败
删除上面的四个用户
可以复用上面的文件,只需要修改、添加几个地方
[root@localhost work]# ansible-playbook --tags=modifyusers deluser.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [add users] *************************************************************
changed: [172.16.11.101] => (item=aaa)
changed: [172.16.11.102] => (item=aaa)
changed: [172.16.11.101] => (item=bbb)
changed: [172.16.11.102] => (item=bbb)
changed: [172.16.11.101] => (item=ccc)
changed: [172.16.11.102] => (item=ccc)
PLAY RECAP ********************************************************************
172.16.11.101 : ok=2 changed=1 unreachable=0 failed=0
172.16.11.102 : ok=2 changed=1 unreachable=0 failed=0
[root@localhost work]# ansible-playbook --tags=modifyusers deluser.yml
添加tags一定要做好缩进,否则可能会报错,要把tags写到对应的-name条目下
安装httpd程序,上传httpd配置文件,如果配置文件修改就重启httpd服务,如果配置文件没有修改就启动httpd服务
# yml文件
[root@localhost work]# vim srv.yml
- hosts: all
remote_user: root
tasks:
- name: install httpd
yum: name='httpd' state='present'
- name: upload httpd.conf
template: src=/work/httpd.conf dest=/etc/httpd/conf/
notify: changed
- name: start httpd
service: name=httpd state=started
handlers:
- name: changed
service: name=httpd state=restarted
# 运行状况
[root@localhost work]# ansible-playbook srv.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [install httpd] *********************************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
TASK: [upload httpd.conf] *****************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [start httpd] ***********************************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
PLAY RECAP ********************************************************************
172.16.11.101 : ok=4 changed=2 unreachable=0 failed=0
172.16.11.102 : ok=4 changed=2 unreachable=0 failed=0
# 远程主机状况
[root@husa ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
# 可以看到已经启动了80端口服务
如何修改上述两台远程主机的端口分别为808
# 定义一个变量
[root@localhost work]# vim srv.yml
- hosts: all
remote_user: root
vars:
port: 808
tasks:
- name: install httpd
yum: name='httpd' state='present'
- name: upload httpd.conf
template: src=/work/httpd.conf dest=/etc/httpd/conf/
notify: changed
- name: start httpd
service: name=httpd state=started
handlers:
- name: changed
service: name=httpd state=restarted
# 修改上传的配置文件
[root@localhost work]# vim /work/httpd.conf
#Listen 12.34.56.78:80
#Listen 80
Listen {{ port }}
# 运行
[root@localhost work]# ansible-playbook srv.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [install httpd] *********************************************************
ok: [172.16.11.102]
ok: [172.16.11.101]
TASK: [upload httpd.conf] *****************************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
TASK: [start httpd] ***********************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
NOTIFIED: [changed] ***********************************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
PLAY RECAP ********************************************************************
172.16.11.101 : ok=5 changed=2 unreachable=0 failed=0
172.16.11.102 : ok=5 changed=2 unreachable=0 failed=0
# 远程主机端口
[root@husa ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::808 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
使用roles安装httpd并配置httpd.conf然后启动httpd服务
# 创建roles的目录结构
[root@localhost roles]# cd
[root@localhost ~]# mkdir -pv /etc/ansible/roles/real\ server/{meta,handlers,vars,files,templates,tasks}
mkdir: created directory `/etc/ansible/roles/real server'
mkdir: created directory `/etc/ansible/roles/real server/meta'
mkdir: created directory `/etc/ansible/roles/real server/handlers'
mkdir: created directory `/etc/ansible/roles/real server/vars'
mkdir: created directory `/etc/ansible/roles/real server/files'
mkdir: created directory `/etc/ansible/roles/real server/templates'
mkdir: created directory `/etc/ansible/roles/real server/tasks'
[root@localhost ~]# cd /etc/ansible/roles/real\ server/
# 定义roles所用到的文件
[root@localhost real server]# cp /work/httpd.conf ./files/ # 配置文件的port变量定义为 {{ port }}
# 定义任务
[root@localhost real server]# vim tasks/main.yml
- name: install httpd
yum: name='httpd' state='present'
- name: upload httpd.conf
template: src=httpd.conf dest=/etc/httpd/conf/
notify: changed
- name: start httpd
service: name=httpd state=started
# 定义变量
[root@localhost real server]# vim vars/main.yml
port: 808
# 定义handlers
[root@localhost real server]# vim handlers/main.yml
- name: changed
service: name='httpd' state='restart'
# roles目录结构
[root@localhost work]# tree /etc/ansible/roles/
/etc/ansible/roles/
└── real server
├── files
│ └── httpd.conf
├── handlers
│ └── main.yml
├── meta
├── tasks
│ └── main.yml
├── templates
└── vars
└── main.yml
# 定义roles.yml
[root@localhost work]# vim roles.yml
- hosts: all
remote_user: root
roles:
- real server
# 运行
[root@localhost work]# ansible-playbook roles.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.11.101]
ok: [172.16.11.102]
TASK: [webserver | install httpd] *********************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
TASK: [webserver | upload httpd.conf] *****************************************
changed: [172.16.11.102]
changed: [172.16.11.101]
TASK: [webserver | start httpd] ***********************************************
changed: [172.16.11.101]
changed: [172.16.11.102]
NOTIFIED: [webserver | changed] ***********************************************
failed: [172.16.11.102] => {"failed": true}
msg: value of state must be one of: running,started,stopped,restarted,reloaded, got: restart
failed: [172.16.11.101] => {"failed": true}
msg: value of state must be one of: running,started,stopped,restarted,reloaded, got: restart
FATAL: all hosts have already failed -- aborting
NOTIFIED: [webserver | changed] ***********************************************
FATAL: no hosts matched or all hosts have already failed -- aborting
FATAL: all hosts have already failed -- aborting
NOTIFIED: [webserver | changed] ***********************************************
FATAL: no hosts matched or all hosts have already failed -- aborting
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/roles.retry
172.16.11.101 : ok=4 changed=3 unreachable=0 failed=1
172.16.11.102 : ok=4 changed=3 unreachable=0 failed=1
# 虽然执行结果中含有错误,但是仔细分析就会发现这是正确的,因为httpd.conf配置文件是第一次上传,并没有发生变化,所以changed任务才会失败,因此后续的notify也会失败
可以这样理解:在没有roles之前,是把所有的任务“头”都要写出来,比如tasks、handlers;但是使用roles之后,这些“头”直接以目录的形式体现了,所有在这些目录中不需要再写“头”,只需要写出这些entry的内容就行了…这是我的理解