不求甚解--詳解ansible-playbook中roles的用法

it排球君發表於2024-12-10

前言

本文將詳細介紹ansible-playbook中roles的各種用法,它允許你將相關的任務、變數、處理器、檔案和模板等集合在一起,以便於在不同的專案中複用

環境準備

元件 版本
作業系統 Ubuntu 22.04.4 LTS
ansible 2.17.6

基本用法

檔案結構

.
├── deploy.hosts
├── deploy.yaml
└── roles
    └── base
        └── tasks
            └── main.yaml

  • deploy.hosts作為目標機器的列表檔案
    ▶ cat deploy.hosts
    10.22.11.166
    
  • deploy.yaml作為入口檔案
    ▶ cat deploy.yaml
    - name: deploy
      hosts: all
      remote_user: wilson
      gather_facts: no
      vars:
        ansible_ssh_pass: '123456'
        ansible_python_interpreter: /usr/bin/python3
      roles:
        - base
    
    • name:指定作業的名字:deploy
    • hosts:all代表deploy.hosts檔案中所有的機器(也可以指定機器的分類資訊)
    • remote_user:目標機器的登入使用者
    • gather_facts: 是否需要採集目標機器的基本資料,預設採集。指令碼指定的是不採集,為了提高執行速度
    • vars.ansible_ssh_oass:目標機器登入使用者的密碼
    • vars.ansible_python_interpreter:目標機器python3的路徑
    • roles:指定本次作業所使用的角色 base
  • roles目錄作為ansible-playbook中一系列作業任務的集合,其中一個集合的名字叫做base
    • tasks中的main.yaml作為base的入口檔案
      ▶ cat roles/base/tasks/main.yaml
      - name: first
        command: echo 'hello world'
      
      • base當前只有1個任務,就是登入到目標機器,執行hello world

執行

▶ ansible-playbook -i deploy.hosts deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166]

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

在螢幕上顯示執行結果

需要改造roles/base/tasks/main.yaml

▶ cat roles/base/tasks/main.yaml
- name: first
  command: echo 'hello world'
  register: display_result
- name: display
  debug:
    msg: "{{ display_result }}"

把結果放入變數display_result,然後透過模版語言列印出來,並且是json格式的

執行:

▶ ansible-playbook -i deploy.hosts deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166]

TASK [base : display] ********************************************************************************************
ok: [10.22.11.166] => {
    "msg": {
        "changed": true,
        "cmd": [
            "echo",
            "hello world"
        ],
        "delta": "0:00:00.002740",
        "end": "2024-11-19 07:22:22.226036",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2024-11-19 07:22:22.223296",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "hello world",
        "stdout_lines": [
            "hello world"
        ]
    }
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

引用環境變數

將作業系統的環境變數傳入,可以透過lookup來引用,比如:要使用PATH,可以透過lookup('env', 'PATH')

改造roles/base/tasks/main.yaml

▶ cat roles/base/tasks/main.yaml
- name: first
  debug:
    msg: "{{ lookup('env', 'PATH') }}"

執行:

▶ ansible-playbook -i deploy.hosts deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "/home/wilson/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/usr/local/go/bin:/usr/local/go/bin"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

使用ansible變數

這裡的ansible變數,其中一部分ansible預設的變數,一部分是ansible執行的時候,會預設去採集目標機器的基本資訊,比如作業系統、cpu、記憶體、磁碟等等的基本資訊

部分內建變數

變數名 描述
inventory_hostname 當前任務執行的主機名(來自 Inventory 檔案)
ansible_facts 包含所有收集到的主機事實(facts)
hostvars 所有主機變數的集合,包含當前和其他主機

採集目標機器的基本資訊

需要把之前採集ansible基本資訊的開關開啟gather_facts: yes,開啟之後會犧牲執行速度

改造roles/base/tasks/main.yaml

- name: first
  debug:
    msg: "{{ hostvars }}"

執行:

由於資料量太大,只展示部分,並且json格式,可以直接拿想要的值

▶ ansible-playbook -i deploy.hosts deploy.yaml

PLAY [deploy] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [10.22.11.166]

TASK [base : first] ************************************************************
ok: [10.22.11.166] => {
    "msg": {
        "10.22.11.166": {
            "ansible_all_ipv4_addresses": [
                "10.22.11.166"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::a00:27ff:fef6:82c4"
            ],
            "ansible_apparmor": {
                "status": "enabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "12/01/2006",
            "ansible_bios_vendor": "innotek GmbH",
            "ansible_bios_version": "VirtualBox",
            "ansible_board_asset_tag": "NA",
            "ansible_board_name": "VirtualBox",
            "ansible_board_serial": "NA",
            "ansible_board_vendor": "Oracle Corporation",
            ...
            "inventory_dir": "/home/wilson/workspace/ansible",
            "inventory_file": "/home/wilson/workspace/ansible/deploy.hosts",
            "inventory_hostname": "10.22.11.166",
            "inventory_hostname_short": "10.22.11.166",
            "module_setup": true,
            "playbook_dir": "/home/wilson/workspace/ansible"
        }
    }
}

PLAY RECAP *********************************************************************
10.22.11.166               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

是否採集目標的基本資訊

上面已經演示過,只需要gather_facts: yes即可

從命令列傳入變數

ansible-playbook可以透過-e傳入變數使用

▶ cat roles/base/tasks/main.yaml
- name: first
  debug:
    msg: "{{ app_name }} - {{ app_version }}"

執行:

▶ ansible-playbook -i deploy.hosts -e "app_name=prom app_version=1.0" deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************
ok: [10.22.11.166]

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "prom - 1.0"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

動態選擇host

1)將主機分組

修改deploy.hosts檔案

▶ cat deploy.hosts
[ga]
10.22.11.166

[gb]
10.22.11.166
127.0.0.1

2)改造入口檔案

▶ cat deploy.yaml
- name: deploy
  hosts: '{{h}}'
  remote_user: wilson
  gather_facts: no
  vars:
    ansible_ssh_pass: '123456'
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - base

將hosts改在成為'{{h}}',透過傳入h變數來動態定義

3)執行

指定h為ga

▶ ansible-playbook -i deploy.hosts -e "h=ga" deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

指定h為gb

▶ ansible-playbook -i deploy.hosts -e "h=gb" deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world"
}
ok: [127.0.0.1] => {
    "msg": "hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

條件選擇when

▶ cat roles/base/tasks/main.yaml
- name: first
  debug:
    msg: "version 1"
  when: version == '1'

- name: second
  debug:
    msg: "version 2"
  when: version == '2'

定義臨時變數

透過-e傳入的變數來產生臨時變數

- name: first
  set_fact:
    tag: "hello-{{ version }}"

- name: second
  debug:
    msg: "{{ tag }}"

執行:

▶ ansible-playbook -i deploy.hosts -e "version=2" deploy.yaml

...

TASK [base : second] *********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello-2"
}

...

呼叫多個role

1)新增role: advance

.
├── deploy.hosts
├── deploy.yaml
└── roles
    ├── advance
    │   └── tasks
    │       └── main.yaml
    └── base
        └── tasks
            └── main.yaml

2)直接在入口檔案deploy.yaml引用

.
├── deploy.hosts
├── deploy.yaml
└── roles
    ├── advance
    │   └── tasks
    │       └── main.yaml
    └── base
        └── tasks
            └── main.yaml

執行:

▶ ansible-playbook -i deploy.hosts -e "version=2" deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166]

TASK [base : second] *********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello-2"
}

TASK [advance : new-first] ***************************************************************************************
ok: [10.22.11.166] => {
    "msg": "new hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3)在roles base中引用 advance

▶ cat deploy.yaml
- name: deploy
  hosts: all
  remote_user: wilson
  gather_facts: no
  vars:
    ansible_ssh_pass: '123456'
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - base

▶ cat roles/base/tasks/main.yaml
- name: base first
  debug:
    msg: "base {{ version }}"

- name: base second
  include_role:
    name: advance
  vars:
    role_pipe_from_base: "hello world from base"

- name: base third
  debug:
    msg: "{{ role_pipe_from_advance }}"
▶ cat roles/advance/tasks/main.yaml
- name: advance first
  debug:
    msg: "advance {{ version }}"

- name: advance second
  debug:
    msg: "{{ role_pipe_from_base }}"

- name: advance third
  set_fact:
    role_pipe_from_advance: "hello world from advance"

執行:

▶ ansible-playbook -i deploy.hosts -e "version=2" deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : base first] *****************************************************************************************
ok: [10.22.11.166] => {
    "msg": "base 2"
}

TASK [base second] ***********************************************************************************************
included: advance for 10.22.11.166

TASK [advance : advance first] ***********************************************************************************
ok: [10.22.11.166] => {
    "msg": "advance 2"
}

TASK [advance : advance second] **********************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world from base"
}

TASK [advance : advance third] ***********************************************************************************
ok: [10.22.11.166]

TASK [base : base third] *****************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world from advance"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

這個例子呈現了:

  • 傳入變數version是共用的
  • 如何在role傳遞引數
  • 執行過程中定義的臨時變數role_pipe_from_advance可以跨role持續
  • 多role執行是序列的

小結

  • 聯絡我,做深入的交流


至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...

相關文章