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


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

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

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

    基本 API 使用

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

    通过创建一个 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)   # 渲染
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

      {% for user in users %}
    • {{ user.username|title }}
    • {% endfor %}
    {% for key, value in my_dict.iteritems() %}
    {{ key }}
    {{ value}}
    {% endfor %}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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%}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    {% if variable is defined %}
        value of variable: {{ variable }}
    {% else %}
        variable is not defined
    {% endif %}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在vars.yml文件中定义变量

    hi: hello
    wd: world
    
    • 1
    • 2

    编写playbook:

    - hosts: myhosts
      remote_user: root
      vars_files:
       - vars.yml
      tasks:
       - name: create file
         file: name=/root/{{ hi }}-{{ wd }}.log state=touch
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    #说明: 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")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    role风格的入口

    - hosts: 192.168.0.2
      remote_user: root
      gather_facts: false
      roles:
       - nginx
    
    - hosts: test
      remote_user: root
      gather_facts: false
      roles:
       - mysql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果想要有区别的执行,而不是全部执行,可以加tag标记

    role风格的排版
    在这里插入图片描述

    仿写playbook,可参照其他作者的该文章
    https://www.bilibili.com/read/cv24358297/

  • 相关阅读:
    Postgresql顺滑升级步骤(11升级到14)
    20230527 K-均值聚类算法,由INSCODE AI创作助手进行生成
    nginx 如何根据IP做限流,以及 nginx 直接返回 json 格式数据
    【Java】数组的深浅拷贝问题(二维数组举例)(136)
    大一新生?职场新人?想买电脑该怎么选?
    RP-母版 流程图 发布和预览 团队项目
    闺蜜和我,我和闺蜜
    掌握Conda的艺术:精通channels管理
    《深度学习进阶 自然语言处理》第一章:神经网络的复习
    修改CentOS默认mail发件人名称
  • 原文地址:https://blog.csdn.net/weixin_41997073/article/details/133612655