写点什么

ansible template

作者:ghostwritten
  • 2022 年 5 月 10 日
  • 本文字数:3115 字

    阅读完需:约 10 分钟

ansible template

1. 简介

template 模块会在 ansible 控制机中对模板文件进行渲染,最终生成各个主机对应的配置文件,然后拷贝到远程主机的指定位置中。

2. 参数

  • owner: 指定最终生成的文件拷贝到远程主机后的属主。

  • group: 指定最终生成的文件拷贝到远程主机后的属组。

  • mode:指定最终生成的文件拷贝到远程主机后的权限,如果你想将权限设置为”rw-r–r–“,则可以使用 mode=0644 表示,如果你想要在 user 对应的权限位上添加执行权限,则可以使用 mode=u+x 表示。


除了上述参数,还有如下参数也很常用


  • force: 远程主机的目标路径中已经存在同名文件,并且与最终生成的文件内容不同时,是否强制覆盖,可选值有 yes 和 no,默认值为 yes,表示覆盖,如果设置为 no,则不会执行覆盖拷贝操作,远程主机中的文件保持不变。

  • backup:当远程主机的目标路径中已经存在同名文件,并且与最终生成的文件内容不同时,是否对远程主机的文件进行备份,可选值有 yes 和 no,当设置为 yes 时,会先备份远程主机中的文件,然后再将最终生成的文件拷贝到远程主机。

3. 示例

3.1 使用 template 模块在 jinja2 中引用变量,先来目录结构树

[root@master ansible]# tree


.├── ansible.cfg├── hosts├── roles│   └── temp│       ├── tasks│       │   └── main.yaml│       ├── templates│       │   ├── test_if.j2│       │   └── test.j2│       └── vars│           └── main.yaml└── work_dir    ├── copy_configfile.retry    └── copy_configfile.yaml
复制代码


打开定义好的变量:


[root@master ansible]# cat roles/temp/vars/main.yaml master_ip: 192.168.101.14master_hostname: masternode1_ip: 192.168.101.15node1_hostname: node1
复制代码


打开 hosts 文件查看节点信息:


[root@master ansible]# egrep -v "^#|^$" hosts [nodes]192.168.101.14 192.168.101.15
复制代码


现在通过定义好的变量在 templates 目录下创建 j2 文件:


[root@master ansible]# cat roles/temp/templates/test.j2 ExecStart=/usr/local/bin/etcd --name {{ master_hostname }} --initial-advertise-peer-urls http://{{ master_ip }}:2380
复制代码


查看 tasks 主任务定义:


[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes  template:    src: test.j2    dest: /tmp/test.conf
复制代码


查看工作目录下面的执行 yaml:


[root@master ansible]# cat work_dir/copy_configfile.yaml - hosts: nodes  remote_user: root  roles:     - temp
复制代码


在 tasks 目录下面的 main.yaml 定义使用了 template 模块,调用 templates 目录下面的 test.j2 文件


执行:


[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
复制代码


然后在两个节点查看:


[root@master ~]# cat /tmp/test.conf     ExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380[root@node1 ~]# cat /tmp/test.confExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380
复制代码


可以看见在各个节点的 tem 目录下面的文件都用变量替换了。

3.2 使用 template 模块调用的 j2 文件使用{% if %} {% endif %}进行控制:

[root@master ansible]# cat roles/temp/templates/test_if.j2 {% if ansible_hostname == master_hostname %}ExecStart=/usr/local/bin/etcd --name {{ master_hostname }} --initial-advertise-peer-urls http://{{ master_ip }}:2380{% elif ansible_hostname == node1_hostname %}ExecStart=/usr/local/bin/etcd --name {{ node1_hostname }} --initial-advertise-peer-urls http://{{ node1_ip }}:2380{% endif %}
复制代码


在上面中使用 if 进行了判断,如果ansible_hostname变量与定义的master_hostname变量值相等,那么将此文件 copy 到节点上就使用条件 1,而过不满足条件 1 那么执行条件 2


ansible_hostname这个变量是 setup 模块中的值,是节点的固定值。


[root@master ~]# ansible all -m setup -a "filter=ansible_hostname"192.168.101.15 | SUCCESS => {    "ansible_facts": {        "ansible_hostname": "node1"    },     "changed": false,     "failed": false}192.168.101.14 | SUCCESS => {    "ansible_facts": {        "ansible_hostname": "master"    },     "changed": false,     "failed": false}
复制代码


现在查看 tasks 下面的文件:


[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes  template:    src: test_if.j2    dest: /tmp/test.conf
复制代码


将上面的 test.j2 改为了 if 条件的 j2,然后执行:


[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
复制代码


查看各节点生成的文件内容:


[root@master ~]# cat /tmp/test.conf ExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380[root@node1 ~]# cat /tmp/test.confExecStart=/usr/local/bin/etcd --name node1 --initial-advertise-peer-urls http://192.168.101.15:2380
复制代码


可以看见生成的文件内容不一样,于是这样就可以将节点的不同内容进行分离开了


当然还可以使用另外的方式隔离节点的不同:


ExecStart=/usr/local/bin/etcd --name {{ ansible_hostname }} --initial-advertise-peer-urls http://{{ ansible_ens33.ipv4.address }}:2380
复制代码


因为各个节点的 ansible_hostname 和 ip 都是固定的所以也可以根据上面进行区分不同(不过这种方式限制了一定的范围)

3.3 使用 template 模块调用 j2 文件使用 for 循环:

创建jinja关于 for 的文件:


 [root@master ansible]# cat roles/temp/templates/test_for.j2 {% for i in range(1,10) %}test{{ i }}{% endfor %}
复制代码


[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes  template:    src: test_for.j2    dest: /tmp/test.conf
复制代码


执行该角色:


[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
复制代码


验证两节点的文件内容:


[root@master ~]# cat /tmp/test.conf test1test2test3test4test5test6test7test8test9
复制代码


[root@node1 ~]# cat /tmp/test.conf test1test2test3test4test5test6test7test8test9
复制代码

3.4 使用default()默认值

当我们定义了变量的值时,采用变量的值,当我们没有定义变量的值时,那么使用默认给定的值:


首先查看定义的变量:


[root@master ansible]# cat roles/temp/vars/main.yaml master_ip: 192.168.101.14master_hostname: masternode1_ip: 192.168.101.15node1_hostname: node1
复制代码


然后查看 jinja2 的文件:


[root@master ansible]# cat roles/temp/templates/test_default.j2 Listen: {{ server_port|default(80) }}
复制代码


可以看见并没有定义 server_port 这个变量


查看 tasks 文件:


[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes  template:    src: test_default.j2    dest: /tmp/test.conf
复制代码


执行完成后,查看文件内容:


[root@master ~]# cat /tmp/test.conf Listen: 80
复制代码


现在向 vars/main.yaml 中定义 server_port 变量,并给定值:


[root@master ansible]# cat roles/temp/vars/main.yaml    master_ip: 192.168.101.14master_hostname: masternode1_ip: 192.168.101.15node1_hostname: node1server_port: 8080
复制代码


再次执行,然后查看文件内容:


[root@master ~]# cat /tmp/test.conf Listen: 8080
复制代码


可以看见使用了定义的值.


发布于: 刚刚阅读数: 2
用户头像

ghostwritten

关注

还未添加个人签名 2018.11.14 加入

虚心好学,勤奋努力,为中华之崛起而读书。

评论

发布
暂无评论
ansible template_ansible_ghostwritten_InfoQ写作社区