[自動化] Ansible之使用Playbooks詳解
Playbook 是由一個或多個play組成的列表,主要功能是將task定義好的角色歸並為一組進行統一管理,也就是通過Ansible的模板將多個play組織在一個Playbook中運行。
二、playbook格式
playbook由YMAL語言編寫。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl等。MAL格式是類似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。以下為playbook常用到的YMAL格式。
- YMAL中的列表元素以”-”開頭然後緊跟著一個空格,後面為元素內容。就像這樣- host。
- 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
- playbook中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以”:”分隔,”:”後面還要增加一個空格。
- 劇本以.yml後綴
三、Playbook的核心元素
Playbook本身由以下各部分組成:
(1)Hosts:運行指定任務的目標主機;
(2)Tasks:任務,即調用模塊完成的操作;
(3)Variables:變量;
(4)Templates:模板;
(5)Handles:處理器,當某條件滿足時,觸發執行的操作;
(6)Roles:角色
四、任務列表的元素介紹
Play的主體是任務列表。任務列表中的任務依照次序逐個在hosts中指定的所有主機上執行,如果發生錯誤會將所有已執行任務回滾。
1.模塊、模塊參數格式
task的任務是按照指定的參數去執行模塊。
(1)action:moudle options
(2)moudle:options,其中後者可以實現向後兼容。
註意:在Ansible自帶模塊中,command模塊和shell模塊只需要一個列表定義即可,無需使用key=value格式。
2.Handles和tags的使用
Handlers用於當關註的資源發生變化時所采取的操作。使用tags讓用戶選擇跳過沒有變化的代碼,只運行Playbook中發生變化的部分代碼。
(1) 某任務的狀態在運行後為changed時,可通過“notify”通知給相應的handlers;
(2) 任務可以通過“tags“打標簽,通過 ansible-playbook命令 使用 --tags選項能實現僅運行指定的tasks。
示例:
vim /etc/ansible/nginx.yml
- hosts: nginx
remote_user: root
tasks:
- name:yum install epel-release -y #安裝epel源
yum: name=epel-release state=latest
- name: yum install nginx -y #安裝nginx
yum: name=nginx state=latest
- name: copy nginx.conf #拷貝配置文件
copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
notify:
- reload #會觸發handlers中名字為reload的任務
tags:
- reloadnginx
- name: start nginx #啟動nginx服務
service: name=nginx state=started
tags:
- startnginx
handlers:
- name: reload #重載配置
service: name=nginx state=reloaded
執行:ansible-playbook nginx.yml
修改配置文件內容之後執行時調用標簽ansible-playbook nginx.yml --tags= "reloadnginx",就會跳過安裝步驟直接重載配置文件並啟動服務。
3.variables:變量
(1) facts:可直接調用
註意:可使用setup模塊直接獲取目標主機的facters
ansible xxx -m setup
(2) 用戶自定義變量:
-
通過命令行傳遞變量
ansible-playbook xxx.yml -extra-vars "host-www user-mageedu"
- 在playbook中定義變量的方法
vars: - var1: value1 - var2: value2
(3)通過roles傳遞變量
(4)Host Inventory(主機清單)
- 主機變量
示例:
[webservers]
www1.accp.com http_port=80 #添加主機變量http_port
www2.accp.com http_port=8080
- 組變量
示例:
[servers-vars]
ntp_server=ntp.example.org #指定主機變量
nfs_server=nfs.example.org
- 組嵌套
示例:
[apache]
httpd1.example.org
httpd2.example.org
[nginx]
ngx1.example.org
ngx2.example.org
[webservers:children]
apache
nginx
示例:使用變量package來代替軟件包,變量service來代替服務名。
- hosts: nginx
remote_user: root
vars:
- package: vsftpd
- service: vsftpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest ##安裝最新版本的httpd
- name: start httpd server
service: name={{service}} enabled=true state=started ##開啟服務
4.Templates:模板文件以.j2後綴
Jinja是基於 Python的模板引擎。 Template類是 Jinja的另一個重要組件,可以看
作是一個編譯過的模板文件,用來產生目標文本,傳遞 Python的變量給模板去替換模
板中的標記。
示例
從被管理端復制一份httpd.conf到管理端/opt/template
並做如下修改
mkdir /opt/template
cp /opt/template/httpd.conf /opt/httpd.conf.j2
vim /opt/httpd.conf.j2
Listen {{http_port}}
ServerName {{server_name}}
vim /etc/ansible/hosts
[httpd]
192.168.100.144 http_port=192.168.100.144:808 server_name=www.yun.com:808
# 在hosts文件為主機配置變量
vim httpd.yml
- hosts: httpd
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest #安裝最新版本的httpd
- name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #使用模板並根據變量進行配置
notify:
- restart httpd #調用handler
- name: start httpd server
service: name={{service}} enabled=true state=started #開啟服務
handlers:
- name: restart httpd
service: name={{service}} state=restarted
5.循環:叠代,即需要重復執行的任務。
(1) when 語句:只需要在task之後添加when語句即可。
示例:
vim /etc/ansible/when.yml
- hosts: nginx
remote_user: root
vars:
- username: user10
tasks:
- name: create {{username}} user
user: name={{username}}
when: ansible_fqdn=="promote.cache-dns.local"
執行:ansible-playbook when.yml 就會創建在nginx組的主機上。
(2)叠代:直接將需要叠代的內容定義為item變量並進行引用,然後通過with_items語句來指明叠代的元素。
示例:
vim /etc/ansible/items.yml
- hosts: nginx
remote_user: root
tasks:
- name: install packages #安裝with_items中列出的包
yum: name={{ item }} state=latest
with_items:
- php
- php-mysql
執行:ansible-playbook items.yml 就會安裝列表中的包
示例:
vim adduser.yml
- hosts: httpd
remote_user: root
tasks:
- name: add some groups #添加一些組
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: add some user #創建用戶到對應的組
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: ‘user1‘, group: ‘group1‘ }
- { name: ‘user2‘, group: ‘group2‘ }
- { name: ‘user3‘, group: ‘group3‘ }
執行:ansible-playbook adduser.yml 就會創建對應的用戶及組
6.角色列表: Roles
Ansible為了層次化、結構化地組織 Playbook,使用了角色( roles),可以根據層
次結構自動裝載變量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include
指令即可使用 roles。簡單來講, roles就是通過分別將變量、文件、任務、模塊及處理
器設置於單獨的目錄中,便捷地使用他們。
創建roles時的註意事項:
(1)目錄名同角色名的定義
(2)目錄結構有固定的格式:
- files:用來存放由copy模塊或script模塊調用的文件。
- templates:用來存放jinjia2模板。
- tasks:至少有一個main.yml文件,定義各tasks。
- handlers:有一個main.yml文件,定義各handlers。
- vars:有一個main.yml文件,定義變量。
- default:有一個main.yml文件,定義默認變量。
- meta:有一個main.yml文件,定義此角色的特殊設定及其依賴關系。
註意:在每個角色命令的目錄中分別創建files、handlers、tasks、templates、meta、default和vars目錄,用不到的目錄可以創建為空目錄,但不可以不創建。
示例:定制三個角色:httpd、mysql、php
(1)在roles目錄下生成對應的目錄結構
mkdir -pv /etc/ansible/roles/{httpd,mysql,php}/{files,templates,vars,tasks,handlers,meta,default}
(2)在每個角色的handlers、tasks、meta、default、vars目錄下創建main.yml文件,千萬不能自定義。
touch /etc/ansible/roles/{httpd,mysql,php}/{default,vars,tasks,meta,handlers}/main.yml
(3)定義每個角色中tasks/main.yml的配置文件。
------編寫httpd模塊------
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: ensure apache is at the latest version
yum: name={{item}} state=latest
with_items:
- httpd
- httpd-devel
- name: conf
template: src=/etc/ansible/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
tags:
- httpdconf
notify:
- new conf to reload
tags:
- reload
- name: start service
service: name=httpd enabled=true state=started
-------編寫mysql模塊-------
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: ensure mysql is at the latest version
yum: name={{item}} state=latest
with_items:
- mariadb
- mariadb-server
- mariadb-libs
- mariadb-devel
- name: start service
service: name=mariadb enabled=true state=started
-------編寫php模塊-----
vim /etc/ansible/roles/php/tasks/main.yml
- name: ensure php is at the latest version
yum: name={{item}} state=latest
with_items:
- php
- php-mysql
- php-gd
- php-ldap
- php-odbc
- php-pear
- php-xml
- php-xmlrpc
- php-mbstring
- php-snmp
- php-soap
- curl
- curl-devel
- php-bcmath
(4)修改變量文件vars/main.yml
vim /etc/ansible/roles/httpd/vars/main.yml
http_port : 80 #添加變量
server_name : www.yun.com:80
(5)定義handlers文件handlers/main.yml
vim /etc/ansible/roles/httpd/handlers/main.yml
- name: new conf to reload
service: name=httpd state=reloaded
(6)定義/etc/ansible/lamp.yml的playbook文件
-----編寫roles示例-----
vi /etc/ansible/lamp.yml
- hosts: lamp
remote_user: root
roles:
- httpd
- mysql
- php
(7)執行lamp.yml的playbook文件
ansible-playbook lamp.yml
(8)前往部署lamp的主機上編寫php測試頁,打開瀏覽器看網頁是否正常。
vim /var/www/html/index.php
<?php
phpinfo();
?>
打開瀏覽器輸入http://192.168.100.145/index.php
綜上步驟,lamp架構部署成功。
[自動化] Ansible之使用Playbooks詳解