tnblog
首页
视频
资源
登录

Ansible Playbook的用法(变量与template)

9290人阅读 2021/4/3 18:52 总访问:3724662 评论:1 收藏:0 手机
分类: Ansible

ansible

Ansible Playbook的用法(变量与template)

使用变量


变量名:仅能由字母、数字和下划线组成,且只能以字母开头。
我们可以通过setup模块查看远程系统中的变量,都可以直接调用。

setup模块示例

  1. # 获取远程主机的所有环境变量
  2. ansible all -m setup
  3. # 如果只需要看部分的,如只查看有address的我们可以用filter参数进行模糊匹配查询
  4. ansible all -m setup -a 'filter=*address*'
  5. # 关于该模块更多参数请参考
  6. ansible-doc -s setup


通过过滤查看ipaddress4

在playbook中定义变量(外部赋值)


这里我们创建file3.yaml文件并以安装httpdvsftpd两个包举例

  1. ---
  2. - hosts: webserver
  3. remote_user: root
  4. tasks:
  5. - name: install {{ pkname1 }} package
  6. yum: name={{ pkname1 }}
  7. - name: install {{ pkname2 }} package
  8. yum: name={{ pkname2 }}

注意在定义变量名时,要以两个大括号包着,并且变量前后要有一个空格。


然后我们通过-e参数进行赋值,执行测试一下

  1. # 这里传入变量参数级别最高
  2. ansible-playbook -e pkname1=httpd -e pkname2=vsftpd file3.yaml
  3. # 也可以这样
  4. ansible-playbook -e 'pkname1=httpd pkname2=vsftpd' file3.yaml

在playbook中定义变量(内部赋值)


根据上面的示例,我们可以直接在内部进行赋值。(这里我就不尝试了)

  1. ---
  2. - hosts: webserver
  3. remote_user: root
  4. vars:
  5. - pkname1: httpd
  6. - pkname2: vsftpd
  7. tasks:
  8. - name: install {{ pkname1 }} package
  9. yum: name={{ pkname1 }}
  10. - name: install {{ pkname2 }} package
  11. yum: name={{ pkname2 }}

配置文件中定义变量与运用


我们知道配置文件的位置在/etc/ansible/hosts,我们可以针对不同的ip地址定义不同的值比如,我这里定义一个my_host_last_number变量,修改/etc/ansible/hosts

  1. [webserver]
  2. 10.211.55.5 my_host_last_number=5
  3. 10.211.55.6 my_host_last_number=6
  4. [dbserver]
  5. 10.211.55.5


然后我们创建一个file4.yaml文件的一个脚本,里面将变量值复制到my_number文件里面

  1. ---
  2. - hosts: webserver
  3. remote_user: root
  4. tasks:
  5. - name: Create Number File
  6. shell: echo '{{ my_host_last_number }}' > my_number


然后我们执行file4.yaml脚本,先测试在执行。

  1. # 测试
  2. ansible-playbook -C file4.yaml
  3. # 执行
  4. ansible-playbook file4.yaml
  5. # 获取执行结果
  6. ansible all -a 'cat my_number'


我们也可以通过指定组进行设置变量,格式为[组名:vars],然后在下面定义变量。然后我们修改一下file4.yaml进行执行

  1. [webserver]
  2. 10.211.55.5 my_host_last_number=5
  3. 10.211.55.6 my_host_last_number=6
  4. [webserver:vars]
  5. mygroup=webserver
  6. [dbserver]
  7. 10.211.55.5
  1. ---
  2. - hosts: webserver
  3. remote_user: root
  4. tasks:
  5. - name: Create Number File
  6. shell: echo '{{ my_host_last_number }}' > my_number
  7. - name: Create Group name
  8. shell: echo '{{ mygroup }}' > my_number
  1. ansible-playbook file4.yaml
  2. ansible all -a 'cat my_number'

普通变量:主机组中主机单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有主机定义统一变量
命令优先级最高

添加自定义变量文件


创建自定义vars.yml环境变量的文件。

  1. # cat vars.yml
  2. xx: hello
  3. hi: io


创建var.yml文件,并通过vars_files属性指定环境变量配置文件的路径

  1. ---
  2. - hosts: webserver
  3. remote_user: root
  4. vars_files:
  5. - vars.yml
  6. tasks:
  7. - name: XX Write
  8. shell: echo '{{ xx }}' > my_number


然后我们执行一下,查看是否将xx配置变量的hello值覆盖到my_number文件中

  1. ansible-playbook -C var.yml
  2. ansible-playbook var.yml
  3. # 检查一下
  4. ansible all -m shell -a 'cat my_number'

注意:这里的vars_files属性最好还是指定为绝对路径。

jinja2语法

jinja2介绍


jinja2模板中使用 {{ }} 语法表示一个变量,它是一种特殊的占位符。当利用jinja2进行渲染的时候,它会把这些特殊的占位符进行填充/替换,jinja2支持python中所有的Python数据类型比如列表、字段、对象等。

Jinja2算术运算


Jinja 允许你用计算值。这在模板中很少用到,但为了完整性允许其存在
支持下面的运算符

+:把两个对象加到一起。
通常对象是素质,但是如果两者是字符串或列表,你可以用这 种方式来衔接它们。
无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 {{ 1 + 1 }} 等于 2
-:用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1
/:对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 {{ 0.5 }}
//:对两个数做除法,返回整数商。 {{ 20 // 7 }} 等于 2
%:计算整数除法的余数。 {{ 11 % 7 }} 等于 4
*:用右边的数乘左边的操作数。 {{ 2 2 }} 会返回 4 。
也可以用于重 复一个字符串多次。{{ ‘=’
80 }} 会打印 80 个等号的横条
**:取左操作数的右操作数次幂。 {{ 2**3 }} 会返回 8

比较操作符


== 比较两个对象是否相等
!= 比较两个对象是否不等
> 如果左边大于右边,返回 true
>= 如果左边大于等于右边,返回 true
< 如果左边小于右边,返回 true
<= 如果左边小于等于右边,返回 true

逻辑运算符


对于 if 语句,在 for 过滤或 if 表达式中,它可以用于联合多个表达式

and如果左操作数和右操作数同为真,返回 true
or如果左操作数和右操作数有一个为真,返回 true
not对一个表达式取反(见下)
(expr)表达式组 ['list', 'of', 'objects']:

Template 模块

Template模块的介绍


当对不同的机器有不同的配置设置时我们可以通过Template的方式设置配置模块。
也可以理解为根据模块文件动态生成对应的配置文件。

Template的注意事项


template文件必须存放于templates目录下,且命名为 .j2 结尾。

  1. # yaml/yml 文件需和templates目录平级,目录结构如下:
  2. ./
  3. ├── temnginx.yml
  4. └── templates
  5. └── nginx.conf.j2

示例同步nginx配置


我们首先在本地安装nginx,并复制相应的配置文件到templates目录下。
(一般都是需要先添加nginx源,如果未添加请参考:https://www.tnblog.net/hb/article/details/5843)

  1. yum install nginx
  2. # 查看配置
  3. cat /etc/nginx/nginx.conf


然后我们想通过不同的主机上cpu的个数去创建nginx的进程数乘2进行创建,将配置文件复制到templates目录下

  1. ansible all -m setup -a 'filter=*cpu*'
  2. ansible all -m setup -a 'filter=ansible_processor_vcpus'
  3. # 创建templates
  4. mkdir templates
  5. # 将配置文件复制到templates目录下
  6. cp /etc/nginx/nginx.conf templates/nginx.conf.j2
  7. # 修改nginx.conf.j2文件
  8. vim templates/nginx.conf.j2
  1. user nginx;
  2. worker_processes {{ ansible_processor_vcpus*2 }};
  3. error_log /var/log/nginx/error.log warn;
  4. pid /var/run/nginx.pid;
  5. events {
  6. worker_connections 1024;
  7. }
  8. http {
  9. include /etc/nginx/mime.types;
  10. default_type application/octet-stream;
  11. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  12. '$status $body_bytes_sent "$http_referer" '
  13. '"$http_user_agent" "$http_x_forwarded_for"';
  14. access_log /var/log/nginx/access.log main;
  15. sendfile on;
  16. #tcp_nopush on;
  17. keepalive_timeout 65;
  18. #gzip on;
  19. include /etc/nginx/conf.d/*.conf;
  20. }


先结束Apache服务器防止端口冲突,接下来我们来编辑nginx.yaml文件,接着检查并执行。最后访问一下nginx的页面。

  1. ansible all -m shell -a 'systemctl stop httpd'
  1. ---
  2. - hosts: all
  3. remote_user: root
  4. tasks:
  5. - name: install nginx package
  6. yum: name=nginx
  7. - name: nginx conf template
  8. template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  9. notify: restart nginx service
  10. - name: start service
  11. service: name=nginx state=started enabled=yes
  12. handlers:
  13. - name: restart nginx service
  14. service: name=nginx state=restarted

  1. ansible all -m shell -a 'curl 127.0.0.1'


如果我们想不受Apache默认启动的80端口影响的话,我们可以通过8拼接my_host_last_number属性形成新的端口,这里就是:85与86端口。然后我们通过cp /etc/nginx/conf.d/default.conf templates/default.conf.j2命令将默认配置移动至templates目录下。

  1. # cat /etc/ansible/hosts
  2. [webserver]
  3. 10.211.55.5 my_host_last_number=5
  4. 10.211.55.6 my_host_last_number=6
  5. [webserver:vars]
  6. mygroup=webserver
  7. [dbserver]
  8. 10.211.55.5
  1. # 编辑模版
  2. # cat templates/default.conf.j2
  3. server {
  4. listen 8{{ my_host_last_number }};
  5. server_name localhost;
  6. #charset koi8-r;
  7. #access_log /var/log/nginx/host.access.lo


接着我们修改nginx.yamlPlay文件,最后执行一下。

  1. ---
  2. - hosts: all
  3. remote_user: root
  4. tasks:
  5. - name: install nginx package
  6. yum: name=nginx
  7. - name: stop service
  8. service: name=nginx state=stopped
  9. ignore_errors: True
  10. - name: nginx default conf template
  11. template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf
  12. notify: restart nginx service
  13. - name: nginx conf template
  14. template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  15. notify: restart nginx service
  16. - name: start service
  17. service: name=nginx state=started enabled=yes
  18. handlers:
  19. - name: restart nginx service
  20. service: name=nginx state=restarted
  1. ansible-playbook nginx.yaml
  2. # 检查一下
  3. ansible all -m shell -a 'curl 127.0.0.1:8{{ my_host_last_number }}'

When的运用


当我们对不同操作系统的时候或对相同操作系统不同版本的时候,会做出不同的修改。所以when正是因为此操作而诞生的。

when的介绍


条件测试:如果需要根据变量、facts或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,通过when的语句实现,在task中使用,jinja2的语法格式。

when语句
在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法

示例


获取不同主机的系统环境版本变量,可以通过如下命令进行查询。

  1. ansible all -m setup -a 'filter=*distribution*'
  2. # 最后查看不同的系统版本时我们发现它是ansible_distribution_major_version
  3. ansible all -m setup -a 'filter=*distribution*'


接着我们可以只判断系统环境为Centos7的才执行。

  1. ---
  2. - hosts: all
  3. remote_user: root
  4. tasks:
  5. - name: install nginx package
  6. yum: name=nginx
  7. - name: stop service
  8. service: name=nginx state=stopped
  9. ignore_errors: True
  10. - name: nginx default conf template
  11. template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf
  12. when: ansible_distribution_major_version == "7"
  13. notify: restart nginx service
  14. - name: nginx conf template
  15. template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  16. when: ansible_distribution_major_version == "7"
  17. notify: restart nginx service
  18. - name: start service
  19. service: name=nginx state=started enabled=yes
  20. handlers:
  21. - name: restart nginx service
  22. service: name=nginx state=restarted

Jinja2配合Template的语法的运用

with_items介绍


迭代:当有需要重复性执行的任务时,可以使用迭代机制。

- 对迭代项的引用,固体变量名为 “item”
- 要在task中使用with_items给定要迭代的元素列表
- 列表格式:
字符串
字典

示例


先创建3个group组,再创建3个group组的用户。

  1. ---
  2. - hosts: all
  3. remote_user: root
  4. tasks:
  5. - name: add some groups
  6. group: name={{item}}
  7. when: ansible_distribution_major_version == "7"
  8. with_items:
  9. - g1
  10. - g2
  11. - g3
  12. - name: add some users
  13. user: name={{item.name}} group={{item.group}}
  14. with_items:
  15. - { name: 'user1', group: 'g1' }
  16. - { name: 'user2', group: 'g1' }
  17. - { name: 'user3', group: 'g3' }

循环语句


j2文件中使用for循环遍历Ansible的变量。首先我们定义testfor.yaml文件。再在for3.conf.j2文件中定义循环。

  1. ---
  2. - hosts: all
  3. remote_user: root
  4. vars:
  5. ports:
  6. - web1:
  7. port: 81
  8. name: web1
  9. rootdir: /data/web1
  10. - web2:
  11. port: 82
  12. name: web2
  13. rootdir: /data/web2
  14. - web3:
  15. port: 83
  16. name: web3
  17. rootdir: /data/web3
  18. tasks:
  19. - name: copy conf
  20. template: src=for3.conf.j2 dest=/data/for3.conf


然后在相对路径中,创建for3.conf.j2文件,并添加相关内容。最后执行命令。

  1. {% for p in ports %}
  2. server{
  3. listen {{ p.port }}
  4. servername {{ p.name }}
  5. documentroot {{ p.rootdir }}
  6. }
  7. {% endfor %}
  1. ansible-playbook -C testfor.yaml
  2. ansible-playbook testfor.yaml


验证一下

  1. ansible all -m shell -a 'cat /data/for3.conf'

判断语句


通过if条件语句判断值有没有被定义。

  1. ---
  2. - hosts: all
  3. remote_user: root
  4. vars:
  5. ports:
  6. - web1:
  7. port: 81
  8. #name: web1
  9. rootdir: /data/web1
  10. - web2:
  11. port: 82
  12. name: web2
  13. rootdir: /data/web2
  14. - web3:
  15. port: 83
  16. #name: web3
  17. rootdir: /data/web3
  18. tasks:
  19. - name: copy conf
  20. template: src=for3.conf.j2 dest=/data/for3.conf
  1. {% for p in ports %}
  2. server{
  3. listen {{ p.port }}
  4. {% if p.name is defined %}
  5. servername {{ p.name }}
  6. {% endif %}
  7. documentroot {{ p.rootdir }}
  8. }
  9. {% endfor %}


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

荔枝大娘

2021/4/9 9:11:26

第三百篇了 牛啊

Ansible Playbook的用法

Ansible Playbook的用法[TOC] Ansible-galaxy它可以连接 https://galaxy.ansible.com 下载相应的roles 相关命令# 列出...

WEBAPI报错:Attribute routes with the same name 'Get' must have the same template

是因为 asp.net core 中默认创建的 api controller 中的 Get(id) Action的属性都是[HttpGet(&quot;{id}&quot;, Name = &quo...

consul http api与Consul-template

consul的主要接口是RESTful HTTP API,该API可以用来增删查改nodes、services、checks、configguration。所有的endpoints主...

Elasticsearch Index template 和 Dynamic template

Elasticsearch Index Template和Dynamic Template[TOC] 什么是 Index Template 可以通过一定的规则去设定 Mappings 和 Se...

[Vue warn]: Failed to mount component: template or render function not defined

检查一下是不是根目录没有template标签,直接写view就会报错

模板对象-Jdbctemplate 01

一、案例、1、坐标&lt;dependencies&gt; &lt;!--mysql--&gt; &lt;dependency&gt; &lt;groupId&gt;mysql&lt;/groupId&gt;...
这一世以无限游戏为使命!
排名
2
文章
662
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术