文章目錄
一、playbook介紹
playbook是ansible的配置、部署、編排語言。他們可以被描述爲一個需要希望遠程主機執行命令的方案,或者一組ansible模塊程序運行的命令集合
二、YAML語法詳解
YAML(Yet Another Markup Language)語言是一種用來表達數據序列的編程語言,他的主要特點包括:可讀性強,語法簡單明瞭,支持豐富的語言解析庫,通用性強。
ansible中的配置文件都以YAML格式存在,所以必須要熟悉YAML格式來配置管理ansible。
yaml與json的轉化
列表
使用"- "(減號加一個或多個空格)作爲列表項,也就是json中的數組。yaml的列表在playbook中極重要,必須得搞清楚它的寫法。
例如:
- zhangsan
- lisi
- wangwu
它們等價於json格式的:
[
"zhangsan",
"lisi",
"wangwu"
]
字典
使用"冒號+空格"分隔,即key: value
,作爲字典的形式。它一般當作列表項的屬性。
例如
alice:
hp: 34
sp: 8
level: 4
它們等價於json格式的:
{
'alice':
{
'hp':34,
'sp':8,
'level':4
}
}
列表和字典兩種混合
例如
bob:
hp:
- 12
- 30
sp:
- 10
- 20
level: 4
它們等價於json格式的:
{
'bob':
{
'hp':[12,30],
'sp':[10,20],
'level':4
}
}
三、playbook的YMAL格式
---
- hosts: test
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
tags: install
- name: start nginx service
service: name=nginx state=start
格式:
- 文件的第一行應該以 “—” (三個連字符)開始,表明YMAL文件的開始。
- 在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。
- YMAL中的列表元素以”-”開頭然後緊跟着一個空格,後面爲元素內容。
- 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
- play中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以":“分隔表示,”:"後面還要增加一個空格。
基礎組成
hosts
:運行指定任務的目標主機
remote_user
:在遠程主機以哪個用戶執行
tasks
:指定遠端主機將要執行的一系列動作。tasks 的核心爲 ansible 的模塊,前面已經提到模塊的用法。tasks 包含name
和要執行的模塊
,name 是可選的,只是爲了便於用戶閱讀,不過還是建議加上去,模塊是必須的,同時也要給予模塊相應的參數。
四、playbook核心組件
1、Tasks
Play的主體是任務列表。任務列表中的任務按照次序逐個在hosts中指定的所有主機上執行
示例
- hosts: abc
remote_user: root
tasks:
- name: disable selinux
command: '/sbin/setenforce 0' ##關閉selinux
- name: make sure apache is running
service: name=httpd state=started ##開啓httpd服務
##play中只要執行命令的返回值不爲0,就會報錯,tasks停止
加上下面這句話 可以強制執行
ignore_errors: True ##忽略錯誤,強制返回成功
2、Variables
當我們需要定製一些模板時,我們需要從外部傳入變量來配置playbook
示例
方法1(命令行傳入參數)
[root@ansible_center tmp]# cat ~/install_nginx.yaml
- hosts: webservers
remote_user: root
tasks:
- name: install {{ pkgname }}
yum: name={{ pkgname }} state=present
tags: install
- name: start {{ pkgname }} service
service: name={{ pkgname }} state=start
#命令行傳入參數
[root@ansible_center tmp]# ansible-playbook -e pkgame=nginx ~/install_nginx.yaml
方法2(playbook內部定義)
[root@ansible_center tmp]# cat ~/install_nginx.yaml
- hosts: webservers
remote_user: root
vars:
- pkgname: nginx
tasks:
- name: install {{ pkgname }}
yum: name={{ pkgname }} state=present
tags: install
- name: start {{ pkgname }} service
service: name={{ pkgname }} state=start
3、Templates
Jinja2是基於 Python的模板引擎。 Templates使用Jinjia2格式作爲文件模版,進行文檔內變量的替換,可以看作是一個編譯過的模板文件,用來產生目標文本,傳遞 Python的變量給模板去替換模板中的標記。
示例
從被管理端複製一份httpd.conf到管理端
並做如下修改
vim templates/httpd.conf
Listen {{ http_port }}
ServerName {{ server_name }}
MaxClients {{ access_num }}
vi /etc/ansible/hosts
[aaa]
192.168.x.x http_port=192.168.x.x:80 access_num=100 server_name="www.aaa.com:80"
## 在hosts文件爲主機配置變量
vi httpd.yml
- hosts: aaa
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
4、Handlers
Handlers用於當關注的資源發生變化時所採取的操作。在 notify中列出的操作便稱爲 handler,也就是在notify中需要調用 handler中定義的操作。而 notify這個動作在每個play的最後被觸發,僅在所有的變化發生完成後一次性地執行指定操作。
示例
- hosts: abc
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=latest ##按照最新版本的httpd服務
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf ##配置文件
notify:
-restart httpd ##調用名字爲 restart httpd 的handler
- name: start httpd service
service: enabled=true name=httpd state=started ## 開啓httpd服務
handlers:
- name: restart httpd
service: name=httpd state=restarted
5、Tags
如果多次執行修改 Playbook 會涉及到一些沒有變化的代碼,可以使用tags讓 用戶選擇跳過沒有變化的代碼。只運行Playbook中發生變化的部分代碼。可以在Playbook中爲某個或某些任務定義“標籤”,在執行此Playbook時通過 ansible-playbook命令 使用 --tags 選項能實現僅運行指定的tasks。
示例
vi hosts.yml
- hosts: aaa
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/etc/hosts
tags:
- only
- name: touch file
file: path=/opt/hosts state=touch
執行命令:ansible-playbook hosts.yml -t only
會只執行標籤爲 only的任務
事實上,不光可以爲單個或多個task指定同一個tags。playbook還提供了一個特殊的tags爲always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。
如果在上面的yaml文件中添加
- name: touch file
file: path=/opt/hosts state=touch
tags:
- always
執行命令:ansible-playbook hosts.yml -tags only
會將兩個task都執行
6、Roles
Ansible爲了層次化、結構化地組織 Playbook,使用了角色( roles),可以根據層次結構自動裝載變量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include指令即可使用 roles。簡單來講, roles就是通過分別將變量、文件、任務、模塊及處理器設置於單獨的目錄中,便捷地使用他們。
roles內各目錄含義解釋
rolename/: 角色名命名的目錄
—files/:用來存放由copy模塊或script模塊調用的文件。
—templates/:用來存放jinjia2模板,template模塊會自動在此目錄中尋找jinjia2模板文件。
—tasks/:此目錄應當包含一個main.yml文件,用於定義此角色的任務列表。
—handlers:此目錄應當包含一個main.yml文件,用於定義此角色中觸發條件時執行的動作。
—vars:此目錄應當包含一個main.yml文件,用於定義此角色用到的變量。
—defaults:此目錄應當包含一個main.yml文件,用於爲當前角色設定默認變量。
—meta:此目錄應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關係。
在每個角色命令的目錄中分別創建files、handlers、tasks、templates、meta、defaults和vars目錄,用不到的目錄可以創建爲空目錄,但不可以不創建。
五、roles實戰部署nginx
1、創建角色目錄及相關子目錄
[root@ansible_center roles]# cd /etc/ansible/roles/
[root@ansible_center roles]# mkdir -pv nginx/{files,templates,vars,handlers,meta,default,tasks}
mkdir: created directory ‘nginx’
mkdir: created directory ‘nginx/files’
mkdir: created directory ‘nginx/templates’
mkdir: created directory ‘nginx/vars’
mkdir: created directory ‘nginx/handlers’
mkdir: created directory ‘nginx/meta’
mkdir: created directory ‘nginx/default’
mkdir: created directory ‘nginx/tasks’
2、在task定義任務
[root@ansible_center roles]# cat nginx/tasks/main.yaml
- name: mkdir /data/www
file: path=/data/www state=directory
- name: create user nginx
user: name=nginx
- name: copy nginx html to remote host
copy: src=index.html dest=usr/local/nginx/html/
- name: copy nginx package to remote host
copy: src=nginx-1.12.2.tar.gz dest=/opt/nginx-1.12.2.tar.gz
tags: cppkg
- name: tar nginx
shell: cd /opt; tar -xf nginx-1.12.2.tar.gz
- name: install pkg
yum: name={{ item }} state=latest
with_items:
- openssl-devel
- pcre-devel
- gcc
- name: install nginx
shell: cd /opt/nginx-1.12.2;./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre;make&&make install
- name: copy conf file nginx.conf
template: src=nginx.conf dest=/usr/local/nginx/nginx.conf
tags: naxconf
notify: reload nginx service
3、相關文件準備
#nginx源碼安裝文件
[root@ansible_center roles]# cd nginx/files/
[root@ansible_center files]# wget http://nginx.org/download/nginx-1.12.2.tar.gz
#nginx首頁html文件
[root@ansible_center files]# cat index.html
<h1>test page</h1>
#nginx配置模板文件
[root@ansible_center files]# cd ../templates/
[root@ansible_center templates]# cat nginx.conf
#user nobody;
worker_processes 1;
events {
worker_connections {{ con_counts }};
}
http {
include mime.types;
default_type application/octet-stream;
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
location / {
root {{ html_dir }};
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
4、在vars中定義變量
[root@ansible_center templates]# cd /etc/ansible/roles/nginx/vars/
[root@ansible_center vars]# vim main.yaml
[root@ansible_center vars]# cat main.yaml
con_counts: "65535"
html_dir: "/data/www"
5、在handlers中定義觸發器
[root@ansible_center vars]# cd /etc/ansible/roles/nginx/handlers/
[root@ansible_center handlers]# vim main.yaml
[root@ansible_center handlers]# cat main.yaml
name: reload nginx service
shell: /usr/local/nginx/sbin/nginx
6、創建nginx.yaml引導文件
[root@ansible_center handlers]# cd /etc/ansible/roles/
[root@ansible_center roles]# vim nginx.yaml
[root@ansible_center roles]# cat nginx.yaml
- host: 192.168.189.134
remote_user: root
roles:
- nginx
運行結果
ansible-playbook /etc/ansible/roles/nginx.yaml