前言
本文將詳細介紹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
- tasks中的main.yaml作為
執行
▶ 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執行是序列的
小結
- 聯絡我,做深入的交流
至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...