Playbooks是一種簡單的配置管理系統與多機器部署系統的基礎,很是適合於複雜應用的部署。Playbooks可用於聲明配置,能夠編排有序的執行過程,甚至能夠作到在多組機器間來回有序的執行指定的步驟,而且能夠同步或異步的發起任務。playbooks能夠稱爲劇本,也能夠稱爲做業,我更習慣將其稱之爲做業。
系統環境:python
服務器 | IP地址 | 操做系統 | 所需軟件 |
---|---|---|---|
ansible主機 | 192.168.2.203 | Centos 7 64位 | ansible |
遠程主機1 | 192.168.2.205 | Centos 7 64位 | httpd |
遠程主機2 | 192.168.2.208 | Centos 7 64位 | httpd |
遠程主機3 | 192.168.2.214 | Centos 7 64位 | 無 |
遠程主機4 | 192.168.2.215 | Centos 7 64位 | 無 |
Playbooks遵循YAML語法,是playbook的配置管理語言。YAML跟XML或JSON同樣,都是一種利於人們讀寫的數據格式。每個YAML文件都是從一個列表開始,列表中的每一項都是一個鍵值對,一般它們被稱爲一個「哈希」或「字典」,咱們須要知道如何在YAML中編寫列表和字典。
YAML基本規則:
一、區分大小寫
二、使用縮進表示層級關係
三、禁止使用tab健縮進,只能使用空格鍵
四、縮進長度沒有限制,只要元素對齊就表示這些元素屬於一個層級。
五、使用#表示註釋
六、字符串能夠不用引號括起來,但有特殊符號的字符串必須用引號括起來
YAML文件的第一行是「---」,聲明一個文件的開始,但實際上也能夠省略此行。
YAML有三種數據結構:一、列表,二、字典,三、常量。
列表中的全部成員都要以」- 」做爲開頭(一個橫槓和一個空格)。舉個例子,下面是一個水果的列表mysql
--- - Apple - Orange - Strawberry - Mango
一個字典是由簡單的「鍵: 值」的形式組成(冒號後面必須有一個空格):linux
name: Example Developer job: Developer skill: Elite
字典也可使用相似json的形式來表示:{name: Example Developer, job: Developer, skill: Elite}
YAML中提供了多種常量結構,包括:整數、浮點數、字符串、NULL、日期、布爾值、時間等。例如:nginx
boolean: Knows_agent: TRUE # true, True均可以 users_cvs: FALSE # false, False均可以 float: - 3.14 - 6.856351e+5 # 可使用科學計數法 int: - 123 - 0b1010_0111_1010_1110 # 二進制表示 null: parent: ~ # 使用~表示null string: - newline - "he&lo x$%d" # 包含特殊字符的字符串要用雙引號括起來 date: - 2018-02-17 # 日期必須使用ISO 8601格式,即yyyy-MM-dd datetime: - 2018-02-17T15:02:31+08:00 # 時間使用ISO 8601格式,時間和日期之間使用T鏈接,最後使用+表明時區
數據格式嵌套,把列表、字典和常量嵌套使用,例如:web
--- name: Example Developer job: Developer skill: Elite employed: True foods: - Apple - Orange languages: ruby: Elite python: Elite dotnet: yes
此外,ansible使用「{{ var }}」來引用變量,一個「{}」將認爲是一個字典,兩個「{{}}」則是變量。例如:Foo: "{{ variable }}"
算法
咱們先來看一個官網的例子
實例1:httpd服務版本更新、配置推送sql
--- # 聲明這是YAML文件 - hosts: webservers # 指定要操做的主機或主機組 vars: # 定義變量 http_port: 80 # 定義了一個http_port變量,http_port變量的內容是80 max_clients: 200 # 定義了一個max_clients變量,max_clients變量的內容是200 remote_user: root # 指定執行的用戶 tasks: # tasks段指定要執行的任務操做 - name: ensure apache is at the latest version # 任務名稱 yum: pkg=httpd state=latest # 經過yum模塊確保httpd服務爲最新版本 - name: write the apache config file # 任務名稱 template: src=/srv/httpd.j2 dest=/etc/httpd/conf/httpd.conf # 使用httpd.j2作爲配置模板,可實現配置推送 notify: # 配置有修改的話將會觸發handlers,重啓httpd服務 - restart apache # 重啓任務的名稱 - name: ensure apache is running # 任務名稱 service: name=httpd state=started # 確保httpd服務是啓動狀態 handlers: # 跟上面的notify是配對的,由notify來進行觸發 - name: restart apache # 任務名稱 service: name=httpd state=restarted # 重啓httpd服務
這個playbook做業的功能以下:
一、確保apache是最新版本,若是不是則升級到最新版本。
二、經過httpd.j2模塊來進行配置推送,若是httpd.j2和httpd.conf文件內容同樣,則什麼都不作;若是httpd.j2文件內容有改動,則將改動的配置更新到httpd.conf,而且重啓apache。
三、確保apache是啓動狀態,若是不是則啓動apache。
首先將httpd服務的配置拷貝到ansible本機的/svr/目錄下,並命名爲httpd.j2,將此文件做爲httpd服務的配置模板文件。scp -P 22 root@192.168.2.208:/etc/httpd/conf/httpd.conf /srv/httpd.j2
而後運行這個playbook做業,確保兩臺機器httpd的版本、配置都同樣。ansible-playbook httpd_config.yml
返回信息的最後兩行詳解:
205這臺主機共修改了3個地方,更新了版本、更新了配置、重啓了服務,因此是changed=3;共確認了5個地方,連通狀況、版本更新、配置推送、運行狀態、重啓,因此ok=5。
208這臺主機共修改了1個地方,更新了版本,因此是changed=1;共確認了4個地方,比205少了一個重啓,因此是ok=4。
接下來咱們來測試下這個playbook做業,修改httpd.j2模板文件,添加status配置內容docker
ExtendedStatus On <Location /server-status> SetHandler server-status Order deny,allow Allow from all </Location>
而後再執行這個playbook做業,將配置推送到兩臺主機上ansible-playbook httpd_config.yml
咱們再到兩臺主機上查看一下配置文件內容,確保status配置已經推送成功。
打開瀏覽器訪問http://192.168.2.205/server-status和http://192.168.2.208/server-status
status頁面訪問OK,之後即便遠程主機的httpd配置被人改動了,能夠很方便的經過這個playbook做業輕鬆恢復;要修改httpd的配置,也能夠經過它來更新配置,是否是很方便啊。
上面這個例子沒看懂的話也沒關係,接下來我會一步一步來說解如何寫一個playbook,並且後面會有更多的實例。
上面這個playbook做業主要是由如下四部分組成:
Target section:定義將要執行 playbook 的遠程主機組或主機
Variable section:定義 playbook 運行時須要使用的變量
Task section:定義將要在遠程主機上執行的任務列表
Handler section:定義 task 執行完成之後須要調用的任務
即然如此,那麼要寫一個playbook,首先得指定須要操做的主機或主機組,以及執行playbook做業的用戶。shell
--- - hosts: web_server # 定義要操做的主機或主機組 remote_user: root # 指定執行任務的用戶
也支持用sudo命令執行playbook做業數據庫
- hosts: web_server remote_user: root sudo: yes # 使用sudo執行任務
若是要sudo到其它用戶,而不是sudo到root,只須要添加sudo_user: xuad
若是sudo設置了密碼的話,可在運行ansible-playbook命令時添加--ask-sudo-pass或者-k選項。建議使用sudo的話,不要設置sudo密碼。
ansible-playbook httpd_config.yml --ask-sudo-pass ansible-playbook httpd_config.yml -k
須要定義變量使用vars
vars: filename: xuad.txt # 定義了一個文件名稱變量 pathname: "/etc/ansible/" # 定義了一個文件路徑變量
須要執行的任務經過tasks來定義
tasks: - name: ensure apache is at the latest version # 任務名稱 service: name=httpd state=started # 定義要執行的操做
也能夠在tasks中指定使用sudo執行命令
tasks: - name: ensure apache is at the latest version service: name=httpd state=started sudo: yes # 使用sudo命令啓動httpd服務 sudo_user: xuad # 指定sudo到的用戶
若是要停止一個playbook做業的運行,可使用ctrl+c組合鍵停止運行。
playbook按從上到下的順序執行,每一個task的目標在於執行一個moudle(模塊),一般是帶有特定的參數來執行,在參數中可使用變量。
能夠經過{{ 變量名 }}的方式獲取vars裏定義的變量,若是參數太多,可使用縮進的方式隔開連續的一行
tasks: - name: Copy ansible inventory file to client copy: src={{ pathname }}{{ filename }} dest={{ pathname }}{{ filename }} owner=root group=root mode=0644 # 使用縮進的方式隔開連續的行
經過前面ansible命令的熟悉後,咱們知道command和shell模塊不使用key=value格式,在playbook中能夠這樣定義
tasks: - name: disable selinux command: /sbin/setenforce 0 # 直接使用command命令 - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true # 直接使用shell命令
notify和handlers組合,當上一條任務發生改動,在每個task結束時會觸發notify去執行handlers,即便有多個任務指出由於有改動須要執行handlers,notify也只會被觸發一次,handlers也只會執行一次。
例如上面那個例子,當httpd配置文件發生改變會觸發notify,咱們在返回的信息明顯看到handlers是在playbook做業的最後一步才執行。
ansible還能夠經過ansible-pull從節點主機上拉取配置,具體的使用可參考官網,這裏我就不講了。
查看一個playbook是對哪些主機執行任務,可以使用下面語句ansible-playbook httpd_config.yml --list-hosts
ansible默認只會建立5個併發進程,也就是說一個任務5臺機器同時執行,而後再同時執行5臺,直到全部機器都執行完成爲止。當咱們有大量的機器時,須要同時執行更多的機器,可使用-f參數,指定併發進程數量。ansible-playbook httpd_config.yml -f 10
若是要併發執行單個任務,好比說某一個任務我須要全部機器同時執行,可使用async和poll,async觸發ansible併發執行任務,async的值是這個任務執行的最長時間,而poll是檢查這個任務是否完成的頻率時間。
- hosts: all tasks: - name: Shell script shell: sh /tmp/script.sh - name: run updatedb command: /usr/bin/updatedb async: 300 poll: 10
上面這個例子shell模塊是同時在5臺機器上執行,而command模塊是同時在全部機器上執行,而且超時時間是300秒,檢查任務完成的頻率時間是10秒。
若是playbook是放到後臺去執行,後臺執行加-B參數,那就不須要檢查了,能夠把poll設置爲0。若是一個任務須要運行很長時間,須要一直等待這個任務完成,不須要設置超時時間,能夠把async的值設置爲0。
(1)經過when語句實現條件選擇
有時咱們可能但願某一個任務在知足一個條件的狀況下執行,若是不知足這個條件就不執行,可使用when語句,能夠按下面方式定義
tasks: - name: "Shutdown RedHat flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "RedHat" # 當節點主機的操做系統是redhat時關機
setup模塊獲取到的主機系統信息能夠直接在playbook裏面調用,查看遠程節點主機是什麼系統可以使用下面語句ansible 192.168.2.205 -m setup -a 'filter=ansible_os_family'
若是不知足此條件能夠用not,有多個條件須要同時知足能夠用and,知足其中一個條件用or。
when: not ansible_os_family == "RedHat" when: ansible_os_family == "RedHat" and ansible_os_family == "Debian" when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
也能夠對數值變量進行判斷,以下
when: ansible_lsb.major_release|int >= 6 when: ansible_lsb.major_release|int != 6
咱們都知道在shell中判斷一條命令執行成功與否,能夠echo $?,0表示成功,1表示失敗。在playbook中咱們可使用register語句來判斷一條命令執行成功與否,成功返回succeeded或者success,失敗返回failed,而後將返回信息保存在一個變量裏,經過這個變量內容來作相應的處理。
實例2:判斷httpd服務是否running狀態,是則打印「httpd is running, OK」,不是則打印「httpd is faild, Faild」
- hosts: web_server remote_user: root tasks: - name: httpd status shell: systemctl status httpd | grep running register: status_result ignore_errors: True - name: Httpd is Running debug: msg="httpd is running, OK" when: status_result is success - name: Httpd is Faild debug: msg="httpd is faild, Faild" when: status_result is failed
register須要配置使用ignore_errors,而且設置成True,不然若是任務執行失敗,即echo $0不爲0,則會致使程序停止,後面的任務不會執行。
dedug模塊有兩個參數,msg和fail,msg就是打印信息,而當fail=yes時,會發送失敗通知給ansible,而後ansible會中止運行任務。debug: msg="OS Family {{ ansible_os_family }} is not supported" fail=yes
不論是在inventory中仍是playbooks中定義的變量均可以給when使用,下面的例子是基於「鍵: 值」來決定一個任務是否被執行
vars: xuad: true tasks: - shell: sh /tmp/abcd.sh when: xuad tasks: - shell: sh /tmp/efgh.sh when: not xuad
若是一個變量不存在,可使用defined跳過執行此任務
tasks: - shell: sh /tmp/abcd.sh # 此任務不會執行 when: foo is defined - shell: sh /tmp/efgh.sh # 此任務會執行 when: bar is not defined
還能夠同時對多個變量進行判斷,可經過items定義多個變量,而後循環代入到任務當中,經過when還判斷變量內容,符合條件的變量纔會代入到任務中執行。關於items的使用,後面循環內容會進行講解。
實例3:對多個變量進行判斷,符合條件的纔會打印變量內容
- hosts: 192.168.2.205 remote_user: root tasks: - command: echo {{ item }} with_items: [ 0, 2, 4, 6, 8, 10 ] when: item > 5
when語句還能夠應用在tasks的includes上面,以下
- include: tasks/xuad.yml when: "'reticulating splines' in output"
when語句也能夠應用在roles上面,以下
- hosts: web_server roles: - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
關於roles(角色)部分,後面會進行講解,這裏只須要知道如何在roles上面定義when便可。
(2)經過變量實現條件選擇
經過setup系統信息息變量獲取變量文件,再經過獲取變量文件裏定義的變量實現條件選擇
實例4:不一樣的系統版本主機獲取對應的變量,實現條件選擇
首先建立一個變量文件RedHat.yml,內容以下:
apache: httpd somethingelse: 42
再建立一個playbook文件httpd_running.yml,內容以下:
- hosts: all remote_user: root vars_files: - [ "/root/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ] tasks: - name: make sure apache is running service: name={{ apache }} state=started
此實例是不一樣的系統版本的主機獲取到本身的apache變量。先經過ansible_os_family變量獲取到RedHat.yml文件或者其它系統版本的變量文件,再經過RedHat.yml獲取apache變量,若是獲取不到,就經過os_defaults.yml默認的變量文件獲取apache變量,而後將apache變量內容代入到service模塊裏,從而實現確保httpd服務是運行狀態。
經過with_first_found實現文件匹配,第一個文件匹配不到,纔會去匹配第二個文件,依此類推。
- name: template a file template: src={{ item }} dest=/etc/myapp/foo.conf with_first_found: - files: - {{ ansible_distribution }}.conf - default.conf paths: - search_location_one/somedir/ - /opt/other_location/somedir/
先經過{{ ansible_distribution }}.conf文件匹配,不一樣的系統版本主機會匹配到本身的配置文件,匹配到的話就推送這個文件的配置;匹配不到的主機會推送default.conf文件的配置。
變量能夠在四個地方進行定義:一、在Inventory中定義變量,這個在我上一篇博文已經講過,這裏再也不重複。二、在playbook中定義變量。三、在文件中定義變量。四、在role中定義變量。
經過前面的一些例子,你們應該已經發如今playbook中定義變量其實很簡單
vars: http_port: 80
引用變量也很簡單,只需使用{{}}兩個大括號便可,例如:{{ http_port }}
下面來看一個例子,咱們如今要批量更新一個應用,那首先是將更新文件打包壓縮,而後將更新包分發到各個遠程主機上,而後再將更新包解壓到應用所在目錄,最後重啓應用。咱們有個以當前日期爲名稱的yml_20180730.tar.gz壓縮包,此壓縮包包含兩個文件docker.yml和nginx.yml,那我如今須要將它分發到web_server組裏全部主機的/tmp目錄下並解壓,以下實例。
實例5:將tar.gz格式的壓縮包拷貝到遠程主機上並解壓
- name: copy and unzip file hosts: web_server remote_user: root vars: file: yml_{{ansible_date_time.year}}{{ansible_date_time.month}}{{ansible_date_time.day}}.tar.gz tasks: - name: 分發更新包 copy: src=/etc/ansible/{{ file }} dest=/tmp - name: 解壓更新包 shell: tar -zxvf /tmp/{{ file }} -C /tmp
ansible-playbook tarcopy.yml
ansible web_server -m shell -a "ls -lh /tmp"
經過facts獲取系統相關的變量,也就是前面所說的setup模塊,例如:獲取遠程系統的當前日期{{ ansible_date_time.date }}
在playbook中也能夠關閉facts數據的獲取,這樣有利於加快ansible操做大批量服務器的速度
- hosts: all gather_facts: no
要想指定獲取哪臺主機的系統變量,能夠按以下方式引用{{ hostvars['192.168.2.205']['ansible_os_family'] }}
在文件中定義變量也很簡單,咱們首先寫一個變量文件vars.yml
somevar: somevalue password: magic
在playbook中能夠按如下方式引用,使用vars_files來獲取文件中的變量
- hosts: all remote_user: root vars: favcolor: blue vars_files: - /vars/vars.yml tasks: - name: this is just a placeholder command: /bin/echo foo
在命令行中傳遞變量,使用--extra-vars,例如我在playbook中引用了兩個變量,以下
- hosts: '{{ hosts }}' remote_user: '{{ user }}' tasks:
在執行playbook的命令中能夠按以下方式傳遞變量到playbook中ansible-playbook release.yml --extra-vars "hosts=web_server user=root"
也能夠傳遞json格式的變量--extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
使用「@」傳遞json文件--extra-vars "@some_file.json"
在roles中能夠按以下方式定義變量
roles: - { role: app_user, name: Ian } - { role: app_user, name: Terry }
若是在不一樣的地方定義了一個相同的變量,獲取變量的優先級以下:
extra vars (在命令行中使用 -e)優先級最高
而後是在inventory中定義的鏈接變量(好比ansible_ssh_user)
接着是大多數的其它變量(命令行轉換,play中的變量,included的變量,role中的變量等)
而後是在inventory定義的其它變量
而後是由系統發現的facts
而後是 "role默認變量", 這個是最默認的值,很容易喪失優先權
使用with_items定義多個變量,以循環的方式引用變量
實例6:copy兩個文件到遠程主機的/tmp下
- name: copy file hosts: web_server remote_user: root tasks: - name: cp file copy: src=/etc/ansible/{{ item }} dest=/tmp with_items: - ansible.cfg - hosts
ansible-playbook copyf.yml
ansible web_server -m shell -a "ls /tmp"
同時引用兩個變量,能夠按以下方式定義
- name: add several users user: name={{ item.name }} state=present groups={{ item.groups }} with_items: - { name: 'testuser1', groups: 'wheel' } - { name: 'testuser2', groups: 'root' }
使用with_nested實現循環嵌套,按以下方式定義
注:item[0]循環alice和bob兩個變量,item[1]循環clientdb、employeedb和providerdb三個變量,如下例子是實如今三個數據庫上建立兩個用戶。
- name: give users access to multiple databases mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo with_nested: - [ 'alice', 'bob' ] - [ 'clientdb', 'employeedb', 'providerdb' ]
使用with_dict實現對哈希表循環,按以下方式定義
users: alice: name: Alice Appleworth telephone: 123-456-7890 bob: name: Bob Bananarama telephone: 987-654-3210 tasks: - name: Print phone records debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" with_dict: "{{users}}"
使用with_fileglob實現對文件列表進行循環,以下實例
實例7:copy一個目錄下的全部文件到遠程主機上
- hosts: web_server remote_user: root tasks: - name: 建立目錄 file: dest=/tmp/ansible state=directory - name: 拷貝目錄下的全部文件 copy: src={{ item }} dest=/tmp/ansible/ owner=root mode=600 with_fileglob: - /etc/ansible/*
ansible-playbook files.yml
使用with_together實現並行循環,一次獲取多個變量
vars: alpha: [ 'a', 'b', 'c', 'd' ] numbers: [ 1, 2, 3, 4 ] tasks: - debug: msg="{{ item.0 }} and {{ item.1 }}" with_together: - "{{alpha}}" - "{{numbers}}"
使用with_subelements實現對子元素使用循環,假設咱們有一份按如下方式定義的文件
users: - name: alice authorized: - /tmp/alice/onekey.pub - /tmp/alice/twokey.pub mysql: password: mysql-password hosts: - "%" - "127.0.0.1" - "::1" - "localhost" privs: - "*.*:SELECT" - "DB1.*:ALL" - name: bob authorized: - /tmp/bob/id_rsa.pub mysql: password: other-mysql-password hosts: - "db1" privs: - "*.*:SELECT" - "DB2.*:ALL"
要獲取以上文件裏定義的數據,能夠按如下方式引用變量
- user: name={{ item.name }} state=present generate_ssh_key=yes with_items: "{{users}}" - authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'" with_subelements: - users - authorized
以嵌套的方式獲取變量,以下
- name: Setup MySQL users mysql_user: name={{ item.0.user }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }} with_subelements: - users - mysql.hosts
使用with_sequence對整數序列使用循環,以下
- hosts: all tasks: # create groups - group: name=evens state=present - group: name=odds state=present # create some test users - user: name={{ item }} state=present groups=evens with_sequence: start=0 end=32 format=testuser%02x # create a series of directories with even numbers for some reason - file: dest=/var/stuff/{{ item }} state=directory with_sequence: start=4 end=16 stride=2 # a simpler way to use the sequence plugin # create 4 groups - group: name=group{{ item }} state=present with_sequence: count=4
使用with_random_choice實現隨機選擇一個變量
- debug: msg={{ item }} with_random_choice: - "go through the door" - "drink from the goblet" - "press the red button" - "do nothing"
使用Do-Until循環,實現循環執行某個任務直到指定的條件成立後中止
- action: shell /usr/bin/foo register: result until: result.stdout.find("all systems go") != -1 retries: 5 delay: 10
上面的例子遞歸運行shell模塊,直到運行結果中的stdout輸出中包含「all systems go」字符串時中止運行,或者該任務按照10秒的延遲重試超過5次時中止運行。
ansible支持將一個playbook進行拆解,好比將vars、tasks和須要操做的主機或執行的用戶分別寫在不一樣的文件裏,而後經過一個簡單的playbook文件去調用這些文件,那麼最好的辦法就是使用角色(roles),也能夠將roles稱之爲各個項目的集合。
一個角色必須包含以下目錄:
role_name/
files/:存儲由copy或script等模塊調用的文件;
tasks/:此目錄中至少應該有一個名爲main.yml的文件,用於定義各個task;其它的文件須要由main.yml進行"包含"調用;
handlers/:此目錄中至少應該有一個名爲main.yml的文件,用於定義各個handler;其它的文件須要由main.yml進行"包含"調用;
vars/:此目錄中至少應該有一個名爲main.yml的文件,用於定義各個variable;其它的文件須要由main.yml進行「包含」調用;
templates/:存儲由template模塊調用的模板文本;
meta/:此目錄中至少應該有一個名爲main.yml的文件,定義當前角色的特殊設定及其依賴關係;其它的文件須要由main.yml進行"包含"調用;
default/:此目錄中至少應該有一個名爲main.yml的文件,用於設定默認變量;
實例8:yum方式批量安裝部署mysql
首先建立ssh-key受權,將公鑰文件copy到兩臺主機上
ssh-copy-id 192.168.2.214 ssh-copy-id 192.168.2.215
而後hosts文件添加以下內容
[db_server] 192.168.2.214 192.168.2.215
肯定2臺主機都能正常鏈接ansible db_server -m ping
創建mysql項目的角色目錄
cd /etc/ansible/roles/ mkdir -p mysql/{default,files,handlers,meta,tasks,templates,vars}
因爲咱們修改了mysql的數據存儲路徑、日誌路徑和socket文件路徑,因此須要關閉selinux,mysql才能正常啓動。
建立關閉selinux的配置模板文件,將此模板文件放到/etc/ansible/roles/mysql/templates目錄下
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. #SELINUX=enforcing SELINUX=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. #SELINUXTYPE=targeted
建立mysql的配置模板文件,將此模板文件放到/etc/ansible/roles/mysql/templates目錄下
[mysqld] datadir=/data/mysql/data socket=/data/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd [mysqld_safe] log-error=/data/mysql/mariadb.log pid-file=/data/mysql/mariadb.pid socket=/data/mysql/mysql.sock # # include all files from the config directory # !includedir /etc/my.cnf.d
建立調用roles的playbook做業vim mysql.yml
- hosts: db_server remote_user: root roles: - mysql
建立關閉selinux的tasks文件vim mysql/tasks/selinux.yml
- name: Modify the configuration file for SELinux template: src=config.j2 dest=/etc/selinux/config - name: close selinux shell: setenforce 0
建立變量vars定義文件vim mysql/vars/main.yml
mysql_name: "mariadb" mysql_path: "/data/mysql" mysql_port: 3306 root_pass: "123456"
yum安裝mariadb須要安裝mariadb-devel、mariadb和mariadb-server三個包,那麼咱們如今來建立tasks文件vim mysql/tasks/mysql_install.yml
- name: ensure {{ mysql_name }}-devel is at the latest version yum: pkg={{ mysql_name}}-devel state=latest - name: ensure {{ mysql_name }} is at the latest version yum: pkg={{ mysql_name }} state=latest - name: ensure {{ mysql_name }}-server is at the latest version yum: pkg={{ mysql_name }}-server state=latest - name: Create a data directory file: dest={{ mysql_path }}/data mode=755 owner=mysql group=mysql state=directory - name: write the mysql config file template: src=my.cnf.j2 dest=/etc/my.cnf notify: - restart mysql - name: ensure mysql is running service: name={{ mysql_name }} state=started enabled=yes - name: Creating a soft link file file: src={{ mysql_path }}/mysql.sock dest=/var/lib/mysql/mysql.sock state=link - name: Setting the root password shell: mysqladmin -u root -h localhost password {{ root_pass }}
建立tasks的main.yml文件vim mysql/tasks/main.yml
- include: selinux.yml - include: mysql_install.yml
建立handlers文件vim mysql/handlers/main.yml
- name: restart mysql service: name=mariadb state=restarted
最終mysql的角色路徑以下
運行mysql.yml做業ansible-playbook mysql.yml
登錄到遠程主機上看一下結果吧
實例9:經過unarchive將tar.gz的壓縮包解壓到遠程主機的指定目錄下
前面的實例5是經過tar命令解壓的,因此會拋出一個警告,意思是建議使用unarchive來完成此任務。
- name: copy and unzip file hosts: web_server remote_user: root tasks: - name: copy your folder from control machine to remote host unarchive: src=yml_{{ansible_date_time.year}}{{ansible_date_time.month}}{{ansible_date_time.day}}.tar.gz dest=/tmp
ansible-playbook untar.yml
實例10:批量啓動、重啓、中止httpd服務
注:tags可實現單獨運行一個playbook做業中的指定的任務
- hosts: web_server remote_user: root tasks: - name: start httpd service: name=httpd state=started tags: start_httpd - name: stop httpd service: name=httpd state=stopped tags: stop_httpd - name: restart httpd service: name=httpd state=restarted tags: restart_httpd
例如我如今重啓httpd服務ansible-playbook httpd.yml -t restart_httpd
實例11:批量建立用戶
首先經過如下方式生成sha-512算法密碼,例如密碼爲xuad123456python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"
而後建立playbook做業,生成的加密串貼到password=」」裏
- hosts: web_server remote_user: root tasks: - name: 建立用戶 user: name={{ item }} password="$6$rounds=656000$O//XUuLIX35/oB2V$yuLC/9TUUvCBb/aCtN0N.xhjBA1ui3t0kPcK2PWP0Hp0eLuThZzx904v3ZoOhAxj/pS6GIHM4RudAzNfnGbxq0" with_items: - xiaozh - wangbs - yangdl
ansible-playbook user_add.yml
實例12:批量初始化zabbix數據庫
首先把zabbix的三個sql文件放到/etc/ansible/roles/mysql/files目錄下
編寫初始化zabbix數據庫的playbook做業vim mysql_add.yml
- hosts: db_server remote_user: root vars_files: - /etc/ansible/roles/mysql/vars/main.yml vars: zauser: zabbix_user user_pass: "user123456" tasks: - name: 安裝MySQL-python模塊 yum: pkg=MySQL-python state=latest - name: 建立zabbix數據庫 mysql_db: login_user=root login_password={{ root_pass }} name=zabbix encoding=utf8 state=present - name: 建立zabbix用戶 mysql_user: login_user=root login_password={{ root_pass }} name={{ zauser }} password={{ user_pass }} priv='zabbix.*:ALL' state=present - name: 分發sql腳本 copy: src={{ item }} dest=/tmp/ with_fileglob: - /etc/ansible/roles/mysql/files/* - name: 導入sql腳本到zabbix數據庫 mysql_db: login_user=root login_password={{ root_pass }} name=zabbix state=import target=/tmp/{{ item }} with_items: - schema.sql - images.sql - data.sql
ansible-playbook mysql_add.yml
可自行登錄到遠程主機上進行測試