功能:根据模块文件动态生成对应的配置文件ios
Jinja2语言,使用字面量,有下面形式 字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1, item2, ...] 元组:(item1, item2, ...) 字典:{key1:value1, key2:value2, ...} 布尔型:true/false 算术运算:+, -, *, /, //, %, ** 比较操做:==, !=, >, >=, <, <= 逻辑运算:and, or, not 流表达式:For If When
templates文件必须存放于templates目录下,且命名为 .j2 结尾 yaml/yml 文件需和templates目录平级,目录结构以下: ./ ├── temnginx.yml └── templates └── nginx.conf.j2
.j2文件nginx
server { worker_connectios {{ ansible_processor_vcpus *2 }}; }
yml文件git
- hosts: dns remote_user: root tasks: - template: src=/app/1.conf.j2 dest=/app/2.conf
生成的配置文件web
server { worker_connectios 4; > ansible_processor_vcpus=2,因此2*2=4 }
语法:shell
{% for i in nginx_vhosts %} 语句块 {% endfor %} {% if vhost.root is defined %} root {{ vhost.root }}; {% endif %}
以实例来说:apache
- hosts: web remote_user: root vars: prot_list: - 8080 - 8081 - 8082 tasks: - name: create vhost template: src=/app/1.conf.j2 dest=/app/2.conf > for 循环是写在.j2文件中的。 通常来说是配合template模板来使用,文件的后缀名为.j2 先创建一个标准模板文件,这个文件须要跟dest使用的格式一致,只不过是将会变化的内容使用for循环的格式来写 {% for prot in prot_list %} server { listen prot; } {% endfor %} 是否是与shell编程的for循环很像?
#ansible-playbook for1.yml 结果: #cat /app/2.conf server { listen 8080; } server { listen 8081; } server { listen 8082; }
再来一个多行多主机的模板:编程
- hosts: web remote_user: root vars: vhosts: - web: prot: 8080 server: web1.hunk.tech root: /app/webroot1 - web: prot: 8081 server: web2.hunk.tech root: /app/webroot2 - web: prot: 8082 server: web2.hunk.tech root: /app/webroot2 tasks: - name: create vhost template: src=/app/1.conf.j2 dest=/app/2.conf j2文件: {% for vhost in vhost_list %} server { listen {{ vhost.prot }}; servername {{ vhost.server }}; root {{ vhost.root }}; } {% endfor %} 执行: #ansible-playbook for1.yml 结果: #cat /app/2.conf server { listen 8080; servername web1.hunk.tech; root /app/webroot1; } server { listen 8081; servername web2.hunk.tech; root /app/webroot2; } server { listen 8082; servername web2.hunk.tech; root /app/webroot2; }
语法:vim
{% if i is defined %} 语句块 {% endif %}
playbook文件:app
- hosts: web remote_user: root vars: vhost_list: - web1: prot: 8080 name: web1.hunk.tech > 注意,web1是定义了name的值 - web2: > 注意,web2是没有定义了name的值 prot: 8081 tasks: - template: src=/app/1.conf.j2 dest=/app/2.conf
j2文件:ide
{% for vhost in vhost_list %} server { listen {{ vhost.prot }}; {% if vhost.name is defined %} > 若是vhost.name有应以,刚填入下面的内容 servername {{ vhost.name }}; {% endif %} } {% endfor % 执行: #ansible-playbook if.yml 结果: #cat /app/2.conf server { listen 8080; servername web1.hunk.tech; } server { listen 8081; }
用于层次性、结构化地组织playbook。 roles可以根据层次型结构自动装载变量文件、tasks以及handlers等。
要使用roles只须要在playbook中使用import_tasks指令便可。(include也能够用,官方明确声明此命令将会淘汰)
简单来说,roles就是经过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并能够便捷地
include它们的一种机制。角色通常用于基于主机构建服务的场景中,但也能够是用于构建守护进程等场景中
复杂场景:建议使用roles,代码复用度高
(1) 建立以roles命名的目录 (2) 在roles目录中分别建立以各角色名称命名的目录,如webservers等 (3) 在每一个角色命名的目录中分别建立files、 handlers、meta、 tasks、 templates和vars目录; 用不到的目录能够建立为空目录,也能够不建立 (4) 在playbook文件中,调用各自角色
├── roles > 必须是这个名字 │ ├── git > 具体项目名称 │ │ ├── default > 设定默认变量时使用此目录中的main.yml文件 │ │ │ └── main.yml > 至少应该包含一个名为main.yml的文件 │ │ ├── files > 存放有copy或script模块等调用的文件 │ │ ├── handlers > 定义触发器 │ │ │ └── main.yml > 至少应该包含一个名为main.yml的文件 │ │ ├── meta > 定义当前角色的特殊设定及其依赖关系 │ │ │ └── main.yml > 至少应该包含一个名为main.yml的文件 │ │ ├── tasks > 定义任务 │ │ │ └── main.yml > 至少应该包含一个名为main.yml的文件 │ │ ├── templates > template模块查找所须要模板文件目录 │ │ │ └── main.yml > 至少应该包含一个名为main.yml的文件 │ │ └── vars > 定义变量;;其余的文件须要在此文件中经过include进行包含 │ │ └── main.yml > 至少应该包含一个名为main.yml的文件
仍是拿一个实例来讲:
若是要在一台初始化的主机上面安装httpd服务,有如下过程:(这里不考虑编译安装状况,假设yum脚本里不会建立组和用户)
1.建立用于httpd服务的组 2.建立用于httpd服务的用户 3.安装httpd软件包 4.启动httpd服务
把这些过程体如今ansible上面就是对应的具体的tasks,所以,将须要在roles/tasks/下面建立分别用于这些过程的独立yml文件
1.建立用于httpd服务的 #vim groupadd.yml - name: groupadd apache group: name=apache 2.建立用于httpd服务的用户 #vim useradd.yml - name: useradd apache user: name=apache group=apache shell=/sbin/nologin system=yes 3.安装httpd软件包 #vim install_httpd.yml - name: yum install httpd yum: name=httpd 4.启动httpd服务 #vim start_httpd.yml - name: start httpd service: name=httpd state=started
每一个具体的小任务有了,那么就得有一个主的配置文件,默认剧本就会读取它,从而肯定其余任务的关系。
注意,文件名必须是main.yml
注意,顺序不能颠倒,步骤是从上而下顺序执行,就像编排电影剧本同样。有没有当导演的感受? #vim main.yml - import_tasks: groupadd.yml - import_tasks: useradd.yml - import_tasks: install_httpd.yml - import_tasks: start_httpd.yml
最后,建立一个执行的playbook文件,这个文件与roles目录是同级目录。
#vim httpd_roles.yml --- - hosts: web remote_user: root roles: - httpd > 注意,这个- 后面跟就是roles目录下的子目录名称 固然,也能够写成 roles: - role: httpd > 注意,这个- role: 是不能够改变名称的,后面跟就是roles目录下的子目录名称
至此,此时的目录结构为:
├── httpd_roles.yml > 执行的playbook文件 └── roles > roles角色目录 ├── httpd > 项目文件夹 │ ├── default │ ├── files │ ├── handlers │ ├── meta │ ├── tasks > 任务文件夹 │ │ ├── groupadd.yml │ │ ├── install_httpd.yml │ │ ├── main.yml │ │ ├── start_httpd.yml │ │ └── useradd.yml │ ├── templates │ └── vars
#ansible web -m shell -a 'ss -nlt|grep 80' 6-web-1.hunk.tech | SUCCESS | rc=0 >> LISTEN 0 128 :::80 7-web-2.hunk.tech | SUCCESS | rc=0 >> LISTEN 0 128 :::80 7-web-0.hunk.tech | SUCCESS | rc=0 >> LISTEN 0 128 :::80
为了更好的复用代码,能够将一些公共的代码集中在一个目录里,按须要在之后的roles进行调用
├── pubtasks │ └── create_nginx_user_and_group.yml
#cat create_nginx_user.yml - name: create nginx group group: name=nginx - name: create nginx user user: name=nginx shell=/usr/sbin/nologin comment="nginx service" group=nginx createhome=no
调用的时候,在tasks中引入便可
- hosts: dns remote_user: root tasks: - name: test import_tasks: /app/yml/pubtasks/create_nginx_user_and_group.yml
同理,在别的文件中引入import_role也是能够的。
前面的章节针对tasks有tags,而roles中也能够运用此方法
- hosts: web remote_user: root roles: - { role: httpd, tags: [ 'web', 'apache22' ] } > 其实,这是字典的一种写法,前面章节有讲到,只不过是写在一行里了。 因此,下面的写法是同等的 roles: - role: httpd tags: - web - apache22
基于条件判断的roles的tags
- { role: nginx, tags: [ 'nginx', 'web' ], when: ansible_distribution_major_version == "6" }
当roles中有了tags后,执行时候加上-t tags名称便可
# ansible-playbook httpd_roles.yml -t web # ansible-playbook httpd_roles.yml -t apache22 也能够同时调用多个tags # ansible-playbook httpd_roles.yml -t "web,db"
第 (五) 篇属于应用级别的。后续再更新了。