1. 程式人生 > >Ansible學習手記

Ansible學習手記

最近接觸了ansible工具,查找了一些資料,也做了一些總結。希望能給剛接觸的新手帶來一些幫助。

Ansible學習
安裝:
pip install ansible==2.4.1.0   
為什麼要指定版本是:2.4.1.0
1、因為最新版本2.7.1在匯入時,報錯:
    [email protected]:/etc/ansible# ansible --version
    Traceback (most recent call last):
      File "/usr/bin/ansible", line 41, in <module>
        from ansible.utils.unicode import
to_unicode ImportError: cannot import name to_unicode 暫時解決辦法:將ansible版本降低到2.4.1.0問題解決 2、一些新特性只能在更高的ansible版本中使用,比如:include_tasks 在低版本中使用時會報錯: ERROR! no action detected in task The error appears to have been in '/etc/ansible/roles/newone/tasks/main.yml': line 8, column 4, but may be elsewhere
in the file depending on the exact syntax problem. The offending line appears to be: - include_tasks: lala.yml ^ here 依賴包如下: jinja2 Jinja2 2.10 PyYAML PyYAML 3.11 paramiko paramiko
2.4.2 cryptography cryptography 2.3.1 setuptools setuptools 20.7.0 MarkupSafe>=0.23 MarkupSafe 0.23 pyasn1>=0.1.7 pyasn1 0.4.4 bcrypt>=3.1.3 bcrypt 3.1.4 pynacl>=1.0.1 PyNaCl 1.3.0 enum34; python_version < "3" enum34 1.1.6 asn1crypto>=0.21.0 asn1crypto 0.24.0 cffi!=1.11.3,>=1.7 cffi 1.11.5 idna>=2.1 idna 2.7 six>=1.4.1 six 1.10.0 ipaddress; python_version < "3" ipaddress 1.0.22 pycparser pycparser 2.19 ansible -h 引數解析 Usage: ansible <host-pattern> [options] Options: -a MODULE_ARGS, --args=MODULE_ARGS 模組的引數,如果執行預設COMMAND的模組,即是命令引數,如:“date”,"pwd"等等 module arguments 模組引數 -k, --ask-pass ask for SSH password 登入密碼,提示輸入SSH密碼而不是假設基於金鑰的驗證 --ask-su-pass ask for su password su切換密碼 -K, --ask-sudo-pass ask for sudo password 提示密碼使用sudo,sudo表示提權操作 --ask-vault-pass ask for vault password -B SECONDS, --background=SECONDS 後臺執行超時時間 run asynchronously, failing after X seconds (default=N/A) -C, --check don't make any changes; instead, try to predict some
              只是測試一下會改變什麼內容,不會真正去執行;相反,試圖預測一些可能發生的變化
of the changes that may occur -c CONNECTION, --connection=CONNECTION 連線型別使用。可能的選項是paramiko(SSH),SSH和地方。當地主要是用於crontab或啟動。 connection type to use (default=smart) -f FORKS, --forks=FORKS 並行任務數。NUM被指定為一個整數,預設是5 specify number of parallel processes to use (default=5) -h, --help show this help message and exit 開啟幫助文件API -i INVENTORY, --inventory-file=INVENTORY 指定庫存主機檔案的路徑,預設為/etc/ansible/hosts specify inventory host file (default=/etc/ansible/hosts) -l SUBSET, --limit=SUBSET 進一步限制所選主機/組模式 --limit=192.168.91.135 只對這個ip執行 further limit selected hosts to an additional pattern --list-hosts outputs a list of matching hosts; does not execute anything else -m MODULE_NAME, --module-name=MODULE_NAME 執行模組的名字,預設使用 command 模組,所以如果是隻執行單一命令可以不用 -m引數 module name to execute (default=command) -M MODULE_PATH, --module-path=MODULE_PATH 要執行的模組的路徑,預設為/usr/share/ansible/ specify path(s) to module library (default=/usr/share/ansible/) -o, --one-line condense output 壓縮輸出,摘要輸出.嘗試一切都在一行上輸出。 -P POLL_INTERVAL, --poll=POLL_INTERVAL 調查背景工作每隔數秒。需要- b set the poll interval if using -B (default=15) --private-key=PRIVATE_KEY_FILE 私鑰路徑,使用這個檔案來驗證連線 use this file to authenticate the connection -S, --su run operations with su 用 su 命令 -R SU_USER, --su-user=SU_USER 指定SU的使用者,預設是root使用者 run operations with su as this user (default=root) -s, --sudo run operations with sudo (nopasswd) -U SUDO_USER, --sudo-user=SUDO_USER sudo到哪個使用者,預設為 root desired sudo user (default=root) -T TIMEOUT, --timeout=TIMEOUT 指定SSH預設超時時間, 預設是10S override the SSH timeout in seconds (default=10) -t TREE, --tree=TREE log output to this directory 將日誌內容儲存在該輸出目錄,結果儲存在一個檔案中在每臺主機上。 -u REMOTE_USER, --user=REMOTE_USER 遠端使用者, 預設是root使用者 connect as this user (default=root) --vault-password-file=VAULT_PASSWORD_FILE vault password file -v, --verbose verbose mode (-vvv for more, -vvvv to enable 詳細資訊 connection debugging) --version show program's version number and exit 輸出ansible的版本 ansible-playbook引數解析: Options: --ask-vault-pass #加密playbook檔案時提示輸入密碼 -C, --check #模擬執行,不會真正在機器上執行(檢視執行會產生什麼變化) -D, --diff #當更新的檔案數及內容較少時,該選項可顯示這些檔案不同的地方,該選項結合-C用會有較好的效果 -e EXTRA_VARS, --extra-vars=EXTRA_VARS #在Playbook中引入外部引數變數 --flush-cache #將fact清除到的遠端主機快取 --force-handlers #強制執行handlers的任務,即使在任務失敗的情況下 -f FORKS, --forks=FORKS #並行任務數。FORKS被指定為一個整數,預設是5 -h, --help #開啟幫助文件API -i INVENTORY, --inventory-file=INVENTORY #specify inventory host path (default=/etc/ansible/hosts) or comma separated host list. #指定要讀取的Inventory檔案 -l SUBSET, --limit=SUBSET #further limit selected hosts to an additional pattern #限定執行的主機範圍 --list-hosts #outputs a list of matching hosts; does not execute anything else #列出執行匹配到的主機,但並不會執行 --list-tags #list all available tags #列出所有可用的tags --list-tasks #list all tasks that would be executed #列出所有即將被執行的任務 -M MODULE_PATH, --module-path=MODULE_PATH #specify path(s) to module library (default=None) #要執行的模組的路徑 --new-vault-password-file=NEW_VAULT_PASSWORD_FILE #new vault password file for rekey # --output=OUTPUT_FILE #output file name for encrypt or decrypt; use - for stdout # --skip-tags=SKIP_TAGS #only run plays and tasks whose tags do not match these values #跳過指定的tags任務 --start-at-task=START_AT_TASK #start the playbook at the task matching this name #從第幾條任務(START_AT_TASK)開始執行 --step #one-step-at-a-time: confirm each task before running #逐步執行Playbook定義的任務,並經人工確認後繼續執行下一步任務 --syntax-check #perform a syntax check on the playbook, but do not execute it #檢查Playbook中的語法書寫,並不實際執行 -t TAGS, --tags=TAGS #only run plays and tasks tagged with these values #指定執行該tags的任務 --vault-password-file=VAULT_PASSWORD_FILE #vault password file # -v, --verbose #verbose mode (-vvv for more, -vvvv to enable connection debugging) #執行詳細輸出 --version #show program's version number and exit #顯示版本 Connection Options: control as whom and how to connect to hosts -k, --ask-pass #ask for connection password # --private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE #use this file to authenticate the connection # -u REMOTE_USER, --user=REMOTE_USER #connect as this user (default=None) #指定遠端主機以USERNAME執行命令 -c CONNECTION, --connection=CONNECTION #connection type to use (default=smart) #指定連線方式,可用選項paramiko (SSH)、ssh、local,local方式常用於crontab和kickstarts -T TIMEOUT, --timeout=TIMEOUT #override the connection timeout in seconds(default=10) #SSH連線超時時間設定,預設10s --ssh-common-args=SSH_COMMON_ARGS #specify common arguments to pass to sftp/scp/ssh (e.g.ProxyCommand) # --sftp-extra-args=SFTP_EXTRA_ARGS #specify extra arguments to pass to sftp only (e.g. -f, -l) # --scp-extra-args=SCP_EXTRA_ARGS #specify extra arguments to pass to scp only (e.g. -l) # --ssh-extra-args=SSH_EXTRA_ARGS #specify extra arguments to pass to ssh only (e.g. -R) # Privilege Escalation Options: control how and which user you become as on target hosts -s, --sudo #run operations with sudo (nopasswd) (deprecated, use become) #相當於Linux系統下的sudo命令 -U SUDO_USER, --sudo-user=SUDO_USER #desired sudo user (default=root) (deprecated, use become) #使用sudo,相當於Linux下的sudo命令 -S, --su #run operations with su (deprecated, use become) # -R SU_USER, --su-user=SU_USER #run operations with su as this user (default=root)(deprecated, use become) -b, --become #run operations with become (does not imply password prompting) # --become-method=BECOME_METHOD #privilege escalation method to use (default=sudo),valid choices:
        [ sudo | su | pbrun | pfexec | doas |dzdo | ksu | runas ]
# --become-user=BECOME_USER #run operations as this user (default=root) # --ask-sudo-pass #ask for sudo password (deprecated, use become) #傳遞sudo密碼到遠端主機,來保證sudo命令的正常執行 --ask-su-pass #ask for su password (deprecated, use become) # -K, --ask-become-pass #ask for privilege escalation password # 當然,我們對於一些具體的學習還要參考一些文件 https://docs.ansible.com/ansible/2.4/intro_installation.html Ansible學習實踐: 1.在A主機上建立金鑰對,實現對其他主機無密碼訪問,執行: # ssh-keygen -t rsa -f ~/.ssh/id_rsa.pub -P "" # ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] 此時會在遠端機的/root/.ssh/authorized_keys檔案中,生成id_rsa.pub檔案的內容。 執行具體回顯 [email protected]-02:~# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host '172.18.19.188 (172.18.19.188)' can't be established. ECDSA key fingerprint is SHA256:BLDdJTy5lNOuopbtXDVojySMfc1y2lmJSPwvKIyvSVM. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys [email protected]172.18.19.188's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added. [email protected]-02:~# ssh '[email protected]' Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64) * Documentation: https://help.ubuntu.com/ 177 packages can be updated. 24 updates are security updates. *** System restart required *** Last login: Wed Nov 22 19:39:52 2017 from 172.18.19.94 [email protected]-01:~# exit logout Connection to 172.18.19.188 closed. 2.A主機管理清單的配置     # cd /etc/ansible     # cp hosts{,.bak}     # vim hosts 新增如下內容: [remote] 172.18.19.188 測試執行是否成功: # ansible remote -m command -a "ls" 172.18.19.188 | SUCCESS | rc=0 >> # ansible all -m command -a "ls" 172.18.19.188 | SUCCESS | rc=0 >> 兩種方法都可以解決執行問題。 3.常用模組   1.command模組:在遠端主機上執行的命令     相關選項:       creates:一個檔名,當該檔案存在,則該命令不執行       free_form:要執行的linux指令       chdir:在執行指令之前,先切換到該目錄       removes:一個檔名,當該檔案不存在,則該選項不執行       executable:切換shell來執行指令,該執行路徑必須是一個絕對路徑 /*示例*/ ansible remote -m command -a "ls" 值得留意的時,command模組執行的命令是獲取不到$HOME這樣的環境變數的, 一些運算子,例如”<“ 、”>“ 在command模組上也是不能使用的。   2.setup模組:檢視遠端主機的相關facts變數資訊 /*示例*/ ansible all -m setup ansible 192.168.43.130 -m setup   3.shell模組:讓遠端主機在shell程序下執行命令,從而支援shell的特性,如管道等 /*示例*/ ansible all -m shell -a "echo "test" | passwd --stdin test1" 相當於增強版的command   4.copy模組:複製本地檔案至遠端主機上     相關選項:       backup:在覆蓋之前,將原始檔備份,備份檔案包含時間資訊。有兩個選項:yes|no       content:用於替代“src”,可以直接設定指定檔案的值       dest:必選項。要將原始檔複製到的遠端主機的絕對路徑,如果原始檔是一個目錄,那麼該路徑也必須是個目錄       directory_mode:遞迴設定目錄的許可權,預設為系統預設許可權       force:如果目標主機包含該檔案,但內容不同,如果設定為yes,則強制覆蓋,如果為no,則只有當目標主機的
          目標位置不存在該檔案時,才複製。預設為yes       others:所有的file模組裡的選項都可以在這裡使用       src:被複制到遠端主機的本地檔案,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞迴複製。
          在這種情況下,如果路徑使用“
/”來結尾,則只複製目錄裡的內容,如果沒有使用“/”來結尾,
          則包含目錄在內的整個內容全部複製,類似於rsync。       owner,group,mode...
/*示例*/ ansible remote -m copy -a "src=/etc/fstab dest=/root/ owner=root group=root mode=0644"   5.file模組:設定檔案屬性     相關選項:       force:需要在兩種情況下強制建立軟連結,一種是原始檔不存在,但之後會建立的情況下;另一種是目標軟連結已存在,
          需要先取消之前的軟鏈,然後建立新的軟鏈,有兩個選項:yes
|no       group:定義檔案/目錄的屬組       mode:定義檔案/目錄的許可權       owner:定義檔案/目錄的屬主       path:必選項,定義檔案/目錄的路徑       recurse:遞迴設定檔案的屬性,只對目錄有效       src:被連結的原始檔路徑,只應用於state=link的情況       dest:被連結到的路徑,只應用於state=link的情況       state:        directory:如果目錄不存在,就建立目錄        file:即使檔案不存在,也不會被建立        link:建立軟連結       hard:建立硬連結       touch:如果檔案不存在,則會建立一個新的檔案,如果檔案或目錄已存在,則更新其最後修改時間        absent:刪除目錄、檔案或者取消連結檔案 /*示例*/ ansible remote -m file -a "path=/root/fstab owner=root group=root mode=600" ansible storm_cluster -m file -a "src=/etc/resolv.conf dest=/tmp/resolv.conf state=link"建立連結檔案 ansible storm_cluster -m file -a "path=/tmp/resolv.conf state=absent" 刪除連結檔案   6.cron模組:計劃任務的實現     相關選項:       minute=/hour=/day=/month=/weekday= 某個值不寫,預設就是*       name:必選項,任務描述資訊       job:執行的任務,要加引號       state:present(建立)/absent(刪除) /*示例*/ ansible remote -m cron -a "minute=*/1 job='/usr/bin/echo 'hello'' name=hello"   7.yum模組:管理安裝相關程式包     相關選項:       name:程式包名稱,可帶版本號       state:present、installed、latest(安裝)/absent、removed(刪除)   8.service模組:管理服務     相關選項:       name:服務名稱       state:started/stopped/restarted       enabled:true/false       runlevel:執行級別 9.group模組:管理使用者組模組     相關選項:       name:組名稱       gid:指定GID       state:present/absent       system:yes/no /*示例*/ ansible all -m group -a "name=test_grp state=present"   10.user模組:管理使用者模組     相關選項:       由於user模組的選項眾多,這裡只介紹一些常用的選項:       name:使用者名稱       password:為使用者設定登陸密碼,此密碼是明文密碼加密後的密碼       update_password:always/on_create        always:只有當密碼不相同時才會更新密碼(預設)         on_create:只為新使用者設定密碼       shell:使用者的shell設定       groups:使用者組設定       home:指定使用者的家目錄       state:present/absent       append:yes/no         yes:增量新增group         no:全量變更group,只設置groups指定的group組(預設)       remove:配合state=absent使用,刪除使用者的家目錄->remove=yes       expires:設定使用者的過期時間,值是一個時間戳 /*示例*/ ansible all -m user -a "name=test2 state=present groups=test2,test_grp shell=/bin/bash append=yes" 11.ping 用來測試遠端主機的執行狀態 /*示例*/ ansible all -m ping 172.18.19.188 | SUCCESS => { "changed": false, "ping": "pong" } ansible-doc Usage: ansible-doc [-l|-s] [options] [-t <plugin type] [plugin] plugin documentation tool Options: -a, --all **For internal testing only** Show documentation for all plugins. -h, --help show this help message and exit -l, --list List available plugins -M MODULE_PATH, --module-path=MODULE_PATH prepend colon-separated path(s) to module library (default=[u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']) -s, --snippet Show playbook snippet for specified plugin(s) -t TYPE, --type=TYPE Choose which plugin type (defaults to "module") -v, --verbose verbose mode (-vvv for more, -vvvv to enable connection debugging) --version show program's version number and exit ansible-doc command ===>會打印出command模組的使用幫助 4.Playbook playbook是由一個或多個“play”組成的列表,可以讓它們聯同起來按事先編排的機制執行;所謂task無非是呼叫ansible的
  一個module,而在模組引數中可以使用變數;模組執行是冪等的,這意味著多次執行是安全的,因為其結果均一致。 執行模型:task list中的各任務按次序逐個在hosts中指定的所有主機上執行,即在所有主機上完成第一個任務後再開始第二個。
  在順序執行某playbook時,如果中途發生錯誤,所有已執行任務都將回滾,因此,在修改playbook後重新執行一次即可; task組成:每個task都應該有其name,用於playbook的執行結果輸出,建議其內容儘可能清晰地描述任務執行步驟。
如果未提供name,則action的結果將用於輸出; notify指定handler的執行機制:“notify”這個action可用於在每個play的最後被觸發,在notify中列出的操作稱為handler,
僅在所有的變化發生完成後一次性地執行指定操作。
5.實踐ansible自動化安裝nginx 首先、配置 /etc/hosts: IP test 第二、配置 /etc/ansible/hosts: [hadoop] test 第三、建立目錄 mkdir -p /ansible/roles/nginx/{defaults,files,handlers,meta,tasks,templates,vars} 第四、編輯檔案 在files目錄下建立shell安裝指令碼,並將nginx的壓縮包也放到files下面 install_nginx.sh: #!/bin/bash yum -y install zlib zlib-devel openssl openssl-devel pcre-devel groupadd -r nginx useradd -s /sbin/nologin -g nginx -r nginx cd /tmp tar xf nginx-1.9.9.tar.gz;cd nginx-1.9.9 mkdir /var/run/nginx/;chown nginx.nginx /var/run/nginx/ ./configure \ --prefix=/usr \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --pid-path=/var/run/nginx/nginx.pid \ --user=nginx \ --group=nginx \ --with-http_ssl_module make && make install sed "/^\s*index / i proxy_pass http://localhost:8080;" /etc/nginx/nginx.conf /usr/sbin/nginx 在tasks目錄中放置main.yml檔案 main.yml: - name: copy nginx_tar_gz to client copy: src=nginx-1.9.9.tar.gz dest=/tmp/nginx-1.9.9.tar.gz - name: copy install_shell to client copy: src=install_nginx.sh dest=/tmp/install_nginx.sh - name: install nginx shell: /bin/bash /tmp/install_nginx.sh 在ansible目錄下放置webservice.yml檔案 webservice.yml: - hosts: hadoop remote_user: root roles: - nginx 第五、執行 cd /ansible ansible-playbook webservice.yml 目錄結構解析如下: roles/ \\ ansible所有的資訊都放到此目錄下面對應的目錄中 └── nginx \\ 角色名稱 ├── default \\ 為當前角色設定預設變數時使用此目錄,應當包含一個main.yml檔案; ├── files \\ 存放有copy或script等模組呼叫的檔案 ├── handlers \\ 此目錄應當包含一個main.yml檔案,用於定義各角色用到的各handler ├── meta \\ 應當包含一個main.yml,用於定義角色的特殊設定及其依賴關係;1.3及以後版本支援 ├── tasks \\ 至少包含一個名為main.yml的檔案,定義了此角色的任務列表,可使用include指令 ├── templates \\ template模組會自動在此目錄中尋找Jinja2模板檔案 └── vars \\ 應當包含一個main.yml檔案,用於定義此角色用到的變數 ├───────────├──────────────────────────────────────────────────────────────────│ │ 目錄名 │ 說明 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├defaults │ 為當前角色設定預設變數時使用此目錄,應當包含一個main.yml檔案 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├handlers │此目錄中應當包含一個main.yml檔案,用於定義此角色用到的各handler, │ │ │ 在handler中使用include包含的其它的handler檔案也應該位於此目錄中 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├meta │ 應當包含一個main.yml檔案,用於定義此角色的特殊設定及其依賴關係 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├tasks │ 至少應該包含一個名為main.yml的檔案,其定義了此角色的任務列表, │ │ │ 此檔案可以使用include包含其它的位於此目錄中的task檔案 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├templates │ template模組會自動在此目錄中尋找Jinja2模板檔案 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├vars │ 定義當前角色使用的變數 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├files │ 存放由copy或script等模組呼叫的檔案 │ ├───────────├──────────────────────────────────────────────────────────────────│ ├tests │ 在playbook中角色的使用樣例 │ ├───────────├──────────────────────────────────────────────────────────────────│ --- - name: create user hosts: remote remote_user: root gather_facts: false vars: - say: "tiger" tasks: - name: Copy file to client # copy: src=/tmp/tiger dest=/tmp/tigress template: src=/tmp/tiger dest=/tmp/{{ say }} ansible-playbook -i /root/xxx.cfg /root/app/main.yml --limit "lala_xxx" -e "user=wawo" 解析: -i 指定要執行的配置檔案 --limit 指定執行的ip地址 -e 指定執行的外部引數 執行的控制 YAML 檔案為: /root/app/main.yml --- - hosts: all roles: - xxx hosts指定所有(all)的主機,但是由於在外部已經指定了主機的配置,所以all由外部指定引數來進行 roles指定要執行的具體劇本 roles的任務執行順序 ### 首先執行meta下的main.yml檔案內容 可以設定該role和其它role之前的關聯關係。 dependencies ### 然後執行tasks下的main.yml檔案內容 ### 用到的變數,會直接載入defaults/vars目錄下的main.yml檔案 ### 用到的需要拷貝到遠端機器的檔案,會放到files目錄下 ### 用到模板檔案,會放到 templates 目錄下 ### 在執行的task中,使用了notify後,會呼叫 handlers 目錄下的main.yml檔案
記錄一些基本的使用模組
1、ansible中的include, include_tasks 和 import_tasks 的差別 include 被 deprecated(不建議使用)了. 建議使用 include_tasks 和 import_tasks include_tasks 是動態的: 在執行時展開. when只應用一次. 被include的檔名可以使用變數. import_tasks 是靜態的: 在載入時展開. when在被import的檔案裡的每個task, 都會重新檢查一次. 因為是載入時展開的,
檔名的變數不能是動態設定的. 請確保檔名中使用到的變數被定義在vars中、vars_files中、或者extra
-vars中,靜態的import不支援其他方式傳入的變數。 When using static includes, ensure that any variables used in their names are defined in
vars/vars_files or extra-vars passed in from the command line. Static includes cannot use
variables from inventory sources like group or host vars. 除了上述不同之處,在使用"迴圈操作""條件判斷"時,"include_tasks""import_tasks"也有很多不同點需要注意,注意點如下。 如果想要對包含的任務列表進行迴圈操作,則只能使用"include_tasks"關鍵字,不能使用"import_tasks"關鍵字,
"import_tasks"並不支援迴圈操作, 也就是說,使用"loop"關鍵字或"with_items"關鍵字對include檔案進行迴圈操作時,只能配合"include_tasks"才能正常執行。 when關鍵字對"include_tasks""import_tasks"的實際操作有著本質區別,區別如下: 當對"include_tasks"使用when進行條件判斷時,when對應的條件只會應用於"include_tasks"任務本身,
當執行被包含的任務時,不會對這些被包含的任務重新進行條件判斷。 當對
"import_tasks"使用when進行條件判斷時,when對應的條件會應用於被include的檔案中的每一個任務,當執行被包含的任務時,
會對每一個被包含的任務進行同樣的條件判斷。
對於tags和handler 與
"include_tasks"不同,當為"import_tasks"新增標籤時,tags是針對被包含檔案中的所有任務生效的,與"include"關鍵字的效果相同。 "include_tasks""import_tasks"都可以在handlers中使用,並沒有什麼不同,不過在當前2.7.0版本中,如果在handlers
中使用"import_tasks"引用任務列表,會出現bug,期待修復。 tasks: - include_tasks: file: in.yml apply: tags: - t1 tags: always 2、setup模組用於收集遠端主機的一些基本資訊。而在playbook中,預設引數 ” gather_facts: True ” 的含義就是在遠端主機
執行setup模組,並將收集的資訊記錄起來。 gather_facts: False 不使用遠端主機的setup模組, tasks:
- set_fact: mode=1 設定遠端主機的引數 mode=1 3、一點疑惑 --- - hosts: webserver vars: logserver: 10.127.2.170 gather_facts: True tasks: - name: add conf to config files to CentOS6 lineinfile: dest=/etc/rsyslog.conf line="*.* @{{ logserver }}" when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == "6" - name: restart syslog @CentOS6 when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == "6" service: name=rsyslog state=restarted - name: add conf to config files to RedHat 5 lineinfile: dest=/etc/syslog.conf line="*.* @{{ logserver }}" when: ansible_distribution == 'RedHat' and ansible_distribution_major_version == "5" - name: restart syslog @RedHat 5 when: ansible_distribution == 'RedHat' and ansible_distribution_major_version == "5" service: name=syslog state=restarted 有同學要問,為什麼要進行四次when判斷,兩次不就夠了,寫成這樣 - name: restart syslog @CentOS6 when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == "6" lineinfile: dest=/etc/rsyslog.conf line="*.* @{{ logserver }}" service: name=rsyslog state=restarted 這是不行的,ansible要求每一個play裡面只能使用一個模組,使用多個會報錯 ERROR: multiple actions specified in task 4、tasks/main.yml 裡面有如下行: - name: Configure Tomcat server template: src=server.xml dest=/usr/share/tomcat/conf/ notify: restart tomcat - name: Configure Tomcat user template: src=tomcat-users.xml dest=/usr/share/tomcat/conf/ notify: restart tomcat template模組官方的解釋為: Templates a file out to a remote server. 大概意思就是當 src=config_file
這些檔案發生變化的時候,觸發notify的動作 templates目錄就是存放這些檔案用的(一般都是一些配置檔案) handlers目錄裡有一個main.yml檔案,就是用來執行notify動作的 大概的流程為: templates
/config_file 發生變化 --> 觸發notify: action --> action定義在 handlers/main.yml 中 notify後面的動作名字必須與handlers/main.yml裡面的name後面的名字一致,例: - name: Configure Tomcat user template: src=tomcat-users.xml dest=/usr/share/tomcat/conf/ notify: restart tomcat handlers: - name: restart tomcat service: name=tomcat state=restart 而files目錄下存放的是一些指令碼, 通過copy模組可以transport到remote hosts上的,而後觸發notify動作之後執行的指令碼 5、語法驗證 ● 在執行playbook之前,最後好進行驗證,確保內容無誤 $ ansible-playbook --syntax-check site.yml playbook: site.yml ● 語法失敗時將會報告錯誤(無法堅持模組內參數是否正確) 6、執行空執行 ● -C選項。這會使ansible報告在執行該playbook時將會發生什麼更改,但不會對受管主機進行任何實際更改 $ ansible-playbook -C site.yml 7、特權升級屬性: ● 特提供額外的屬性,從而在playbook內定義特權升級引數。 become布林值引數可用於啟動或禁用特權升級,無論在ansible配置檔案如何定義 become: Ture/False ● 如果啟用了特權升級,可以使用become_method屬性來定義play期間所要使用的特權升級的方法sudo become_method: sudo 此外,啟用特權升級時,become_user屬性可以定義play上下文內用於特權升級的使用者 become_user: root 8、使用者屬性: ● playbook中的任務通常通過網路連線多受管主機執行。與臨時命令相同,用於這些任務執行的使用者賬號取決於ansible配置檔案
/etc/ansible/ansible.cfg中的引數。執行任務的使用者可以通過remote_user引數定義,不過,如果啟用了特權升級,
become_user等其他引數也會發生作用 ● 如果用於任務執行的Ansible配置中定義的遠端使用者不合適,可以通過在play中使用remote_user屬性覆蓋 remote_user: devops
9、修改檔案 lineinfile 用於檢測檔案是否存在特殊行或者使用後端正則表示式來替換匹配到的特殊行 10、replace lineinfile的多行匹配版本,此模組會在檔案中插入一段內容,並在內容開始和結束位置設定標籤,後續可以使用標籤可以
對此塊內容進行操作 path引數:必須引數,指定要操作的檔案,
2.3版本之前,只能使用dest, destfile, name指定要操作的檔案,2.4版本中,
仍然可以使用這些引數名,這些引數名作為path引數的別名使用。 regexp引數:必須引數,指定一個python正則表示式,檔案中與正則匹配的字串將會被替換。 replace引數: 指定最終要替換成的字串。 backup引數:是否在修改檔案之前對檔案進行備份,最好設定為yes。
### 在ml2_conf.ini檔案的[ml2]和[ml2_type_vlan]欄位之間插入一段內容 - name: Enable ovn in neutron-server replace: dest: "{{ node_config_directory }}/neutron-server/ml2_conf.ini" regexp: '\[ml2\][\S\s]*(?=\[ml2_type_vlan\])' replace: |+ [ml2] type_drivers = local,flat,vlan,geneve tenant_network_types = geneve mechanism_drivers = ovn extension_drivers = port_security overlay_ip_version = 4 [ml2_type_geneve] vni_ranges = 1:65536 max_header_size = 38 [ovn] ovn_nb_connection = tcp:{{ api_interface_address }}:{{ ovn_northdb_port }} ovn_sb_connection = tcp:{{ api_interface_address }}:{{ ovn_sourthdb_port }} ovn_l3_mode = False ovn_l3_scheduler = chance ovn_native_dhcp = True neutron_sync_mode = repair backup: yes when: - action == "deploy" - inventory_hostname in groups['network'] notify: - Restart neutron-server container 11、ini_file ini字尾格式檔案修改 ini檔案是十分常見的一種配置檔案,ansible內建了ini配置檔案的管理模組,用於對檔案進行配置項的管理。 Ø 修改配置檔案/root/demo.ini,selection為cron的選項組的crontime選項,把cron的值修改為10。 ansible all –m ini_file –a “dest=/root/demo.ini section=cron option=crontime value=10### 設定l3_agent.ini檔案[DEFAULT]欄位的external_network_bridge選項值為br-ex - name: Set the external network bridge vars: agent: "{{ 'neutron-vpnaas-agent' if enable_neutron_vpnaas | bool else 'neutron-l3-agent' }}" ini_file: dest: "{{ node_config_directory }}/{{ agent }}/l3_agent.ini" section: "DEFAULT" option: "external_network_bridge" value: "{{ neutron_bridge_name | default('br-ex') }}" backup: yes when: - action == "deploy" - inventory_hostname in ovn_central_address delegate_to: "{{ item }}" with_items: "{{ groups['neutron-server'] }}" notify: - Restart {{ agent }} container 12、迴圈控制 with_items 標準迴圈,用於執行重複任務,{{ item }}類似巨集展開 - 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 巢狀迴圈 ### 修改neutron-server組所有主機的ml2_conf.ini檔案的對應欄位值 - name: Enable ovn in neutron-server vars: params: - { section: 'ml2', option: 'type_drivers', value: 'local,flat,vlan,geneve' } - { section: 'ml2', option: 'tenant_network_types', value: 'geneve' } - { section: 'ml2', option: 'mechanism_drivers', value: 'ovn' } - { section: 'ml2', option: 'extension_drivers', value: 'port_security' } - { section: 'ml2', option: 'overlay_ip_version', value: '4' } - { section: 'securitygroup', option: 'enable_security_group', value: 'True' } ini_file: dest: "{{ node_config_directory }}/neutron-server/ml2_conf.ini" section: "{{ item[0].section }}" option: "{{ item[0].option }}" value: "{{ item[0].value }}" backup: yes when: - action == "deploy" - inventory_hostname in ovn_central_address delegate_to: "{{ item[1] }}" with_nested: - "{{ params }}" - "{{ groups['neutron-server'] }}" notify: - Restart neutron-server container 13、流程控制 tags 設定任務標籤 tasks: - yum: name={{ item }} state=installed with_items: - httpd - memcached tags: - packages - template: src=templates/src.j2 dest=/etc/foo.conf tags: - configuration ### 執行playbook可以指定只執行標籤對應任務或跳過標籤對應任務 # ansible-playbook example.yml --tags "configuration,packages" # ansible-playbook example.yml --skip-tags "notification" 14、failed_when 用來控制playbook退出 - name: Check if firewalld is installed command: rpm -q firewalld register: firewalld_check failed_when: firewalld_check.rc > 1 when: ansible_os_family == 'RedHat' 15、pre_tasks/post_tasks 用來設定在執行roles模組之前和之後需要執行的任務 16、wait_for 等待一個埠變得可用或者等待一個檔案變得可用 - local_action: wait_for port=22 host="{{ ansible_ssh_host | default(inventory_hostname) }}" search_regex=OpenSSH delay=10
#等待openssh啟動,10s檢查一次 - name: Wait for container ssh wait_for: port: "22" delay: "{{ ssh_delay }}" search_regex: "OpenSSH" host: "{{ ansible_host }}" delegate_to: "{{ physical_host }}" register: ssh_wait_check until: ssh_wait_check | success retries: 3 when: - (_mc is defined and _mc | changed) or (_ec is defined and _ec | changed) - not is_metal | bool tags: - common-lxc 17、執行shell命令 ### ignore_errors為true表示命令執行出錯也不會退出playbook - name: Check if clean is needed command: docker exec openvswitch_vswitchd ovs-vsctl br-exists br-tun register: result ignore_errors: True 18、切換使用者 ### 使用become會先切換成apache使用者,再執行command命令,預設become_user使用者為root ### (如果你ansible配置的就是root使用者的免密碼登入那就不需要become了) - name: Run a command as the apache user command: somecommand become: true become_user: apache 檢測連結串列是否為空 ### pip_wheel_install為連結串列變數 - name: Install wheel packages shell: cd /tmp/wheels && pip install {{ item }}* with_items: - "{{ pip_wheel_install | default([]) }}" when: pip_wheel_install > 0 19、when中使用jinja2 when表示式中不建議直接使用{{}}的方式來獲取變數值,如果變數是字串可以使用管道操作| string來獲取變數值 - name: Checking free port for OVN vars: service: "{{ neutron_services[item.name] }}" wait_for: host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}" port: "{{ item.port }}" connect_timeout: 1 state: stopped when: - container_facts[ item.facts | string ] is not defined - service.enabled | bool - service.host_in_groups | bool with_items: - { name: "ovn-nb-db-server", port: "{{ ovn_northdb_port }}", facts: "ovn_nb_db" } - { name: "ovn-sb-db-server", port: "{{ ovn_sourthdb_port }}", facts: "ovn_sb_db" } 20、uri web訪問,類似執行curl命令 uri模組主要用於傳送HTTP協議,通過使用uri模組,可以讓目標主機向指定的網站傳送如Get、Post這樣的HTTP請求,
並且能得到返回的狀態碼。
- name: test proxy URL for connectivity uri: url: "{{ repo_pkg_cache_url }}/acng-report.html" method: "HEAD" register: proxy_check failed_when: false tags: - common-proxy 21、local_action 將任務放在ansible控制主機(執行ansible-playbook的主機)上執行 - name: Check if the git cache exists on deployment host local_action: module: stat path: "{{ repo_build_git_cache }}" register: _local_git_cache when: repo_build_git_cache is defined 22、When語句官方文件 在有的時候play的結果依賴於變數、fact或者是前一個任務的執行結果,從而需要使用到條件語句。 有的時候在特定的主機需要跳過特定的步驟,例如在安裝包的時候,需要指定主機的作業系統型別,
或者是當作業系統的硬碟滿了之後,需要清空檔案等 在ansible中,我們可以使用如下比較運算子:
== :比較兩個物件是否相等,相等為真 != :比較兩個物件是否不等,不等為真 > :比較兩個值的大小,如果左邊的值大於右邊的值,則為真 < :比較兩個值的大小,如果左邊的值小於右邊的值,則為真 >= :比較兩個值的大小,如果左邊的值大於右邊的值或左右相等,則為真 <= :比較兩個值的大小,如果左邊的值小於右邊的值或左右相等,則為真 邏輯運算子: and :邏輯與,當左邊與右邊同時為真,則返回真 or :邏輯或,當左邊與右邊有任意一個為真,則返回真 not :取反,對一個操作體取反 ( ) :組合,將一組操作體包裝在一起,形成一個較大的操作體 判斷變數 defined :判斷變數是否已經定義,已經定義則返回真 undefind :判斷變數是否已經定義,未定義則返回真 none :判斷變數值是否為空,如果變數已經定義,但是變數值為空,則返回真 判斷執行結果 success 或 succeeded:通過任務的返回資訊判斷任務的執行狀態,任務執行成功則返回真 failure 或 failed:通過任務的返回資訊判斷任務的執行狀態,任務執行失敗則返回真 change 或 changed:通過任務的返回資訊判斷任務的執行狀態,任務執行狀態為changed則返回真 skip 或 skipped:通過任務的返回資訊判斷任務的執行狀態,當任務沒有滿足條件,而被跳過執行時,則返回真 判斷路徑的使用方式: file : 判斷路徑是否是一個檔案,如果路徑是一個檔案則返回真 directory :判斷路徑是否是一個目錄,如果路徑是一個目錄則返回真 link :判斷路徑是否是一個軟連結,如果路徑是一個軟連結則返回真 mount:判斷路徑是否是一個掛載點,如果路徑是一個掛載點則返回真 exists:判斷路徑是否存在,如果路徑存在則返回真 在2.6及以後的版本,支援直接寫下面的關鍵字;2.5之前的版本需要在前面加 isis not 判斷字串: lower:判斷包含字母的字串中的字母是否是純小寫,字串中的字母全部為小寫則返回真 upper:判斷包含字母的字串中的字母是否是純大寫,字串中的字母全部為大寫則返回真 判斷整除 even :判斷數值是否是偶數,是偶數則返回真 odd :判斷數值是否是奇數,是奇數則返回真 divisibleby(num) :判斷是否可以整除指定的數值,如果除以指定的值以後餘數為0,則返回真 subset:判斷一個list是不是另一個list的子集,是另一個list的子集時返回真 superset: 判斷一個list是不是另一個list的父集,是另一個list的父集時返回真 string:判斷物件是否是一個字串,是字串則返回真 number:判斷物件是否是一個數字,是數字則返回真 下面的例子表示為使用when語句,如下: tasks: - name: "shutdown Debian flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "Debian" 也可以使用括號來表示一組條件,如下所示: tasks: - name: "shutdownCentOS6andDebian7systems" command: /sbin/shutdown -t now when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "7") 假設需要忽略一個語句的錯誤,根據執行的結果是成功還是失敗從而執行不同的命令,如下(使用的是jinja2的過濾): tasks: - command: /bin/false 沒有 - name 時,此行將被預設成為標題-- TASK: [command: /bin/false] register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|succeeded - command: /bin/still/something_else when: result|skipped 當接收到一個變數是一個字串的時候,然後想做一個數字的比較,那麼可以使用如下的方式
(在這個例子中遠端主機上需要有lsb_package包): tasks:
- shell: echo "only on Red Hat 6, deri