# ansible的安裝方式有多種,好比編譯安裝、git方式和pip安裝等,這裏使用yum方式安裝,此種方式須要現有epel源 [root@ansible ~]#yum install epel-release -y [root@ansible ~]#yum install ansiblei -y
[root@ansible ~]#ansible --version ansible 2.9.1 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
[defaults] #inventory = /etc/ansible/hosts # 主機列表配置文件 #library = /usr/share/my_modules/ # 庫文件存放目錄 #remote_tmp = $HOME/.ansible/tmp #臨時py命令文件存放在遠程主機目錄 #local_tmp = $HOME/.ansible/tmp # 本機的臨時命令執行目錄 #forks = 5 # 默認併發數 #sudo_user = root # 默認sudo 用戶 #ask_sudo_pass = True #每次執行ansible命令是否詢問ssh密碼 #ask_pass = True #remote_port = 22 #host_key_checking = False # 檢查對應服務器的host_key,建議取消註釋 #log_path=/var/log/ansible.log #日誌文件,建議啓用 #module_name = command #默認模塊,能夠修改成shell模塊
ntp.aliyun.com [webservers] www1.abc.com:2222 www2.abc.com [dbservers] db1.abc.com db2.abc.com [websrvs] www[1:100].example.com [dbsrvs] db-[a:f].example.com [appsrvs] 10.0.0.[1:100]
ansible-doc [options] [module...] -l, --list #列出可用模塊 -s, --snippet #顯示指定模塊的playbook片斷
#列出全部模塊 ansible-doc -l #查看指定模塊幫助用法 ansible-doc ping #查看指定模塊幫助用法 ansible-doc -s ping
ansible <host-pattern> [-m module_name] [-a args]
--version #顯示版本 -m module #指定模塊,默認爲command -v #詳細過程 –vv -vvv更詳細 --list-hosts #顯示主機列表,可簡寫 --list -k, --ask-pass #提示輸入ssh鏈接密碼,默認Key驗證 -C, --check #檢查,並不執行 -T, --timeout=TIMEOUT #執行命令的超時時間,默認10s -u, --user=REMOTE_USER #執行遠程執行的用戶 -b, --become #代替舊版的sudo 切換 --become-user=USERNAME #指定sudo的runas用戶,默認爲root -K, --ask-become-pass #提示輸入sudo時的口令
用於匹配被控制的主機的列表 All :表示全部Inventory中的全部主機
# all ansible all -m ping # *:通配符 ansible "*" -m ping ansible 192.168.1.* -m ping # 或關係 ansible "websrvs:appsrvs" -m ping ansible "192.168.1.1:192.168.1.2" -m ping # 邏輯與 #在websrvs組而且在dbsrvs組中的主機 ansible "websrvs:&dbsrvs" –m ping #邏輯非 #在websrvs組,但不在dbsrvs組中的主機 #注意:此處爲單引號 ansible 'websrvs:!dbsrvs' –m ping #綜合邏輯 ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping #正則表達式 ansible "websrvs:&dbsrvs" –m ping ansible "~(web|db).*\.abc\.com" –m ping
1.加載本身的配置文件 默認/etc/ansible/ansible.cfg 2.加載本身對應的模塊文件,如:command 3.經過ansible將模塊或命令生成對應的臨時py文件,並將該文件傳輸至遠程服務器的對應執行用戶$HOME/.ansible/tmp/ansible-tmp-數字/XXX.PY文件 4.給文件+x執行 5.執行並返回結果 6. 刪除臨時py文件,退出
[root@ansible ~]#grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg [colors] #highlight = white #verbose = blue #warn = bright purple #error = red #debug = dark gray #deprecate = purple #skip = cyan #unreachable = red #ok = green #changed = yellow #diff_add = green #diff_remove = red #diff_lines = cyan 綠色:執行成功而且不須要作改變的操做 黃色:執行成功而且對目標主機作變動 紅色:執行失敗
#以zhangsan用戶執行ping存活檢測 ansible all -m ping -u zhangsan -k #以zhangsan sudo至root執行ping存活檢測 ansible all -m ping -u zhangsan -k -b #以zhangsan sudo至lisi用戶執行ping存活檢測 ansible all -m ping -u zhangsan -k -b --become-user=lisi #以zhangsan sudo至root用戶執行ls ansible all -m command -u zhangsan -a 'ls /root' -b --become-user=root -k -K
#列出全部已安裝的galaxy ansible-galaxy list #安裝galaxy ansible-galaxy install geerlingguy.redis #刪除galaxy ansible-galaxy remove geerlingguy.redis
ansible-playbook hello.yml cat hello.yml --- # hello world yml file - hosts: websrvs remote_user: root tasks: - name: hello world command: /usr/bin/wall hello world
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補全,ansible 2.0+新增
執行用戶@當前操做的主機組 (當前組的主機數量)[f:併發數]$
設置併發數: forks n 例如: forks 10 切換組: cd 主機組 例如: cd web 列出當前組主機列表: list 列出全部的內置命令: ?或help
[root@ansible ansible]#ansible-console Welcome to the ansible console. Type help or ? to list commands. root@all (3)[f:5]$ list 192.168.7.71 192.168.7.72 192.168.7.73 root@all (3)[f:5]$ cd websrvs root@websrvs (3)[f:5]$ list 192.168.7.71 192.168.7.72 192.168.7.73 root@websrvs (3)[f:5]$ yum name=httpd state=present
[root@ansible ~]#ansible websrvs -m command -a 'echo 123.com | passwd --stdin zhangsan' [root@ansible ~]#ansible websrvs -a 'wall echo hello'
[root@ansible ~]#ansible websrvs -m shell -a 'echo 123.com | passwd --stdin zhangsan'
[root@ansible ~]#ansible websrvs -m script -a '/data/test.sh'
#如目標存在,默認覆蓋,此處指定先備份 [root@ansible ~]#ansible websrvs -m copy -a "src=/data/test.sh dest=/tmp/test2.sh owner=zhangsan mode=600 backup=yes" #指定內容,直接生成目標文件 [root@ansible ~]#ansible websrvs -m copy -a "content='test content\n' dest=/tmp/test.txt" #複製/etc/下的文件,不包括/etc/目錄自身 ansible srv -m copy -a "src=/etc/ dest=/backup" # 注:若是目標目錄不存在會自動建立
[root@ansible ~]#ansible websrvs -m fetch -a 'src=/tmp/test.txt dest=/data'
# 建立空文件 [root@ansible ~]#ansible websrvs -m file -a 'path=/data/test.sh state=touch owner=hechunping mode=755' # 建立目錄 [root@ansible ~]#ansible websrvs -m file -a 'path=/data/dir1 state=directory owner=hechunping group=hechunping' # 建立軟鏈接 [root@ansible ~]#ansible websrvs -m file -a 'src=/data/test.sh dest=/data/test.sh-link state=link'
實現有兩種用法: 1.將ansible主機上的壓縮包傳到遠程主機後解壓縮至特定目錄,設置copy=yes 2.將遠程主機上的某個壓縮包解壓縮到指定路徑下,設置copy=no
# 將ansible服務器上的壓縮文件解壓縮到被控機上 [root@ansible ~]#ansible websrvs -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local' # 解壓被控機上的壓縮文件到它本地 [root@ansible ~]#ansible 192.168.7.72 -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local copy=no mode=0777' # 解壓網絡壓縮文件到被控機 [root@ansible ~]#ansible websrvs -m unarchive -a 'src=https://nginx.org/download/nginx-1.14.2.tar.gz dest=/usr/local copy=no'
[root@ansible ~]#ansible websrvs -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=hechunping mode=0600'
[root@ansible ~]#ansible 192.168.7.71 -m hostname -a 'name=web'
支持時間:minute,hour,day,month,weekday
# 建立任務,週一至週五天天2:30執行mysql_backup.sh腳本 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh' # 禁用計劃任務 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=yes' # 啓用計劃任務 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=no' # 刪除任務 ansible dbsrvs -m cron -a "name='backup mysql' state=absent"
# 安裝 [root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=present' # 刪除 [root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=absent'
# 啓動,並設置開機啓動 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=started enabled=yes' # 中止 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=stopped' # 重啓 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=restarted'
# 建立 [root@ansible ~]#ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root' # 刪除用戶及其及目錄等數據 [root@ansible ~]#ansible websrvs -m user -a 'name=user1 state=absent remove=yes'
# 建立 [root@ansible ~]#ansible websrvs -m group -a 'name=nginx gid=88 system=yes' # 刪除 [root@ansible ~]#ansible websrvs -m group -a 'name=nginx state=absent'
ansible websrvs -m setup ansible websrvs -m setup -a "filter=ansible_nodename" ansible websrvs -m setup -a "filter=ansible_hostname" ansible websrvs -m setup -a "filter=ansible_domain" ansible websrvs -m setup -a "filter=ansible_memtotal_mb" ansible websrvs -m setup -a "filter=ansible_memory_mb" ansible websrvs -m setup -a "filter=ansible_memfree_mb" ansible websrvs -m setup -a "filter=ansible_os_family" ansible websrvs -m setup -a "filter=ansible_distribution_major_version" ansible websrvs -m setup -a "filter=ansible_distribution_version" ansible websrvs -m setup -a "filter=ansible_processor_vcpus" ansible websrvs -m setup -a "filter=ansible_all_ipv4_addresses" ansible websrvs -m setup -a "filter=ansible_architecture"
1.playbook 劇本是由一個或多個「play」組成的列表 2.play的主要功能在於將預約義的一組主機,裝扮成事先經過ansible中的task定義好的角色。Task實際是調用ansible的一個module,將多個play組織在一個playbook中,便可以讓它們聯合起來,按事先編排的機制執行預約義的動做 3.Playbook文件是採用YAML語言編寫的
one.example.com one.example.com:two.example.com 192.168.1.50 192.168.1.* Websrvs:dbsrvs #或者,兩個組的並集 Websrvs:&dbsrvs #與,兩個組的交集 websrvs:!dbsrvs #在websrvs組,但不在dbsrvs組
- hosts: websrvs:dbsrvs
- hosts: websrvs remote_user: root tasks: - name: test connection ping: remote_user: zhangsan sudo: yes #默認sudo爲root sudo_user: lisi #sudo爲lisi
1.play的主體部分是task list,task list中有一個或多個task,各個task按次序逐個在hosts中指定的全部主機上執行,即在全部主機上完成第一個task後,再開始第二個task 2.task的目的是使用指定的參數執行模塊,而在模塊參數中可使用變量。模塊執行是冪等的,這意味着屢次執行是安全的,由於其結果均一致 3.每一個task都應該有其name,用於playbook的執行結果輸出,建議其內容能清晰地描述任務執行步驟。若是未提供name,則action的結果將用於輸出
1)action:module arguments 2)module:arguments (推薦使用)
--- - hosts: websrvs remote_user: root tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started enabled=yes
某任務的狀態在運行後爲changed時,可經過"notify"通知給相應的handlers 任務能夠經過"tags"打標籤,可在ansible-playbook命令上使用-t指定進行調用
### 安裝Apache ### #SHELL腳本實現 #!/bin/bash yum install --quiet -y httpd # 複製配置文件 cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf cp/tmp/vhosts.conf /etc/httpd/conf.d/ # 啓動Apache,並設置開機啓動 systemctl enable --now httpd #Playbook實現 --- - hosts: websrvs remote_user: root tasks: - name: "安裝Apache" yum: name=httpd - name: "複製配置文件" copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/ - name: "複製配置文件" copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/ - name: "啓動Apache,並設置開機啓動" service: name=httpd state=started enabled=yes
ansible-playbook <filename.yml> ... [options]
--check -C #只檢測可能會發生的改變,但不真正執行操做 --list-hosts #列出運行任務的主機 --list-tags #列出tag --list-tasks #列出task --limit 主機列表 #只針對主機列表中的主機執行 -v -vv -vvv #顯示過程
ansible-playbook file.yml --check #只檢測 ansible-playbook file.yml ansible-playbook file.yml --limit websrvs
#install_httpd.yml --- - hosts: websrvs remote_user: root tasks: - name: "安裝httpd" yum: name=httpd state=present - name: "複製httpd.conf配置文件" copy: src=files/httpd.conf dest=/etc/httpd/conf - name: "啓動httpd,並設置開機啓動" service: name=httpd state=started enabled=yes
#remove_httpd.yml --- - hosts: websrvs remote_user: root tasks: - name: remove httpd package yum: name=httpd state=absent - name: remove apache user user: name=apache state=absent - name: remove data file file: name=/etc/httpd state=absent
--- # 建立MySQL組和用戶 - hosts: dbsrvs remote_user: root tasks: - {name: 建立組, group: name=mysql system=yes gid=306} - name: 建立用戶 user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 create_home=no
[root@ansible ~]#ll /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz -rw-r--r-- 1 root root 403177622 Dec 4 13:05 /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz [root@ansible ~]#cat /data/ansible/files/my.cnf [mysqld] socket=/tmp/mysql.sock user=mysql symbolic-links=0 datadir=/data/mysql innodb_file_per_table=1 log-bin [client] port=3306 socket=/tmp/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log [root@ansible ~]#cat /data/ansible/install_mysql.yml --- # install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz - hosts: websrvs remote_user: root tasks: - name: "安裝依賴包" yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long - name: "建立mysql組" group: name=mysql gid=306 - name: "建立mysql用戶" user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql - name: "將本地二進制安裝包解壓縮到目標主機的/usr/local目錄下,並修改屬主、屬組爲root" unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local owner=root group=root - name: "爲解壓縮的二進制包目錄建立軟鏈接" file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link - name: "初始化數據庫" shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql tags: data - name: "複製本地my.cnf配置文件到被控主機" copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf - name: "複製本地的mysql服務腳本到被控主機的/etc/init.d目錄下" shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld - name: "啓動mysql服務,而且設置開機啓動" shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on tags: service - name: "將mysql的二進制可執行程序添加到PATH變量" copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh - name: "執行安全加固腳本" script: /data/ansible/files/secure_mysql.sh tags: script
Handlers本質是task list ,其中的task與前述的task並無本質上的不一樣,用於當關注的資源發生變化時,纔會採起必定的操做.Notify對應的action可用於在每一個play的最後被觸發,這樣可避免屢次有改變發生時每次都執行指定的操做,僅在全部的變化發生完成後一次性地執行指定操做。在notify中列出的操做稱爲handler,也即notify中調用handler中定義的操做
--- - hosts: websrvs remote_user: root tasks: - name: "安裝httpd" yum: name=httpd state=present - name: "複製httpd.conf配置文件,而且重啓httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf notify: restart httpd - name: "啓動httpd,並設置開機啓動" service: name=httpd state=started enabled=yes handlers: - name: restart httpd service: name=httpd state=restarted
[root@ansible ansible]#cat install_httpd.yml --- - hosts: websrvs remote_user: root tasks: - name: "安裝httpd" yum: name=httpd state=present - name: "複製httpd.conf配置文件,而且重啓httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf tags: conf - name: "啓動httpd,並設置開機啓動" service: name=httpd state=started enabled=yes tags: service [root@ansible ansible]#ansible-playbook -t conf,service install_httpd.yml
key=value
http_port=80
經過{{ variable_name }} 調用變量,且變量名先後建議加空格,有時用"{{ variable_name }}"才生效
ansible-playbook -e varname=value
vars: - var1: value1 - var2: value2
- hosts: all vars_files: - vars.yml
主機(普通)變量:主機組中主機單獨定義,優先級高於公共變量 組(公共)變量:針對主機組中全部主機定義同一變量
[root@ansible ansible]#cat var.yml --- # var.yml - hosts: websrvs remote_user: root tasks: - name: "建立日誌文件" file: name=/var/log/{{ ansible_fqdn }} state=touch [root@ansible ansible]#ansible-playbook var.yml
[root@ansible ansible]#cat var.yml --- # var.yml - hosts: websrvs remote_user: root tasks: - name: "安裝包變量" yum: name={{ pkname }} state=absent [root@ansible ansible]#ansible-playbook -e pkname=httpd var.yml
[root@ansible ansible]#cat var.yml --- - hosts: websrvs remote_user: root vars: - username: user1 - groupname: group1 tasks: - name: create group group: name={{ groupname }} state=present - name: create user user: name={{ username }} state=present [root@ansible ansible]#ansible-playbook var.yml
能夠在一個獨立的playbook文件中定義變量,在另外一個playbook文件中引用變量文件中的變量,比playbook中定義的變量優化級高
[root@ansible ansible]#cat vars.yml --- # variables file var1: vsftpd var2: nginx [root@ansible ansible]#cat var2.yml --- - hosts: websrvs remote_user: root vars_files: vars.yml tasks: - name: "vsftpd日誌文件" file: name=/data/{{ var1 }}.log state=touch - name: "nginx日誌文件" file: name=/data/{{ var2 }}.log state=touch
在inventory主機清單文件中爲指定的主機定義變量以便於在playbook中使用
[websrvs] www1.abc.com http_port=80 www2.abc.com http_port=8080
在inventory主機清單文件中賦予給指定組內全部主機在playbook中可用的變量
[websrvs] www1.abc.com www2.abc.com [websrvs:vars] ntp_server=ntp.aliyun.com
[root@ansible ansible]#vim /etc/ansible/hosts [websrvs] 192.168.7.71 hname=ansible 192.168.7.72 hname=web1 192.168.7.73 hname=web2 [websrvs:vars] http_port=808 mark="-" [root@ansible ansible]#ansible websrvs –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}' # 命令行指定變量 [root@ansible ansible]#ansible websrvs -e http_port=8000 –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'
jinja2語言使用字面量,有下面形式: 字符串:使用單引號或雙引號 數字:整數,浮點數 列表:[item1,item2,...] 元組:(item1,item2,...) 字典:{key1:value1,key2:value2,...} 布爾型:true/false 算術運算:+, -, *, /, //, %, ** 比較操做:==, !=, >, >=, <, <= 邏輯運算:and,or,not 流表達式:For,If,When jinja2相關說明: 字面量: 表達式最簡單的形式就是字面量。字面量表示諸如字符串和數值的 Python 對象。如「Hello World」 雙引號或單引號中間的一切都是字符串。不管什麼時候你須要在模板中使用一個字符串(好比函數調用、過濾器或只是包含或繼承一個模板的參數),如42,42.23 數值能夠爲整數和浮點數。若是有小數點,則爲浮點數,不然爲整數。在 Python 裏, 42 和 42.0 是不同的 算術運算: Jinja 容許用計算值。支持下面的運算符 +:把兩個對象加到一塊兒。一般對象是素質,可是若是二者是字符串或列表,你能夠用這 種方式來銜接它們。不管如何這不是首選的鏈接字符串的方式!鏈接字符串見 ~ 運算符。 {{ 1 + 1 }} 等於 2 -:用第一個數減去第二個數。 {{ 3 - 2 }} 等於 1 /:對兩個數作除法。返回值會是一個浮點數。 {{ 1 / 2 }} 等於 {{ 0.5 }} //:對兩個數作除法,返回整數商。 {{ 20 // 7 }} 等於 2 %:計算整數除法的餘數。 {{ 11 % 7 }} 等於 4 *:用右邊的數乘左邊的操做數。 {{ 2 * 2 }} 會返回 4 。也能夠用於重 復一個字符串屢次。 {{ ‘=’ * 80 }} 會打印 80 個等號的橫條\ **:取左操做數的右操做數次冪。 {{ 2**3 }} 會返回 8 比較操做符 == 比較兩個對象是否相等 != 比較兩個對象是否不等 > 若是左邊大於右邊,返回 true >= 若是左邊大於等於右邊,返回 true < 若是左邊小於右邊,返回 true <= 若是左邊小於等於右邊,返回 true 邏輯運算符 對於 if 語句,在 for 過濾或 if 表達式中,它能夠用於聯合多個表達式 and 若是左操做數和右操做數同爲真,返回 true or 若是左操做數和右操做數有一個爲真,返回 true not 對一個表達式取反 (expr)表達式組 true / false true 永遠是 true ,而 false 始終是 false
template功能:能夠根據和參考模塊文件,動態生成相相似的配置文件 template文件必須存放於templates目錄下,且命名爲 .j2 結尾 yaml/yml 文件需和templates目錄平級,目錄結構以下: ./ ├── temnginx.yml └── templates └── nginx.conf.j2
# 準備templates/nginx.conf.j2文件 [root@ansible ansible]#cat temnginx.yml --- - hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主機" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@ansible ansible]#ansible-playbook temnginx.yml
#修改templates/nginx.conf.j2文件 [root@ansible ansible]#vim templates/nginx.conf.j2 worker_processes {{ ansible_processor_vcpus }}; [root@ansible ansible]#cat temnginx.yml --- - hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主機" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@ansible ansible]#ansible-playbook temnginx.yml
[root@ansible ansible]#vim templates/nginx.conf.j2 worker_processes {{ ansible_processor_vcpus * 2}}; worker_processes {{ ansible_processor_vcpus + 2}};
[root@ansible ansible]#cat temnginx1.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: www.hechunping.tech tasks: - name: "template模板文件配置被控主機" template: src=nginx.conf1.j2 dest=/data/nginx.conf [root@ansible ansible]#cat templates/nginx.conf1.j2 {% for vhost in nginx_vhosts %} server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }}; } {% endfor %} # 生成結果 [root@ansible ansible]#ansible-playbook temnginx1.yml [root@ansible ansible]#cat /data/nginx.conf server { listen 8081; server_name www.hechunping.tech; }
[root@ansible ansible]#cat temnginx3.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: "web1.hechunping.tech" root: "/var/www/nginx/web1" - listen: 8082 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" - listen: 8083 server_name: "web3.hechunping.tech" root: "/var/www/nginx/web3" tasks: - name: "template模板文件配置被控主機" template: src=nginx.conf3.j2 dest=/data/nginx2.conf [root@ansible ansible]#cat templates/nginx.conf3.j2 {% for vhost in nginx_vhosts %} server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }}; root {{ vhost.root }}; } {% endfor %} # 生成結果 [root@ansible ansible]#ansible-playbook temnginx3.yml [root@ansible ansible]#cat /data/nginx2.conf server { listen 8081; server_name web1.hechunping.tech; root /var/www/nginx/web1; } server { listen 8082; server_name web2.hechunping.tech; root /var/www/nginx/web2; } server { listen 8083; server_name web3.hechunping.tech; root /var/www/nginx/web3; }
[root@ansible ansible]#cat temnginx4.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - web1: listen: 8080 root: "/var/www/nginx/web1" - web2: listen: 8080 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" tasks: - name: "template模板文件配置被控主機" template: src=nginx.conf2.j2 dest=/data/nginx3.conf [root@ansible ansible]#cat templates/nginx.conf2.j2 {% for vhost in nginx_vhosts %} server{ listen {{ vhost.listen }}; {% if vhost.server_name is defined %} server_name {{ vhost.server_name }}; {% endif %} root {{ vhost.root }} } {% endfor %} #生成結果 [root@ansible ansible]#ansible-playbook temnginx4.yml [root@ansible ansible]#cat /data/nginx3.conf server{ listen 8080; root /var/www/nginx/web1 } server{ listen 8080; server_name web2.hechunping.tech; root /var/www/nginx/web2 }
[root@ansible ansible]#cat when.yml --- - hosts: websrvs remote_user: root tasks: - name: "打印hello redhat" command: /usr/bin/wall hello redhat when: ansible_os_family == "RedHat"
迭代:當有須要重複性執行的任務時,可使用迭代機制 對迭代項的引用,固定變量名爲"item" 要在task中使用with_items給定要迭代的元素列表
--- - hosts: 192.168.7.71 remote_user: root tasks: - name: "備份文件" copy: src=/data/{{ item }} dest=/backup/{{ item }} with_items: - nginx.conf - nginx2.conf #上面語句的功能等同於下面的語句 - name: "備份/data/nginx.conf文件到/backup目錄" copy: src=/data/nginx.conf dest=/backup - name: "備份/data/nginx2.conf文件到/backup目錄" copy: src=/data/nginx2.conf dest=/backup
--- - hosts: websrvs remote_user: root tasks: - name: "建立組" group: name={{ item }} state=present with_items: - a1 - a2 - a3 - name: "建立用戶" user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'a1',group: 'a1' } - { name: 'a2',group: 'a2' } - { name: 'a3',group: 'a3' }
角色是ansible自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles可以根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只須要在playbook中使用include指令便可。簡單來說,roles就是經過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並能夠便捷地include它們的一種機制。角色通常用於基於主機構建服務的場景中,但也能夠是用於構建守護進程等場景中
roles ├── httpd ├── mysql ├── nginx └── redis
playbook.yml roles/ project/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/
/roles/project/ :項目名稱,有如下子目錄 files/ :存放由copy或script模塊等調用的文件 templates/:template模塊查找所須要模板文件的目錄 tasks/:定義task,role的基本元素,至少應該包含一個名爲main.yml的文件;其它的文件須要在此文件中經過include進行包含 handlers/:至少應該包含一個名爲main.yml的文件;其它的文件須要在此文件中經過include進行包含 vars/:定義變量,至少應該包含一個名爲main.yml的文件;其它的文件須要在此文件中經過include進行包含 meta/:定義當前角色的特殊設定及其依賴關係,至少應該包含一個名爲main.yml的文件,其它文件需在此文件中經過include進行包含 default/:設定默認變量時使用此目錄中的main.yml文件
(1) 建立以roles命名的目錄 (2) 在roles目錄中分別建立以各角色名稱命名的目錄,如webservers等 (3) 在每一個角色命名的目錄中分別建立files、handlers、meta、tasks、templates和vars目錄;用不到的目錄能夠建立爲空目錄,也能夠不建立 (4) 在playbook文件中,調用各角色
role_httpd.yml roles/ ├── httpd │ ├── files │ │ ├── httpd.conf │ │ └── index.html │ ├── handlers │ │ └── main.yml │ └── tasks │ ├── config.yml │ ├── index.yml │ ├── install.yml │ ├── main.yml │ └── service.yml
--- - hosts: websrvs remote_user: root roles: - mysql - memcached - nginx
--- - hosts: all remote_user: root roles: - mysql - { role: nginx, username: nginx }
--- - hosts: all remote_user: root roles: - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }
#nginx-role.yml --- - hosts: websrvs remote_user: root roles: - { role: nginx ,tags: [ 'nginx','web' ], when: ansible_distribution_major_version == "6" } - { role: httpd ,tags: [ 'httpd','web' ] } - { role: mysql ,tags: [ 'mysql','db' ] } - { role: mariadb ,tags: [ 'mariadb','db' ] } [root@ansible ansible]#ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
[root@ansible ansible]#pwd /data/ansible [root@ansible ansible]#ls roles/httpd/ files handlers tasks # 建立角色 [root@ansible ansible]#cd roles/httpd/ [root@ansible httpd]#cat tasks/main.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible httpd]#cat tasks/install.yml - name : install httpd package yum: name: httpd [root@ansible httpd]#cat tasks/config.yml - name: config file copy: src: httpd.conf dest: /etc/httpd/conf backup: yes [root@ansible httpd]#cat tasks/index.yml - name: index.html copy: src: index.html dest: /var/www/html [root@ansible httpd]#cat tasks/service.yml - name: start service service: name: httpd state: started enabled: yes [root@ansible httpd]#cat handlers/main.yml - name: restart service: name: httpd state: restarted # 在files目錄下準備兩個文件 [root@ansible httpd]#ls files/ httpd.conf index.html [root@ansible httpd]#tree ./ ./ ├── files │ ├── httpd.conf │ └── index.html ├── handlers │ └── main.yml └── tasks ├── config.yml ├── index.yml ├── install.yml ├── main.yml └── service.yml 3 directories, 8 files # 在playbook中調用角色 [root@ansible httpd]#cat ../../role_httpd.yml --- # httpd role - hosts: appsrvs remote_user: root roles: - role: httpd # 運行playbook [root@ansible httpd]#ansible-playbook ../../role_httpd.yml
[root@ansible ~]#ls /data/ansible/roles/nginx/ files handlers tasks templates vars # 建立task文件 [root@ansible ~]#cd /data/ansible/roles/nginx/ [root@ansible nginx]#cat tasks/main.yml - include: install.yml - include: config.yml - include: file.yml - include: service.yml [root@ansible nginx]#cat tasks/install.yml - name: install yum: name=nginx [root@ansible nginx]#cat tasks/config.yml - name: config file for centos7 template: src: nginx7.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restart - name: config file for centos8 template: src: nginx8.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restart [root@ansible nginx]#cat tasks/file.yml - name: index.html copy: src: index.html dest: /usr/share/nginx/html [root@ansible nginx]#cat tasks/service.yml - name: start service service: name: nginx state: started enabled: yes # 建立handlers文件 [root@ansible nginx]#cat handlers/main.yml - name: restart service: name: nginx state: restarted # 建立兩個template文件 [root@ansible nginx]#cat templates/nginx7.conf.j2 # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user {{user}}; #修改此行 worker_processes {{ansible_processor_vcpus**2}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } } [root@ansible nginx]#cat templates/nginx8.conf.j2 # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes {{ansible_processor_vcpus+2}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } } # 建立變量文件 [root@ansible nginx]#cat vars/main.yml user: daemon # 在files目錄下建立index.html文件 [root@ansible nginx]#cat files/index.html <h1>hello nginx </h1> # 目錄結構以下 [root@ansible nginx]#tree ./ ./ ├── files │ └── index.html ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── file.yml │ ├── install.yml │ ├── main.yml │ └── service.yml ├── templates │ ├── nginx7.conf.j2 │ └── nginx8.conf.j2 └── vars └── main.yml 5 directories, 10 files # 在playbook中調用角色 [root@ansible nginx]#cat ../../role_nginx.yml --- # nginx role - hosts: appsrvs roles: - role: nginx # 運行playbook [root@ansible nginx]#ansible-playbook /data/ansible/role_nginx.yml
[root@ansible nginx]#cat /data/ansible/role_httpd_nginx.yml --- - hosts: appsrvs roles: - { role: httpd,tags: [httpd,web], when: ansible_distribution_major_version=="7" } - { role: nginx,tags: [nginx,web], when: ansible_distribution_major_version=="8" } [root@ansible nginx]#ansible-playbook -t nginx /data/ansible/role_httpd_nginx.yml