{{ cat }}'s docs

1.3.6: playbook-动态、循环include(yaml)


0. 思路详解

希望在同一个role里面包含线上服务器所有服务的安装,这些安装task分散到不同的yaml文件中,然后通过group中不同身份标识(服务器身份变量)的传递,来对这些安装文件进行组合。
确切的讲,就是希望达到使用变量在main.yml中达到动态的、循环的(有可能同一台服务器多个身份标识)include yaml文件的效果

特别需要注意的是,下面内容中的转义符"\"仅仅是为了兼容语法而存在,实际使用过程中,应该要去掉


1. 实现实例

1) 主机列表、变量文件和task文件内容

inventory文件: hosts

[webserver]
testweb ansible_host=192.168.33.112

[webservice]
testservice ansible_host=192.168.33.112

为了测试,给同一个主机配置了不同的主机alias

group变量文件: group_vars/webserver

---
# ssh config
ansible_ssh_private_key_file: "/root/.ssh/id_rsa"
ansible_ssh_pass: "123456"

# server config
# server_type: {nginx,webserver,webservice,middleservice,redis,zookeeper}
server_type:
    - "webserver"
    - "nginx"
---

这里使用server_type来给服务器指定身份标识

roles里面的main.yml文件: roles/server_initialize/tasks/main.yml

---
- include: "\{\{ item }}.yml"
  with_items: "\{\{ server_type }}"
---

在main.yml同目录下还有其他的server_type对应的yaml task文件,我们希望通过with_items循环include它们,这里重点关注"\{\{ item }}.yml",之前错误的尝试过"\{\{ item }}".yml"\{\{ item }}"".yml",不断的排错之后,才最终找到正确的写法"\{\{ item }}.yml"

在网上找到一种解释,yaml文件中如果以{开头,yaml解释器将其认定为一个dict,所以为了解决这个问题,当\{\{ var }}不在结尾时,需要用双引号,将其与其他字符串一同引起来,参考链接

为了测试,server_type对应的yml文件只输出简单的debug信息

# webserver.yml
---
- debug: msg="webserver"

# nginx.yml
---
- debug: msg="nginx"
---

2) 执行结果

按照预期,我们配置了两个server_type,所以应该输出两个server_type的debug信息

ansible-playbook -i hosts main.yml -e "{'role':'server_initialize','host':'webserver'}"                                                  
PLAY [webserver] ***************************************************************

TASK [server_initialize : include] *********************************************
included: /root/ansible/roles/server_initialize/tasks/webserver.yml for testweb
included: /root/ansible/roles/server_initialize/tasks/nginx.yml for testweb

TASK [server_initialize : debug] ***********************************************
ok: [testweb] => {
    "msg": "webserver"
}

TASK [server_initialize : debug] ***********************************************
ok: [testweb] => {
    "msg": "nginx"
}

PLAY RECAP *********************************************************************
testweb                    : ok=4    changed=0    unreachable=0    failed=0

输出结果中表示,我们确实循环include了两个yaml文件,而且这两个yaml文件也确实执行了他们的task,这样我们就达到了我们的预期目标