鏈接 https://galaxy.ansible.com 下載相應的roles,此網站是Ansible愛好者將平常使用較好的playbooks打包上傳,其餘人能夠免費下載 到Ansible PlayBooks並當即投入使用。
ansible-galaxy 語法:php
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] 列出已安裝的galaxy #ansible-galaxy list geerlingguy.mysql - geerlingguy.mysql, 2.8.1 安裝galaxy ansible-galaxy install geerlingguy.redis 刪除galaxy ansible-galaxy remove geerlingguy.redis
進入網站後找到這時標記的地方mysql
把名字複製下來nginx
就能夠在你的ansible主機上進行安裝劇本了。git
#ansible-galaxy install geerlingguy.mysql - downloading role 'mysql', owned by geerlingguy - downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/2.8.1.tar.gz - extracting geerlingguy.mysql to /root/.ansible/roles/geerlingguy.mysql - geerlingguy.mysql (2.8.1) was installed successfully
安裝的劇本默認是存放在家目錄的隱藏文件中。
/root/.ansiblegithub
#tree -L 2 . └── geerlingguy.mysql ├── defaults ├── handlers ├── LICENSE ├── meta ├── README.md ├── tasks ├── templates ├── tests └── vars
固然,本機的galaxy命令也提供在線搜索劇本。web
#ansible-galaxy search --author geerlingguy Found 90 roles matching your search: Name Description ---- ----------- geerlingguy.raspberry-pi Configures a Raspberry Pi. geerlingguy.php-redis PhpRedis support for Linux geerlingguy.drupal-console Drupal Console geerlingguy.adminer Installs Adminer for Database management. geerlingguy.blackfire Blackfire installation for Linux geerlingguy.tomcat6 Tomcat 6 for RHEL/CentOS and Debian/Ubuntu. geerlingguy.php-pear PHP PEAR library installation.
功能:管理加密解密yml文件正則表達式
ansible-vault [create|decrypt|edit|encrypt|rekey|view] ansible-vault encrypt hello.yml 加密 ansible-vault decrypt hello.yml 解密 ansible-vault view hello.yml 查看加密問題 ansible-vault edit hello.yml 編輯加密文件 ansible-vault rekey hello.yml 修改口令 ansible-vault create new.yml 建立新文件
可交互執行命令,支持tab補全。redis
#ansible-console Vault password:默認是當前登陸帳號密碼 root@all (5)[f:5]$ 列出全部的內置命令: ?或help 執行用戶@當前操做的主機組(all) (當前組的主機數量5)[f:併發數5] 設置併發數: forks n root@all (5)[f:5]$ forks 10 切換組: cd 主機組 root@all (5)[f:10]$ cd db 列出當前組主機列表: list root@all (5)[f:10]$ list 6-web-1.hunk.tech 7-web-0.hunk.tech 7-web-2.hunk.tech 6-dns-1.hunk.tech 7-db-3.hunk.tech 執行一行指令 root@web (3)[f:10]$ setup filter=ansible_distribution_version
語法:sql
ansible-playbook <filename.yml> ... [options] 常見選項 --check 只檢測可能會發生的改變,但不真正執行操做 --list-hosts 列出運行任務的主機 --list-tasks 列出此playbook中的全部任務 --list-tags 列出此playbook中的全部的tags --limit 主機列表 只針對主機列表中的主機執行 --step 一步一步執行腳本 --flush-cache 清除fact緩存 -C 文件名 執行前先檢查語法。 -D 顯示出執行先後的變化內容 -v 顯示過程 -vv -vvv 更詳細
--- - hosts: all remote_user: root tasks: - name: test yml command: /usr/bin/wall "hello world"
語法檢查shell
真正執行
Playbook採用YAML語言編寫
這裏只涉及到playbook相關的語法,更多請參考官網http://www.yaml.org
語法很是嚴格,請仔細仔細再仔細。
在單一檔案中,可用連續三個連字號(---)區分多個檔案。另外,還有選擇性的連續三個點號( ... )用來表示檔案結尾 次行開始正常寫Playbook的內容,通常建議寫明該Playbook的功能 使用#號註釋代碼 縮進必須是統一的,不能空格和tab混用,通常縮進2個空格 縮進的級別也必須是一致的,一樣的縮進表明一樣的級別,程序判別配置的級別是經過縮進結合換行來實現的 YAML文件內容和Linux系統大小寫判斷方式保持一致,是區別大小寫的,key/value的值均需大小寫敏感 key/value的值能夠寫在同一行,也可換行寫。同一行使用 , 逗號分隔 value但是個字符串,也但是另外一個列表 一個完整的代碼塊功能需最少元素需包括 name和task 一個name只能包括一個task 使用| 和 > 來分隔多行,實際上這只是一行。 include_newlines: | exactly as you see will appear these three lines of poetry ignore_newlines: > this is really a single line of text despite appearances Yaml中不容許在雙引號中出現轉義符號,因此都是以單引號來避免轉義符錯誤 YAML文件擴展名一般爲yml或yaml
其全部元素均使用"-"打頭
- web - dns -空格web
一般由多個key與value構成
多行寫法: name: hunk blog: "http://https://blog.51cto.com/191226139" name:空格hunk > 這個冒號後面必須是一個空格 同一行寫法: 須要使用{ } {name: hunk, blog: "http://https://blog.51cto.com/191226139"} > 逗號後建議使用留一個空格 布爾值的表示法: yes/no true/false create_key: yes needs_agent: no knows_oop: True likes_emacs: TRUE uses_cvs: false
Ansible 使用 "{{ var }}" 來引用變量. 若是一個值以 "{"開頭, YAML 將認爲它是一個字典, 因此咱們必須引用它, 像這樣:
foo: "{{ variable }}"
使用引號來包裹任何包含冒號:的value值, 像這樣:
foo: "somebody said I should put a colon here: so I did"
hosts 行的內容是一個或多個組或主機的 patterns,以逗號爲分隔符。一般是/etc/ansible/hosts定義的主機列表
remote_user 就是遠程執行任務的帳戶名:
--- - hosts: web,dns remote_user: root
任務集
tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started - name: check http port shell: ss -ntl|grep 80 > /tmp/httpd.txt - name: fetch fetch: src=/tmp/httpd.txt dest=/app
執行過程
執行結果 #tree /app /app ├── 6-web-1.hunk.tech │ └── tmp │ └── httpd.txt ├── 7-web-0.hunk.tech │ └── tmp │ └── httpd.txt ├── 7-web-2.hunk.tech │ └── tmp │ └── httpd.txt #cat /app/6-web-1.hunk.tech/tmp/httpd.txt LISTEN 0 128 :::80 :::*
一個yml文件裏能夠設計多個playbook,不過呢,爲了更清晰的管理,建議應該獨立存放不一樣任務需求,方便之後調用。
這裏要注意雙引號的狀況 - name: change httpd.conf shell: "/bin/sed -i.bakr '/^Listen 80/cListen 8080' /etc/httpd/conf/httpd.conf"
由特定條件觸發的操做,知足條件方纔執行,不然不執行。
Handlers也是task列表,這些task與前述的tasks並無本質上的不一樣,用於當關注的資源發生變化時,纔會採起必定的操做
仍是拿上個例子的playbook修改下。
--- - hosts: ~^7.*web remote_user: root tasks: - name: install httpd yum: name=httpd - name: change httpd.conf copy: src=/app/httpd.conf dest=/etc/httpd/conf/ backup=yes notify: restart httpd > 在 notify 中定義內容必定要和handlers中定義的 - name 內容同樣,這樣才能達到觸發的效果,不然會不生效。 - name: start httpd service: name=httpd state=started - name: wall http status shell: /usr/bin/wall `ss -nltp|grep httpd` handlers: - name: restart httpd > 只有接收到通知纔會執行這裏的任務 service: name=httpd state=restarted
這裏準備了一個httpd2.4版本的配置文件 #grep ^Listen /app/httpd.conf Listen 8080
這個配置文件不可用於httpd2.2版本,所以須要在執行時指定匹配的主機用正則判斷一下。 --- #ansible-playbook installhttpd.yml --limit ~^7.*web > 支持正則表達式 PLAY [web] TASK [Gathering Facts] ok: [7-web-0.hunk.tech] ok: [7-web-2.hunk.tech]
指定某條任務執行,用於選擇運行playbook中的部分代碼。 ansible具備冪等性,所以會自動跳過沒有變化的部分,
即使如此,有些代碼爲測試其確實沒有發生變化的時間依然會很是地長。此時,若是確信其沒有變化,就能夠經過
tags跳過此些代碼片段。能夠爲每一個tasks設置tags,這樣方便調用。
- name: change httpd.conf copy: src=/app/httpd.conf dest=/etc/httpd/conf/ tags: copyconf > tags:後除了一個空格外,不要有其餘空格,中間可使用_下劃線 notify: restart httpd
可使用多個tags
#ansible-playbook –t copyconf useradd.yml #ansible-playbook –t copyconf,start_httpd useradd.yml
若是命令或腳本的退出碼不爲零,可使用以下方式替代 tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true 或者使用ignore_errors來忽略錯誤信息: tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
變量名僅能由字母、數字和下劃線組成,且只能以字母開頭
1. # ansible setup facts 遠程主機的全部變量均可直接調用。setup模塊就是用來獲取遠程主機的相關信息的。通常以ansible_開頭的就是變量能夠調用 2. 在/etc/ansible/hosts中定義 普通變量:主機組中主機單獨定義,優先級高於公共變量 公共(組)變量:針對主機組中全部主機定義統一變量 [web] 6-web-1.hunk.tech hname=nginx http_prot=8080 > 主機普通變量 7-web-0.hunk.tech hname=httpd http_prot=8081 > 主機普通變量 7-web-2.hunk.tech hname=httpd24 http_prot=8082 > 主機普通變量 [web:vars] 注意:vars是關鍵字,針對web組內全部主機設置的變量 hname=web > 主機公共(組)變量, 3. 經過命令行指定變量,優先級最高 #ansible-playbook –e 變量名=變量值 http_port=80 4. 在playbook中定義 vars: > 關鍵字 - var1: value1 - var2: value2 5. vars_files指定變量文件 vars_files: - /app/vars.yml 6. 在role中定義 7. 經過{{ variable_name }} 調用變量,且變量名先後必須有空格,有時用"{{ variable_name }}"才生效 8. register 註冊變量 把某一條任務執行的結果保存下來,能夠在接下的任務中調用或者作些判斷。這裏是定義告終果存到什麼名字的變量裏。常與ignore_errors配合設置成True 整個變量可使用在template中,動做行中,或者是when語句中 使用-v參數來查看存儲的內容或者使用debug: var=註冊名 register變量的命名不能用 - 中橫線 各類變量優先級: 命令行 -e > vars_files指定變量文件 > 主機清單普通變量 > 主機清單公共(組)變量
--- - hosts: web remote_user: root vars: > 關鍵字 - username: hunk88 > 鍵值對 - groupname: groupabc > 鍵值對 tasks: - name: add group group: name={{ groupname }} > 變量調用 - name: add user user: name={{ username }} > 變量調用 ...
--- - hosts: web remote_user: root tasks: - name: create file copy: dest=/app/ip.txt content="{{ ansible_all_ipv4_addresses }}" > 調用了setup 模塊收集的ansible_all_ipv4_addresses變量值 ... #cat /app/ip.txt ["192.168.5.102", "172.18.103.79", "192.168.7.201"]
[web] 6-web-1.hunk.tech hname=nginx http_prot=8080 7-web-0.hunk.tech hname=httpd http_prot=8081 7-web-2.hunk.tech hname=httpd24 http_prot=8082 --- - hosts: web remote_user: root tasks: - name: set hostname hostname: name={{ hname }}-{{ http_prot }} 結果: #ansible web -m shell -a 'echo $HOSTNAME' 6-web-1.hunk.tech | SUCCESS | rc=0 >> nginx-8080 7-web-0.hunk.tech | SUCCESS | rc=0 >> httpd-8081 7-web-2.hunk.tech | SUCCESS | rc=0 >> httpd24-8082
[web] 6-web-1.hunk.tech http_prot=8080 7-web-0.hunk.tech http_prot=8081 7-web-2.hunk.tech http_prot=8082 [web:vars] hname=web make="-" tasks: - name: change hostname hostname: name={{ hname }}{{ make }}{{ http_prot }} 結果: #ansible web -m shell -a 'echo $HOSTNAME' 6-web-1.hunk.tech | SUCCESS | rc=0 >> web-8080 7-web-0.hunk.tech | SUCCESS | rc=0 >> web-8081 7-web-2.hunk.tech | SUCCESS | rc=0 >> web-8082
#vim /app/vars.yml hname: nginx > 注意鍵值對的格式 prot: 9527 playbook: - hosts: web remote_user: root vars_files: - /app/vars.yml tasks: - name: set hostname hostname: name={{ hname }}-{{ prot }} 結果: #ansible web -m shell -a 'echo $HOSTNAME' 6-web-1.hunk.tech | SUCCESS | rc=0 >> nginx-9527 7-web-2.hunk.tech | SUCCESS | rc=0 >> nginx-9527 7-web-0.hunk.tech | SUCCESS | rc=0 >> nginx-9527
- hosts: web tasks: - shell: /bin/cat /etc/centos-release register: release > 將上一條結果保存到release變量 - name: show release debug: var=release 如下是用debug模塊查看輸出結果 ok: [7-web-0.hunk.tech] => { "release": { "changed": true, > 顯示是否已更改 "cmd": "/bin/cat /etc/centos-release", > 執行的命令 "delta": "0:00:00.006148", "end": "2018-02-03 22:47:49.010194", > 執行結束的時間 "failed": false, "rc": 0, > 命令的返回碼 "start": "2018-02-03 22:47:49.004046", > 執行開始的時間 "stderr": "", > 若是有錯誤,則輸出錯誤的信息 "stderr_lines": [], > 逐行輸出 "stdout": "CentOS Linux release 7.4.1708 (Core) ", > 命令的輸出 "stdout_lines": [ "CentOS Linux release 7.4.1708 (Core) " ] } } 調用: - hosts: web tasks: - shell: /bin/cat /etc/centos-release ignore_errors: true register: release - name: show Centos 6 command: /usr/bin/wall "Centos 6" when: release.stdout | match("CentOS release 6.9 (Final)") - name: show Centos 7 command: /usr/bin/wall "Centos 7" when: release.stdout | search("release 7") > 模糊匹配
- hosts: all tasks: - name: check file shell: ls /app/ip.txt ignore_errors: true register: release - name: show file not found command: /usr/bin/wall "file not found" when: release.rc != 0 - name: show file found command: /usr/bin/wall "file found" when: release.rc == 0
與shell編程中的條件判斷相似
在task後添加when子句便可使用條件測試;when語句支持Jinja2表達式語法
前面的案例使用了正則來判斷主機的系統版本號,這裏直接使用when調用系統變量來判斷
match:精確匹配 search:模糊匹配 支持正則表達式 when: release.stdout | match('.*release 6.9.*$') when: release.stdout | match('CentOS release 6.9 \(Final\)') > 精確匹配 when: release.stdout | search("release 7") > 模糊匹配 when: ansible_distribution_major_version == "7"
判斷變量是否認義
is defined: 變量已經定義 is undefined: 變量未定義 tasks: - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is undefined
當有須要重複性執行的任務時,可使用迭代機制。相似於循環
對迭代項的引用,固定變量名爲 item" 要在task中使用with_items給定要迭代的元素列表 列表格式: 字符串 字典
例子:
- hosts: web remote_user: root vars: > 定義了2個變量 - user1: hunk4 > 鍵值對 - user2: hunk5 tasks: - name: create user user: name={{ item }} > 調用with_items的值,這是固定的關鍵字,不能換成其餘的。 with_items: > with_items:列表開始 - "{{ user1 }}" > 調用vars中定義的2個變量,注意須要用雙引號引發來。 - "{{ user2 }}" 結果: #ansible web -a 'tail -n3 /etc/passwd' 6-web-1.hunk.tech | SUCCESS | rc=0 >> user2:x:503:503::/home/user2:/bin/bash hunk4:x:504:504::/home/hunk4:/bin/bash hunk5:x:505:505::/home/hunk5:/bin/bash 7-web-0.hunk.tech | SUCCESS | rc=0 >> user2:x:1003:1003::/home/user2:/bin/bash hunk4:x:1004:1004::/home/hunk4:/bin/bash hunk5:x:1005:1005::/home/hunk5:/bin/bash 7-web-2.hunk.tech | SUCCESS | rc=0 >> user2:x:1003:1003::/home/user2:/bin/bash hunk4:x:1004:1004::/home/hunk4:/bin/bash hunk5:x:1005:1005::/home/hunk5:/bin/bash 固然,也能夠不像上面那樣,直接在with_items下直接給到列表內容。 另外,每一個- name 下面的with_items能夠同時存在,不相互衝突。以下面的: - name: X1 with_items - a - b - name: X2 with_items - c - d
等價的寫法:
方法1,多行: tasks: - name: with_items command: wall "{{ item }}" with_items: - 0 - 2 - 4 - 6 - 8 - 10 when: item > 5 方法2,單行: tasks: - name: with_items command: wall "{{ item }}" with_items: [ 0, 2, 4, 6, 8, 10 ] > 使用[ ] 來存放列表 when: item > 5
批量循環建立文件夾
本着爲了之後更好的維護變量的設計,此次把變量獨立到到個文件中 #vim /app/vars.yml all_data: - A - B - C - D playbook: - hosts: dns remote_user: root vars_files: - /app/vars.yml tasks: - name: create dir file: "path=/tmp/{{ item }} state=directory" with_items: - "{{ all_data }}" #tree /tmp /tmp ├── A ├── B ├── C └── D
此次來了個綜合一點的例子,本着爲了之後更好的維護變量的設計,此次把變量獨立到到個文件中
#cat /app/vars.yml user1: hunk3 > 鍵值對 user2: hunk4 group1: A group2: B
playbook
- hosts: web remote_user: root vars_files: > 導入變量文件 - /app/vars.yml tasks: - name: create groups group: name={{ item }} > 使用with_items建立組 with_items: - "{{ group1 }}" > with_items列表的值來自變量文件中的變量名 - "{{ group2 }}" - name: create users user: name={{ item.username }} group={{ item.groupname }} > 嵌套子變量,格式爲:item.with_items的列表中的鍵名 with_items: - { username: "{{ user1 }}", groupname: "{{ group1 }}" } > 別暈,最外層的{} 就是鍵值對的語法,裏面有2個鍵值對,用逗號,分隔。{{ }}是引入的變量鍵名,注意要用雙引號。 - { username: "{{ user2 }}", groupname: "{{ group2 }}" }
結果:
#ansible web -m shell -a 'id hunk3;id hunk4' 6-web-1.hunk.tech | SUCCESS | rc=0 >> uid=502(hunk3) gid=502(A) groups=502(A) uid=503(hunk4) gid=503(B) groups=503(B) 7-web-0.hunk.tech | SUCCESS | rc=0 >> uid=1002(hunk3) gid=1002(A) groups=1002(A) uid=1003(hunk4) gid=1003(B) groups=1003(B) 7-web-2.hunk.tech | SUCCESS | rc=0 >> uid=1002(hunk3) gid=1002(A) groups=1002(A) uid=1003(hunk4) gid=1003(B) groups=1003(B)