【星海出品】ansible入门(三) 深入playbook

Ansible playbook常用到模板驱动jinja2
都是python编写的。Jinja2 需要至少 Python 2.4 版本来运行。

jinja2过滤器
Jinja2中的过滤器可以把一个模板表达式转换为另一个.Jinja2附带了很多这样的功能。

jinja2源码
https://github.com/pallets/jinja/blob/main/

基本 API 使用

>>> from jinja2 import Template
>>> template = Template('Hello {{ name }}!')
>>> template.render(name='John Doe')
u'Hello John Doe!'

通过创建一个 Template 的实例,你会得到一个新的模板对象,提供一 个名为 render() 的方法
该方法在有字典或关键字参数时调用 扩充模板。字典或关键字参数会被传递到模板,即模板“上下文”。

渲染一个html

from jinja2 import PackageLoader,Environment
env = Environment(loader=PackageLoader('python_project','templates'))    # 创建一个包加载器对 
#PackageLoader()的两个参数为:python包的名称,以及模板目录名称。
template = env.get_template('bast.html')    # 获取一个模板文件
template.render(name='daxin',age=18)   # 渲染

jinja2是如何直接使用过滤器? 只需要在变量后面使用管道(|)分割,多个过滤器可以链式调用,前一个过滤器的输出会作为后一个过滤器的输入。

{{ 'abc' | captialize  }}
# Abc

{{ 'abc' | upper  }}
# ABC

{{ 'hello world' | title  }}
# Hello World

{{ "hello world" | replace('world','daxin') | upper }}
# HELLO DAXIN

{{ 18.18 | round | int }}
# 18

对列表和字典进行递归,生成模板

    {% for user in users %}
  • {{ user.username|title }}
  • {% endfor %}
{% for key, value in my_dict.iteritems() %}
{{ key }}
{{ value}}
{% endfor %}

cat for-if.yml

        - hosts: myhosts
          remote_user: root
          vars:
            hosts:
              - {listen_port: 8080,web: nginx1,name: web1.fz.com}
              - {listen_port: 8081,web: nginx2,name: web2.fz.com}
              - {listen_port: 8082,web: nginx3}
          tasks:
            - name: for-if
              template: src=for-if.j2 dest=/root/for-if

cat templates/for-if.j2

        {% for host in hosts %}
        server{
                listen: {{host.listen_port}};
        {%if host.name is defined%}
                name: {{host.name}};
        {%endif%}
                web: {{host.web}};
        }
        {%endfor%}

#defined是找到的意思,也可以添加else

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

在vars.yml文件中定义变量

hi: hello
wd: world

编写playbook:

- hosts: myhosts
  remote_user: root
  vars_files:
   - vars.yml
  tasks:
   - name: create file
     file: name=/root/{{ hi }}-{{ wd }}.log state=touch

Ansible提供了notify指令和handlers功能。
如果在某个task中定义了notify指令,当Ansible在监控到该任务 changed=1时,会触发该notify指令所定义的handler,然后去执行handler。所谓handler,其实就是task

cat httpd.yml 
---
- name: play1
  hosts: all
  remote_user: root
  gather_facts: false
  
  tasks:
    - name: install httpd
      yum: name=httpd state=installed
    - name: copy httpd config
      copy: src=/etc/httpd/conf/httpd.conf  dest=/etc/httpd/conf/httpd.conf
      notify:
       - restart httpd
    - name: start httpd
      service: name=httpd state=started enabled=true
    
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。

ansible实现循环

[root@ansible-test1 ansible]# cat while.yml

hosts: testhost
user: root
tasks:
  name: change mode for files
  file: path=/tmp/{{ item }} mode=600
  with_items:
    1.txt
    2.txt
    3.txt

执行while.yml。
[root@ansible-test1 ansible]# ansible-playbook while.yml

#说明: with_items为循环的对象

ansible条件判断
when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行。

---
- hosts: mysql
- remote_user: root
  tasks:
    - name: "shutdown C6 systems"
      command: /sbin/shutdown -t now
      when: (ansible_distribution == CentOS and ansible_distribution_major_version == "6") or
            (ansible_distribution == CentOS and ansible_distribution_major_version == "7")

你可能感兴趣的:(ansible)