1、Jinja2模版的基本语法
模板的表达式都是包含在他要分隔符 "{{}}" 内的
控制的语句都是包含在分隔符 "{% %}" 内的
"{% -%}" 和 "{% %}" 的写法区别,暂时不知
模板支持注释,都是包含在分隔符 '{# #}' 内,支持块注释
调用变量计算
{{2+2}}
判断
{{1 in {{1,2,3}}
2、Jinja2模版控制语句
{% if name == '诗仙' %} 李白 {% elif name == '诗圣' %} 杜甫 {% elif name == '诗魔' %} 白居易 {% else %} 李贺 {% endif %}
3、Jinja2过滤器
变量可以通过过滤器修改,过滤器与变量用管道符号( | )分割,也可以用圆括号传递可选参数,多个过滤器可以链式调用,前一个过滤器的输出会被作业后一个过滤器的输入
例如:
加密一个字符串: {{'astr' | password_hash('sha512')}}
tasks: - shell: cat /some/path/to/file.json register: result - set_fact: myvar="{{ result.stdout | from_json }}"
从json字符串读取,其结果为json类型
{{ some_variable | from_json }}
在写 playbook
的时候发现了很多 task 都要重复引用某个相同的模块,比如一次启动10个服务,或者一次拷贝10个文件,如果按照传统的写法最少要写10次,这样会使得 playbook
很臃肿。
格式:
"item"
;task
中使用with_items
或loop
关键字给定要迭代的元素列表;实操:
方式1
cat loop.yml - hosts: web remote_user: root tasks: - name: Install Packages yum: name: "{{ item }}" state: present loop: - rsync - glances
有执行结果可知,glances安装成功,rsync没有改变是因为软件已经安装有了。
方式2:
cat loop1.yml - hosts: web remote_user: root vars: packages: - httpd - glances tasks: - name: Install Packages yum: name: "{{ packages }}" state: present
方式采用变量方方式,显示上不如loop直观
cat loop_service.yml - hosts: NginxWebs remote_user: root tasks: - name: Start Service service: name: "{{ item }}" state: started loop: - httpd - mariadb-server
注:此处将loop换成with_items也是一样
- hosts: web tasks: - name: Create Groups group: name: "{{ item }}" state: present loop: - group1 - group2 - group3 - name: Create Users user: name: "{{ item.user }}" group: "{{ item.group }}" uid: "{{ item.uid }}" state: present create_home: yes loop: - { user: user1,group: group1, uid: 2001 } - { user: user2,group: group2, uid: 2002 } - { user: user3,group: group3, uid: 2003 }
- hosts: web tasks: - name: Copy Configuer File template: src: "{{ item.src }}" dest: "{{ item.dest }}" owner: "{{ item.owner }}" group: "{{ item.group }}" mode: "{{ item.mode }}" loop: - { src: "/root/conf/nginx.conf.j2", dest: "/etc/nginx/nginx.conf", owner: "root", group: "root", mode: "0644" } - { src: "/root/conf/example.com.conf.j2", dest: "/etc/nginx/conf.d/example.con.conf", owner: "root", group: "root", mode: "0644" } - { src: "/root/file/index.html", dest: "/data/nginx/example/index.html", owner: "nginx", group: "nginx", mode: 0644 }
注意:应用template时用法和copy一致,但是此处dest目标路径需要自己提前创建好、属主(组)都要有
copy是这样介绍的:
= dest Remote absolute path where the file should be copied to. If `src' is a directory, this must be a directory too. #如果 `src' 是一个目录,dest也必须是一个目录。 If `dest' is a non-existent path and if either `dest' ends with "/" or `src' is a directory, `dest' is created. #如果 `dest' 是不存在的路径,并且如果 `dest' 以“/”结尾或 `src' 是目录,则创建 `dest'。 If `dest' is a relative path, the starting directory is determined by the remote host. #如果“dest”是相对路径,则起始目录由远程主机确定。 If `src' and `dest' are files, the parent directory of `dest' is not created and the task fails if it does not already exist. #如果 `src' 和 `dest' 是文件,则不创建 `dest' 的父目录,如果不存在则任务失败。 type: path
cat loop6.yml --- - hosts: web remote_user: root gather_facts: no tasks: - file: state: directory path: "/testdir/{{item.0}}/{{item.1}}" with_nested: - [ a, b, c ] - [ test1, test2 ]
效果
tree /testdir/ /testdir/ |-- a | |-- test1 | `-- test2 |-- b | |-- test1 | `-- test2 `-- c |-- test1 `-- test2 9 directories, 0 files
--- - hosts: web vars: users: alice: name: Alice Appleworth telephone: 123-456-7890 bob: name: Bob Bananarama telephone: 987-654-3210 tasks: - name: Print phone records debug: msg: "User {{ item.key }} is {{ item.value.name }} {{ item.value.telephone }}" with_dict: "{{users}}"
cat loop7.yml --- - hosts: web tasks: - copy: src: "{{ item }}" dest: /etc/fooapp/ owner: root mode: 600 with_fileglob: - /playbooks/files/fooapp/*
效果
1、
ansible之when条件判断 - 一介凡人-DGP - 博客园 (cnblogs.com)
ansible playbooks loop循环 - nineep - 博客园 (cnblogs.com)
Ansible——循环与条件判断 - 阿不思布丁 - 博客园 (cnblogs.com)
Ansible 小手册系列 十三(Jinja2) - 简书 (jianshu.com)
Ansible 小手册系列 十四(条件判断和循环) - 简书 (jianshu.com)
start.yml
shell: 'docker run --restart={{ docker.restart }} -d \ --name {{ _container_name }} \ --log-opt max-size={{ docker.log.max_size | default("300m") }} \ --log-opt max-file={{ docker.log.max_file | default("2") }} \ -p {{ frontend.stolon.postgresql.listen_port }} \ {% if docker.search_domain is defined and docker.search_domain is not none and docker.search_domain != "" %} --dns-search={{ docker.search_domain }} \ {% endif %} {% if docker.dns is defined and docker.dns is not none and docker.dns != "" %} --dns={{ docker.dns }} \ --shm-size=1g \ {% endif %} -v {{ frontend.stolon.local_dir | default(_workspace_local_dir ~ "/stolon") }}/data:/var/lib/postgresql/data \ -e POSTGRES_DATABASE={{ frontend.stolon.postgres_db }} \ -e POSTGRES_USER={{ frontend.stolon.postgres_user }} \ -e POSTGRES_PASSWORD={{ frontend.stolon.postgres_password }} \ -e SERVICE_NAME=stolon-proxy \ {{ _image_registry_prefix }}{{ frontend.stolon.postgresql.image }}'