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/)本人同意即可轉載,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章