Ansible-Jinja2模板的使用与Roles角色管理

发布于:2024-12-18 ⋅ 阅读:(152) ⋅ 点赞:(0)

目录

一.Ansible中jinja2模板的使用

1.jinja2模板语法

(1).template模块

copy模块与template模块的区别

template模块常用参数

(2).基础语法

(3).插入变量

创建jinja2模板文件

在playbook中使用模板

运行playbook

(4).流程控制

条件判断

格式:

示例:

多条件判断

格式:

示例:

循环表达式

格式:

示例:

字典循环

示例:

(5).过滤器

示例:将字符串转换为大写

(6).宏定义

示例:

(7).其他模板

二.Ansible中的Roles角色管理

1.roles模块介绍

2.roles的目录结构

3.ansible-galaxy命令

(1).初始化roles的目录结构

(2).查看生成的目录结构

(3).列出已安装的roles

(4).查看指定roles的信息

4.使用roles部署的流程


一.Ansible中jinja2模板的使用

Jinja2 是一个强大的模板引擎,广泛用于 Ansible 中生成配置文件、脚本和其他文本内容。通过 Jinja2 模板,你可以动态地插入变量、执行条件逻辑和循环等操作,从而使 Playbook 更加灵活和可维护。

Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。通常jinja2模板文件的后缀为.j2

1.jinja2模板语法

(1).template模块

template模块与copy模块的用法十分类似,只是更多用于jinja2模板的渲染,也就是模板文件中可以引用变量,实现对不同主机有定制化的配置。

copy模块与template模块的区别
  1. copy模块不替代参数,template模块替代参数
  2. template的参数几乎与copy的参数完全相同
template模块常用参数

参数

解析

src

指定本地jinja2模板文件的位置

dest

指定目标远程主机路径

backup

指定是否备份,默认值no

mode

设置权限

user

设置用户

group

设置用户组

(2).基础语法

  1. Playbook文件使用template模块
  2. 模板文件里面变量使用 {{ 名称 }} ,比如自定义变量或者使用facts变量
  3. {{ }}也可以使用表达式,比如{{ 3+5 }},{{ 3 in [1,2,3,4,5] - }}

说明:{{}}中的表达式其实就是python中的表达式,可以包括比较运算,算数运算,逻辑运算,成员运行。

该模板支持:

字符串:使用单引号或双引号;

  数字:整数,浮点数;

  列表:[item1, item2, ...]

  元组:(item1, item2, ...)

  字典:{key1:value1, key2:value2, ...}

  布尔型:true/false

  算术运算:

    +, -, *, /, //, %, **

  比较操作:

    ==, !=, >, >=, <, <=

  逻辑运算:

    and, or, not

模板通常都是通过引用变量来运行的

(3).插入变量

创建jinja2模板文件

首先,需要创建一个包含Jinja2模板的文件。这个文件通常包含要插入变量或表达式的位置。可以在文件中使用{{ }}来包裹变量或表达式。

例如创建一个名为template.j2的模板文件:

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

Servername {{ ansible_fqdn }}

Listen {{ port }}

activate {{ service }}

在playbook中使用模板

在 Ansible Playbook中,可以使用template模块来加载模板文件并将变量传递给它。

示例playbook:

[root@server ~]# vi jinja.yml

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    port: 80

    service: nginx

  tasks:

    - name:

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

在这个示例中,我们使用了template模块,指定了模板文件的源 (src) 和目标 (dest)。我们还传递了变量ansible_fqdn、port 和 service,这些变量会在模板中替换{{ }}中的相应位置

运行playbook

运行上述Playbook,Ansible将使用模板文件生成 /root/myapp.conf 配置文件,并将模板中的{{ }}替换为变量的值。

[root@server ~]# ansible-playbook jinja.yml

[WARNING]: Found variable using reserved name: port

PLAY [use jinja2] ************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************

ok: [192.168.77.172]

TASK [template] **************************************************************************************************************************

changed: [192.168.77.172]

PLAY RECAP *******************************************************************************************************************************

192.168.77.172             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@server ~]# ansible host1 -m shell -a "cat /root/myapp.conf"

192.168.77.172 | CHANGED | rc=0 >>

Servername host1

Listen 80

activate nginx

我们能看到变量都被替换成了变量的值,其中我们在playbook中定义了port和service的值,内置变量ansible_fqdn并没有定义但是也被替换成了变量的值,所以在模板中使用的内置变量不需要在playbook中定义变量。

(4).流程控制

条件判断

使用 {% if %} 语句可以实现条件逻辑。

格式:

# 条件判断

{% if 表达式 %}

       执行内容

{% else %}

       执行内容

{% endif %}

示例:

jinja2模板文件

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

{% if user.is_admin %}

    <p>Welcome, Admin!</p>

{% else %}

    <p>Welcome, User!</p>

{% endif %}

假设当user.is_admin为ture时,则输出的结果为:

[root@server ~]# vi jinja.yml

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    user:

      name: root

      is_admin: ture

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

[root@server ~]# ansible-playbook jinja.yml

PLAY [use jinja2] ************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************

ok: [192.168.77.172]

TASK [use jinja2 touch file] *************************************************************************************************************

changed: [192.168.77.172]

PLAY RECAP *******************************************************************************************************************************

192.168.77.172             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@server ~]# ansible host1 -m shell -a "cat /root/myapp.conf"

192.168.77.172 | CHANGED | rc=0 >>

    <p>Welcome, Admin!</p>

当user.is_admin为no时,则输出的结果为:

多条件判断
格式:

# 多条件判断

{% if 表达式 %}

       执行内容

{% elif 表达式 %}

       执行内容

{% else %}

       执行内容

{% endif %}

示例:

jinja2模板文件

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

{% if user.age >= 18 %}

    This man is an adult

{% elif user.age >= 6 and user.age < 18 %}

    This man is an teenager

{% else %}

    this man is an toddler

{% endif %}

假设当user.age为15时,则输出的结果为:

[root@server ~]# vi jinja.yml

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    user:

      name: root

      age: 15

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

[root@server ~]# ansible-playbook jinja.yml

PLAY [use jinja2] ************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************

ok: [192.168.77.172]

TASK [use jinja2 touch file] *************************************************************************************************************

changed: [192.168.77.172]

PLAY RECAP *******************************************************************************************************************************

192.168.77.172             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@server ~]# ansible host1 -m shell -a "cat /root/myapp.conf"

192.168.77.172 | CHANGED | rc=0 >>

    This man is an teenager

循环表达式

使用 {% for %} 语句可以遍历列表或字典:

格式:

{% for i in 表达式 %}

       执行内容

{% endfor %}

示例:

jinja2模板文件

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

{% for i in items %}

    {{ i }}

{% endfor %}

playbook:

[root@server ~]# vi jinja.yml

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    items:

      - apple

      - banana

      - cherry

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

执行:

字典循环

对于字典,可以同时访问键和值

示例:

Jinja2模板文件

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

{% for username, details in user_details.items() %}

User: {{ username }}

Name: {{ details.name }}

Age: {{ details.age }}

{% endfor %}

playbook:

[root@server ~]# vi jinja.yml

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    user_details:

      user1:

        name: root

        age: 15

      user2:

        name: qiu

        age: 20

      user3:

        name: tutu

        age: 18

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

执行:

(5).过滤器

Jinja2还支持过滤器,可以使用过滤器来对变量进行操作。

常见的过滤器包括:

  1. upper:将字符串转换为大写。
  2. lower:将字符串转换为小写。
  3. title:将字符串的每个单词首字母大写。
  4. trim:去除字符串两端的空白字符。
  5. default:如果变量未定义,则使用默认值。
  6. join:将列表中的元素连接成一个字符串,指定分隔符。
  7. first 和 last:获取列表的第一个或最后一个元素。
  8. length:返回字符串或列表的长度。
  9. sort:对列表进行排序。
  10. dictsort:对字典进行排序(按键或值)。
  11. int 和 float:将字符串转换为整数或浮点数。
示例:将字符串转换为大写

模板文件

[root@server ~]# cat template.j2

welcome to {{ city | upper }}

playbook:

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    city: shenyang

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

执行:

(6).宏定义

宏类似于shell脚本中的函数,可以在模板中重复使用

示例:

假设你有一个包含用户信息的列表,并希望在模板中使用宏来生成每个用户的详细信息。

Jinja2模板文件:

[root@server ~]# vi template.j2

[root@server ~]# cat template.j2

{% macro user_info(user) %}                                #定义宏

name: {{ user.name }}

age: {{ user.age }}

{% endmacro %}

{% for user in users %}                            #定义循环

{{ user_info(user) }}                               #调用宏

{% endfor %}

Playbook:

[root@server ~]# cat jinja.yml

---

- name: use jinja2

  hosts: host1

  vars:

    users:

      - name: qiu

        age: 20

      - name: tutu

        age: 18

      - name: root

        age: 30

  tasks:

    - name: use jinja2 touch file

      template:

        src: /root/template.j2

        dest: /root/myapp.conf

执行:

(7).其他模板

Jinja2还支持其他控制结构,如{% include %}用于包含其他模板文件。

请注意,Jinja2语法和功能非常强大,支持许多高级用例,例如宏、继承、自定义过滤器等。要更深入地了解Jinja2模板的流程控制和功能,请查看Jinja2的官方文档。在Ansible中,可以将这些模板用于生成配置文件、编排任务等,以满足不同的需求和环境。

二.Ansible中的Roles角色管理

1.roles模块介绍

在roles中能够根据层次型结构自动装载变量文件、task以及handlers等。 简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中、并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中、但也可以是用于构建守护进程等场景中。

其主要作用有以下几点:

  1. 模块化任务和变量管理:允许将相关任务、处理程序、变量和模板等组织到一个独立的角色中,以便更好地管理和维护代码。
  2. 重复使用:角色允许将常见的任务和功能打包到可重用的单元中,可以在不同的 Playbook 中多次引用,提高了代码的重用性。
  3. 结构化组织:角色允许按照应用程序的不同组件或功能模块来组织任务,使代码更易于理解和维护。
  4. 简化playbook:通过将复杂的任务拆分成多个角色,可以使playbook 更为清晰简洁,提高代码的可读性和可维护性
  5. 自动化部署:角色可以包含特定应用程序或服务的安装、配置和部署等任务,简化了自动化部署过程

2.roles的目录结构

创建一个角色目录,用于演示:

[root@server ~]# mkdir -pv /etc/ansible/roles/{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}

查看roles的目录结构:

[root@server ~]# tree /etc/ansible/roles/

没有tree命令的安装tree命令

yum -y install tree

目录解析:

  1. /etc/ansible/roles/:存放roles的文件路径
  2. httpd:存放apached服务的yml文件
  3. mysql:存放mysql服务的yml文件
  4. nginx:存放nginx服务的yml文件
  5. default:此目录至少应该有一个名为main.yml的文件,用于设定默认变量
  6. files:存储由copy或者script等模块调用的文件或者脚本
  7. handlers:此目录中至少应该有一个名为main.yml的文件,用于定义各个handler;其他文件需要由main.yml进行包含调用
  8. meta:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定以及依赖关系,其他文件需要由main.yml进行包含调用
  9. tasks:此目录中至少应该有一个名为main.yml的文件,用于定义各个task;其他文件需要由main.yml进行包含调用
  10. templates:存储由templates模块调用的模板文件
  11. vars:此目录至少应该有一个名为main,yml的文件,用于定义各个variable;其他的文件需要由main.yml进行包含调用

3.ansible-galaxy命令

ansible-galaxy命令用于管理roles,同时也可以在 galaxy.ansible.com 上下载别人写好的roles。

(1).初始化roles的目录结构

[root@server roles]# ansible-galaxy init /etc/ansible/roles/webserver

将在当前目录下创建一个名为 webserver 的新目录,并填充标准的角色结构。

(2).查看生成的目录结构

执行上述命令后,你可以使用 tree 或 ls -R 查看生成的目录结构。典型的角色目录结构如下:

[root@server roles]# tree /etc/ansible/roles/webserver

/etc/ansible/roles/webserver

├── defaults

│   └── main.yml

├── files

├── handlers

│   └── main.yml

├── meta

│   └── main.yml

├── README.md

├── tasks

│   └── main.yml

├── templates

├── tests

│   ├── inventory

│   └── test.yml

└── vars

    └── main.yml

8 directories, 8 files

(3).列出已安装的roles

[root@server roles]# ansible-galaxy list

能看到我们刚才创建的webserver

(4).查看指定roles的信息

[root@server roles]# ansible-galaxy info webserver

能够查看到webserver的信息

4.使用roles部署的流程

定义配置文件 --> 定义jinja2模板,生成配置文件用 --> 定义变量 --> 定义触发(通知已定义在配置文件中) --> 定义roles的yml文件

检查yml语法 --> 执行roles.yml文件 --> 查看服务启动状态

 至此ansible-jinja2模板和roles角色管理的使用就结束了,接下来还会有一期ansible的运维实战,尽请期待吧!


网站公告

今日签到

点亮在社区的每一天
去签到