• 014.Ansible Playbook Role 及调试


    一 role 简介

    在ansible中,role是将playbook分割为多个文件的主要机制,大大简化了复杂的playbook的编写,同时已与复用

    role各个目录的作用及可用文件

    • files:存放由copy或script等模块调用的文件
    • tempaltes:Jinja2模板文件
    • tasks:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表,些文件可以使用include包含其它的位于此目录中的task文件
    • handlers:至少包含一个main.yml文件,用于定义此角色用到的各handler,在handler中使用include包含的其他handler文件也应该位于此目录
    • vars:应当包含一个main.yml文件,用于定义此角色用到的变量,拥有比较高的优先级,仅次于命令行
    • meta:应当包含一个main.yml文件,用于定义此角色的特殊设定及依赖关系等
    • default:为当前角色设定默认变量时使用些目录,包含一个main.yml文件,变量的优先级最低

    二 创建role步骤

    1 创建以role命名的目录

    2 在role下创建一个任务目录,定义角色

    3 分别创建 defaults vars files templates tasks handlers meta tests的目录,用不到的目录,可以不创建,也可以创建空目录

    4 在playbook中调用各文件

    [root@node1 ansible]# cd roles/

    [root@node1 roles]# vim ../ansible.cfg

    roles_path    = /etc/ansible/roles

    [root@node1 roles]# mkdir systeminit

    [root@node1 systeminit]# mkdir defaults vars files templates tasks handlers meta tests

    [root@node1 systeminit]# touch {defaults,vars,files,templates,tasks,handlers,meta}/main.yml

    [root@node1 systeminit]# tree ./

    ./
    ├── defaults
    │   └── main.yml
    ├── files
    │   └── main.yml
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    │   └── main.yml
    ├── tests
    └── vars
        └── main.yml

    把前面tasks里面的文件,按照roles放到对应的位置,删掉多余的文件

    drwxr-xr-x 2 root root 41 May  2 20:12 files
    drwxr-xr-x 2 root root 42 May  2 20:13 handlers
    drwxr-xr-x 2 root root 85 May  2 20:13 tasks
    drwxr-xr-x 2 root root 22 May  2 19:56 templates
    [root@node1 systeminit]# tree ./
    ./
    ├── files
    │   └── resolv.conf
    ├── handlers
    │   ├── handlers.yml
    │   └── main.yml
    ├── tasks
    │   ├── dns.yml
    │   ├── host.yml
    │   ├── main.yml
    │   ├── nginx.yml
    │   └── ntp.yml
    └── templates
        └── main.yml

    开始调用个文件配置

    [root@node1 systeminit]# vim tasks/main.yml

    - include_tasks:
        file: host.yml
    - include_tasks:
        file: dns.yml
    #- include_tasks:
    #    file: ntp.yml

    [root@node1 systeminit]# vim handlers/main.yml

    - include_tasks:
        file: handlers.yml

    tasks文件中,默认情况下,src就是指向files下的文件,files可以省略

    [root@node1 systeminit]# vim tasks/dns.yml 

    - name: modify resolv.conf
      copy:
        src: resolv.conf
        dest: /etc/resolv.conf
    - name: /etc/resolvconf/base
      copy:
        src: resolv.conf
        dest: /etc/resolv.conf
      when: ansible_distribution == "Ubuntu"

    创建一个palybook.yml

    [root@node1 roles]# vim playbook.yml

    - hosts: demo2.example.com
      roles:
        - systeminit

    执行

    [root@node1 roles]# ansible-playbook playbook.yml

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com
    
    TASK [systeminit : modify num to 0] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : modify hostname] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com
    
    TASK [systeminit : modify resolv.conf] ************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : /etc/resolvconf/base] **********************************************************************************************************
    skipping: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 

    三 role中变量设置

    3.1 使用default定义变量

    [root@node1 systeminit]# vim defaults/main.yml

    testvars:
      users:
        bob:
          name: bob
          gender: male
        alice:
          name: alice
          gender: female

    [root@node1 systeminit]# vim tasks/host.yml

    - name: modify num to 0 
      set_fact:
        num: 0
    
    - name: modify hostname
      hostname:
        name: test.example.com
    
    - name: print testvars
      debug:
        msg: "{{ testvars }}"   

    执行

    [root@node1 roles]# ansible-playbook playbook.yml

    ok: [demo2.example.com] => {   #打印出了testvar的值
        "msg": {
            "users": {
                "alice": {
                    "gender": "female", 
                    "name": "alice"
                }, 
                "bob": {
                    "gender": "male", 
                    "name": "bob"
                }
            }
        }
    }

    3.2 使用命令行的变量

    [root@node1 roles]# ansible-playbook -e "{'testvars':'aaa'}"  playbook.yml

    TASK [systeminit : print testvars] ****************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "aaa"
    }

    3.3 在palybbok.yml文件直接定义变量

    [root@node1 roles]# vim playbook.yml

    - hosts: demo2.example.com
      roles:
        - role: systeminit 
          vars:
            testvars: bbbbtest

    [root@node1 roles]# ansible-playbook playbook.yml

    TASK [systeminit : print testvars] ****************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "bbbbtest"
    }

    创建第二个role

    [root@node1 roles]# mkdir -p nginx/{defaults,handlers,files,tasks}

    [root@node1 roles]# vim nginx/tasks/nginx.yml

    - name: install nginx
      yum:
        name:  nginx
        state: present
    #- name: mpdify nginx.conf
    #  template:
    #    src: templates/nginx.conf.j2
    #    dest: /etc/nginx/nginx.conf
    #  notify:  
    #    - restart nginx
    - name: start nginx
      systemd:
        name: nginx
        state: started
        enabled: yes
    
    - name: print testvars
      debug:
        msg: "{{ testvars }}"

    [root@node1 roles]# vim nginx/tasks/main.yml

    - include_tasks: 
        file: nginx.yml

    [root@node1 roles]# vim nginx/defaults/main.yml

    testvars:
      user:
        natasha:
          name: natasha
          gender: female

    [root@node1 roles]# vim playbook.yml 

    - hosts: demo2.example.com
      roles:
        - role: systeminit
          vars:
            testvars: bbbbtest
        - role: nginx

    [root@node1 roles]# ansible-playbook playbook.yml

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com
    
    TASK [systeminit : modify num to 0] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : modify hostname] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : print testvars] ****************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "bbbbtest"
    }
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com
    
    TASK [systeminit : modify resolv.conf] ************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : /etc/resolvconf/base] **********************************************************************************************************
    skipping: [demo2.example.com]
    
    TASK [nginx : include_tasks] **********************************************************************************************************************
    included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com
    
    TASK [nginx : install nginx] **********************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : start nginx] ************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : print testvars] *********************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "bbbbtest"
    }
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=11   changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

    这是因为在playbook.yml定义的变量都是全局的,优先级高于所有角色的default.yml定义的变量

    3.4 在var中定义自己的变量

    若要使nginx使用自己的变量,就把变量定义在vars的目录中

    [root@node1 roles]# mv nginx/defaults nginx/vars

    [root@node1 roles]# ansible-playbook playbook.yml

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com
    
    TASK [systeminit : modify num to 0] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : modify hostname] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : print testvars] ****************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "bbbbtest"
    }
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com
    
    TASK [systeminit : modify resolv.conf] ************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : /etc/resolvconf/base] **********************************************************************************************************
    skipping: [demo2.example.com]
    
    TASK [nginx : include_tasks] **********************************************************************************************************************
    included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com
    
    TASK [nginx : install nginx] **********************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : start nginx] ************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : print testvars] *********************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": {
            "user": {
                "natasha": {
                    "gender": "female", 
                    "name": "natasha"
                }
            }
        }
    }

    也可以定义到当前role中

    [root@node1 roles]# vim playbook.yml

    - hosts: demo2.example.com
      roles:
        - {role: systeminit,testvars: "bbbtest"}
        - role: nginx

    [root@node1 roles]# mv nginx/vars nginx/defaults

    [root@node1 roles]# ansible-playbook playbook.yml

    TASK [nginx : include_tasks] **********************************************************************************************************************
    included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com
    
    TASK [nginx : install nginx] **********************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : start nginx] ************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : print testvars] *********************************************************************************************************************
    ok: [demo2.example.com] => {  #nginx依然打印出自己的defaut的变量
        "msg": {
            "user": {
                "natasha": {
                    "gender": "female", 
                    "name": "natasha"
                }
            }
        }
    }

    引用role,也可以添加条件

    - hosts: webserver
      roles:
        - {role: some_role,when: "ansible_os_family ==  'Redhat' "}

    3.5 pre_tasks和post_tasks操作

    在执行一个role之前和之后,可以使用这两个实现  

    - name: deplay webserver
      hosts: webserver
      vars_files:
        - secrets.yml
      pre_tasks:
        - name: update yum cache
          yum: update_cache=yes
      roles:
        - role: apache
          database_host: {{ hostvars.db.ansible_eth0.ipv4.address }}
          domains:
            - example.com
            - www.example.com
      post_tasks:
        - name: print something
          shell: echo "The role have been update "

    3.6 role的依赖

    [root@node1 roles]# vim systeminit/tasks/pkgs.yml

    - name: install development tools
      yum :
        name: "{{ pkgs.name }}"

    引入:

    - include_tasks:
        file: host.yml
    
    - include_tasks:
        file: dns.yml
    
    - include_tasks:
        file: pkgs.yml
    
    #- include_tasks:
    #    file: ntp.yml

    设置变量

    [root@node1 roles]# mkdir systeminit/vars
    [root@node1 roles]# vim systeminit/vars/main.yml

    pkgs:
      name:
      - gcc
      - make
      - git

    在nginx定义依赖

    [root@node1 roles]# mkdir nginx/meta

    [root@node1 roles]# vim nginx/meta/main.yml

    dependencies:
      - role: systeminit

    [root@node1 roles]# vim playbook.yml 

    - hosts: demo2.example.com
      roles:
        - role: nginx

    [root@node1 roles]# ansible-playbook playbook.yml 

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/host.yml for demo2.example.com
    
    TASK [systeminit : modify num to 0] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : modify hostname] ***************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : print testvars] ****************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": {
            "users": {
                "alice": {
                    "gender": "female", 
                    "name": "alice"
                }, 
                "bob": {
                    "gender": "male", 
                    "name": "bob"
                }
            }
        }
    }
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/dns.yml for demo2.example.com
    
    TASK [systeminit : modify resolv.conf] ************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [systeminit : /etc/resolvconf/base] **********************************************************************************************************
    skipping: [demo2.example.com]
    
    TASK [systeminit : include_tasks] *****************************************************************************************************************
    included: /etc/ansible/roles/systeminit/tasks/pkgs.yml for demo2.example.com
    
    TASK [systeminit : install development tools] *****************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : include_tasks] **********************************************************************************************************************
    included: /etc/ansible/roles/nginx/tasks/nginx.yml for demo2.example.com
    
    TASK [nginx : install nginx] **********************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : start nginx] ************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [nginx : print testvars] *********************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": {
            "user": {
                "natasha": {
                    "gender": "female", 
                    "name": "natasha"
                }
            }
        }
    }
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=13   changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

    先执行systeminit,在执行nginx,是因为nginx依赖于systeminit执行

    四 社区版roles

    https://galaxy.ansible.com/

    https://galaxy.ansible.com/geerlingguy/nginx

    用这里就可以获取到作者已经写好的roles

    下载

    [root@node1 roles]# ansible-galaxy install geerlingguy.nginx

    - changing role geerlingguy.nginx from 2.7.0 to unspecified
    - downloading role 'nginx', owned by geerlingguy
    - downloading role from https://github.com/geerlingguy/ansible-role-nginx/archive/2.7.0.tar.gz
    - extracting geerlingguy.nginx to /root/.ansible/roles/geerlingguy.nginx
    - geerlingguy.nginx (2.7.0) was installed successfully

    [root@node1 roles]# ansible-galaxy --help

    usage: ansible-galaxy [-h] [--version] [-v] TYPE ...
    
    Perform various Role and Collection related operations.
    
    positional arguments:
      TYPE
        collection   Manage an Ansible Galaxy collection.
        role         Manage an Ansible Galaxy role.
    
    optional arguments:
      --version      show program's version number, config file location,
                     configured module search path, module location, executable
                     location and exit
      -h, --help     show this help message and exit
      -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                     debugging)
    [root@node1 roles]# 

    [root@node1 roles]# cp -r /root/.ansible/roles/geerlingguy.nginx  ./

    [root@node1 roles]# ls -l

    drwxr-xr-x 9 root root 177 May  2 21:55 geerlingguy.nginx
    drwxr-xr-x 7 root root  76 May  2 21:22 nginx
    -rw-r--r-- 1 root root  54 May  2 21:37 playbook.yml
    drwxr-xr-x 8 root root 113 May  2 21:18 systeminit

    [root@node1 roles]#  ansible-galaxy init apache

    [root@node1 roles]# ls -l

    drwxr-xr-x 10 root root 154 May  2 21:56 apache
    drwxr-xr-x  9 root root 177 May  2 21:55 geerlingguy.nginx
    drwxr-xr-x  7 root root  76 May  2 21:22 nginx
    -rw-r--r--  1 root root  54 May  2 21:37 playbook.yml
    drwxr-xr-x  8 root root 113 May  2 21:18 systeminit

    [root@node1 roles]# tree apache/

    apache/
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

    列出安装别人的role

    [root@node1 roles]# ansible-galaxy list

    # /root/.ansible/roles
    - geerlingguy.nginx, 2.7.0
    # /usr/share/ansible/roles
    # /etc/ansible/roles
    - nginx, (unknown version)
    - geerlingguy.nginx, 2.7.0
    - apache, (unknown version)

    查看一个role的完整信息

    [root@node1 roles]# ansible-galaxy info geerlingguy.nginx

    Role: geerlingguy.nginx/
            description: Nginx installation for Linux, FreeBSD and OpenBSD.
            active: True
            commit: 87ecb1127f62c5c2f9c901f44594c5445aeb75d4
            commit_message: Add probot/stale configuration to repository for stale issues.
            commit_url: https://api.github.com/repos/geerlingguy/ansible-role-nginx/git/commits/87ecb1127f62c5c2f9c901f44594c5445aeb75d4
            company: Midwestern Mac, LLC
            created: 2014-03-07T14:57:09.348940Z
            dependencies: []
            download_count: 4130883
            forks_count: 357
            galaxy_info:
                    author: geerlingguy
                    company: Midwestern Mac, LLC
                    galaxy_tags: ['development', 'web', 'nginx', 'reverse', 'proxy', 'load', 'balancer']
                    license: license (BSD, MIT)
                    min_ansible_version: 2.4
                    platforms: [{'name': 'EL', 'versions': [6, 7]}, {'name': 'D .......

    移除

    [root@node1 roles]# ansible-galaxy remove apache
    - apache is not installed, skipping.

    五 调试ansible

    1 运行前检查

    当我们在运行ansible-playbook时,使用--check选项时,将不会对被控端做出任何更改,而是通过模拟的方式 执行所有的tasks,以用于检查playbook运行的的状态

    ansible-playbook with_items.yml --check

    2.再运行palybook时,使用--diff选项配合--check,可以用于检查本次执行playbook,相较上一次产生了那些改变

    [root@node1 ansible]# ansible-playbook  --check --diff  with_items.yml 
    [root@node1 ansible]# ansible-playbook  --check --diff --limit demo2.example.com  with_items.yml
    [root@node1 ansible]# ansible-playbook  --syntax-check  with_items.yml 

    3 有时候,我们在检测模式下,运行play时,希望某个play总是运行,可以使用always_run

    tasks:
      - name: this task is run even is check mode
        command: /something/to/run/  --even-in-check-mode
        always_run: yes

    如果一个tasks包含有always_run和when,当when为false时,如果always_run时true,任务依然会执行

    debug调试:

    - name: install nginx
      yum:
        name:  nginx
        state: present
      tags: install_nginx
      register: result
      ignore_errors: true
    
    - debug:
        msg: "{{ result }}"
      failed_when: result is failed

    assert模块:

    assert会在指定的条件不符合,返回错误并退出

    #当目标主机没有eth1网卡足额playbook失败
    tasks:
    - name: assert ansbile_bond0 is not dfined
    assert:
    that: ansible_bond0 is defined

    再执行playbook时,插入assert在我们设定的条件不成立;立即失败,调试很有用 


    博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!

  • 相关阅读:
    python基础—函数装饰器
    python基础—函数嵌套与闭包
    Python之三级菜单
    Python之运算符
    Python之字典
    Python之购物车
    Python之列表
    Python之布尔
    Python之“Hello World”
    Python之递归函数
  • 原文地址:https://www.cnblogs.com/zyxnhr/p/12820025.html
Copyright © 2020-2023  润新知