1. ansible中使用python字符串
獲取a字符串的第3個字符,則可以使用"a[2]"獲取,索引從0開始
cat test.yml
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "{{a[2]}}"
a[2:5]獲取到a字符串的第3到第5個字符(不包含第6個字符)
a[:5]獲取到a字符串的第6個字符之前的所有字符(不包含第6個字符)
a[5:]獲取到a字符串的第6個字符之後的所有字符(包含第6個字符)
in和not in,也是python的字符串運算符
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "true"
when: "'va' in a"
使用加號"+"連接兩個字符串
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
b: "vbB67890"
tasks:
- debug:
msg: "{{a+b}}"
使用乘號"*"連續的重複輸出字符串
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "{{a*3}}"
使用find函數查找指定字符在字符串中的位置
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "{{a.find('A1')}}"
當在字符串中沒有找到對應的字符時,find函數的返回值爲"-1",所以,我們也可以利用這一特性,判斷字符串中是否包含指定的字符
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "not found"
when: a.find('A2') == -1
在使用find函數時,也可以指定查找範圍,find函數的語法是find(string,begin,end)
string是要查找的字符串,begin是起始位置,end是結束位置
- hosts: test71
gather_facts: no
vars:
a: "vaA12345"
tasks:
- debug:
msg: "{{a.find('A1',1)}}"
2. 任務委派
在某些場景下,需要指定某個任務在特定的主機上執行,playbook中設置的目標主機是A、B、C三臺主機,playbook中一共有5個task,,其中第3個task需要在D主機上執行,而不是在A、B、C這三臺目標主機上執行,將第3個task單獨設置成一個play段,然後將這個play段的目標主機設置爲D,示意代碼如下:
- hosts: A,B,C
tasks:
- task1:
...
- task2:
...
- hosts: D
gather_facts: no
tasks:
- task3:
- hosts: A,B,C
tasks:
- task4:
...
- task5:
...
任務委派可以讓某個任務在指定的主機上執 行,使用delegate_to關鍵字即可實現"任務委託"功能。
- hosts: test70,test71
gather_facts: no
tasks:
- file:
path: "/tmp/ttt"
state: touch
- file:
path: "/tmp/delegate"
state: touch
delegate_to: test61
- file:
path: "/tmp/ttt1"
state: touch
3. 在ansible主機上執行任務
默認情況下,task都會在目標主機上執行,但是在某些場景下,需要讓某個task在ansible主機上執行,而不是在目標主機上執行將"delegate_to"對應的主機設置成ansible主機解決這個問題,也可以使用"connection: local"來完成。
- hosts: test70,test61
gather_facts: no
tasks:
- file:
path: "/tmp/inAnsible"
state: touch
connection: local
- file:
path: "/tmp/test"
state: touch
4. 設置某個task只運行一次
使用了get_url模塊,從網站上下載了這個包,但是由於目標主機中一共有5臺,所以,下載包的這個task會重複執行5次,示例如下:
- hosts: A,B,C,D,E
gather_facts: no
tasks:
- get_url:
url: "http://nexus.zsythink.net/repository/testraw/testfile/test.tar"
dest: /tmp/
connection: local
- copy:
src: "/tmp/test.tar"
dest: "/tmp"
執行上例playbook,每個任務會針對每個目標主機都執行一遍,一共執行5遍,但是對於第一個task來說,沒有必要執行5 遍,因爲只要執行一遍,我需要的安裝包就會下載到ansible主機中,之後的4遍就沒必要執行了,如果執行上例playbook,由於 ansible具備冪等性,當第一個task執行一次後,之後執行的4次其實並沒有什麼實質性的操作,但是,當你的安裝包特別大、目標主機又特別多時,這 些多餘的操作會浪費一些時間,所以,完全沒有必要執行之後的4遍操作,藉助到"run_once"關鍵字 了,"run_once"關鍵字能讓對應的任務只運行一次,示例如下:
- hosts: A,B,C,D,E
gather_facts: no
tasks:
- get_url:
url: "http://nexus.zsythink.net/repository/testraw/testfile/test.tar"
dest: /tmp/
connection: local
run_once: true
- copy:
src: "/tmp/test.tar"
dest: "/tmp"
5. 向列表中追加項
直接將兩個列表相加,這樣兩個列表會合併成一個列表
- hosts: test71
gather_facts: no
vars:
l1:
- 1
- 2
l2:
- a
- b
- 2
tasks:
- set_fact:
l3: "{{ l1 + l2 }}"
- debug:
var: l3
利用列表合併的這一特性,在列表中追加元素
- hosts: test71
gather_facts: no
vars:
tlist:
- 1
- 2
tasks:
- set_fact:
tlist: "{{ tlist + ['a'] }}"
- debug:
var: tlist
使用jinja2的語法,完成上述追加元素的過程
- hosts: test71
gather_facts: no
vars:
tlist:
- 1
- 2
tasks:
- set_fact:
tlist: "{% set tlist = tlist + ['a'] %}{{tlist}}"
- debug:
var: tlist
在python中,使用列表的extend()函數,也可以實現列表合併的效果,與使用"+"的效果完全相同,比如,將列表A和列表B合併,可以使用A.extend(B)
- hosts: test71
gather_facts: no
vars:
tlist:
- 1
- 2
tasks:
- set_fact:
tlist: "{{ tlist.extend([3,'a']) }}{{tlist}}"
- debug:
var: tlist
append()函數可以直接在列表中追加元素
- hosts: test71
gather_facts: no
vars:
tlist:
- 1
- 2
tasks:
- set_fact:
tlist: "{{ tlist.append('a') }}{{tlist}}"
- debug:
var: tlist
append函數只是單純的將一個對象當做新元素追加到列表中,這個新元素可以時數值或者字符串,也可以是一個列表,或者字典。
- hosts: test71
gather_facts: no
vars:
tlist:
- 1
- 2
tasks:
- set_fact:
tlist: "{{ tlist.append(['a','b']) }}{{tlist}}"
- debug:
var: tlist
6. 在列表中插入項
利用python的insert()函數,在list的指定位置插入新元素
- hosts: test71
gather_facts: no
vars:
tlist:
- 11
- 2
- 11
tasks:
- set_fact:
tlist: "{{ tlist.insert(1,'a') }}{{tlist}}"
- debug:
var: tlist
7. 從列表中刪除項
利用python的pop()函數,根據指定的索引刪除元素。在python中,pop()函數會根據索引刪除元素的同時,將被刪除的元素值作爲返回值。
- hosts: test71
gather_facts: no
vars:
tlist:
- 11
- 2
- 'a'
- 'b'
- 3
tasks:
- debug:
msg: "{{tlist.pop(2)}}"
利用pop()函數刪除列表中指定位置的元素
- hosts: test71
gather_facts: no
vars:
tlist:
- 11
- 2
- 'a'
- 'b'
- 3
tasks:
- set_fact:
tlist: "{{ [ tlist.pop(2),tlist ][1] }}"
- debug:
var: tlist
利用python的remove()函數,根據指定的值刪除元素(第一個與指定值匹配的元素會被刪除)
- hosts: test71
gather_facts: no
vars:
tlist:
- 11
- 'b'
- 'a'
- 'b'
- 3
tasks:
- set_fact:
tlist: "{{ tlist.remove('b') }}{{tlist}}"
- debug:
var: tlist
利用jinja2的for循環,刪除列表中所有匹配到的項
- hosts: test71
gather_facts: no
vars:
tlist:
- 11
- 'b'
- 'a'
- 'b'
- 11
- 'a11'
- '1a'
- '11'
tasks:
- set_fact:
tlist: "{%for i in tlist%}{% if 11 in tlist%}{{tlist.remove(11)}}{%endif%}{%endfor%}{{tlist}}"
- debug:
var: tlist
如下寫法只適合所有元素都是字符串類型的列表,而且,如下寫法可以通過正則表達式,刪除掉所有匹配的元素
- hosts: test71
gather_facts: no
vars:
tlist:
- '11'
- 'b'
- '1a'
- '1b'
- 'c'
- 'a1c'
- 'b1'
tasks:
- set_fact:
tlist: "{{ tlist | reject('search','1') | list }}"
- debug:
var: tlist
reject是jinja2中的一個內建的filter,search是 ansible實現的一個tests,list也是一個過濾器,上例通過將它們結合的方式,刪除了列表中所有符合條件的元素,使用這種方法有個前提條件, 就是列表中的所有元素都必須是字符串,當列表中的所有元素都是字符串時,使用這種方法,可以通過正則表達式靈活的刪除元素,比如,刪除所有’1’開頭的元素。
- hosts: test71
gather_facts: no
vars:
tlist: ['11','b','1a','1b','c','a1c1','b11']
tasks:
- set_fact:
tlist: "{{ tlist | reject('search','^1') | list }}"
- debug:
var: tlist
上例playbook執行後,debug輸出如下:
TASK [debug] ***********************
ok: [test71] => {
"tlist": [
"b",
"c",
"a1c1",
"b11"
]
}
————Blueicex 2020/3/31 11:41 [email protected]