運維自動化-Ansible ( 四 )
功能:根據模塊文件動態生成對應的配置文件
? Jinja2語言,使用字面量,有下面形式
字符串:使用單引號或雙引號
數字:整數,浮點數
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false
? 算術運算:+, -, *, /, //, %, **
? 比較操作:==, !=, >, >=, <, <=
? 邏輯運算:and, or, not
? 流表達式:For If When
? templates文件必須存放於templates目錄下,且命名為 .j2 結尾 ? yaml/yml 文件需和templates目錄平級,目錄結構如下: ./ ├── temnginx.yml └── templates └── nginx.conf.j2
Playbook中template 的 算術運算
.j2文件
server {
worker_connectios {{ ansible_processor_vcpus *2 }};
}
yml文件
- hosts: dns
remote_user: root
tasks:
- template: src=/app/1.conf.j2 dest=/app/2.conf
生成的配置文件
server {
worker_connectios 4; > ansible_processor_vcpus=2,所以2*2=4
}
Playbook中template 的 for 循環
語法:
{% for i in nginx_vhosts %}
語句塊
{% endfor %}
{% if vhost.root is defined %}
root {{ vhost.root }};
{% endif %}
以實例來講:
- hosts: web remote_user: root vars: prot_list: - 8080 - 8081 - 8082 tasks: - name: create vhost template: src=/app/1.conf.j2 dest=/app/2.conf > for 循環是寫在.j2文件中的。 一般來講是配合template模板來使用,文件的後綴名為.j2 先建立一個標準模板文件,這個文件需要跟dest使用的格式一致,只不過是將會變化的內容使用for循環的格式來寫 {% for prot in prot_list %} server { listen prot; } {% endfor %} 是不是與shell編程的for循環很像?
#ansible-playbook for1.yml
結果:
#cat /app/2.conf
server {
listen 8080;
}
server {
listen 8081;
}
server {
listen 8082;
}
再來一個多行多主機的模板:
- hosts: web
remote_user: root
vars:
vhosts:
- web:
prot: 8080
server: web1.hunk.tech
root: /app/webroot1
- web:
prot: 8081
server: web2.hunk.tech
root: /app/webroot2
- web:
prot: 8082
server: web2.hunk.tech
root: /app/webroot2
tasks:
- name: create vhost
template: src=/app/1.conf.j2 dest=/app/2.conf
j2文件:
{% for vhost in vhost_list %}
server {
listen {{ vhost.prot }};
servername {{ vhost.server }};
root {{ vhost.root }};
}
{% endfor %}
執行:
#ansible-playbook for1.yml
結果:
#cat /app/2.conf
server {
listen 8080;
servername web1.hunk.tech;
root /app/webroot1;
}
server {
listen 8081;
servername web2.hunk.tech;
root /app/webroot2;
}
server {
listen 8082;
servername web2.hunk.tech;
root /app/webroot2;
}
Playbook中template 的 if 判斷
語法:
{% if i is defined %}
語句塊
{% endif %}
playbook文件:
- hosts: web
remote_user: root
vars:
vhost_list:
- web1:
prot: 8080
name: web1.hunk.tech > 註意,web1是定義了name的值
- web2: > 註意,web2是沒有定義了name的值
prot: 8081
tasks:
- template: src=/app/1.conf.j2 dest=/app/2.conf
j2文件:
{% for vhost in vhost_list %}
server {
listen {{ vhost.prot }};
{% if vhost.name is defined %} > 如果vhost.name有應以,剛填入下面的內容
servername {{ vhost.name }};
{% endif %}
}
{% endfor %
執行:
#ansible-playbook if.yml
結果:
#cat /app/2.conf
server {
listen 8080;
servername web1.hunk.tech;
}
server {
listen 8081;
}
roles
用於層次性、結構化地組織playbook。 roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。
要使用roles只需要在playbook中使用import_tasks指令即可。(include也可以用,官方明確聲明此命令將會淘汰)
簡單來講,roles就是通過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並可以便捷地
include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中
? 復雜場景:建議使用roles,代碼復用度高
創建role的步驟
(1) 創建以roles命名的目錄
(2) 在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等
(3) 在每個角色命名的目錄中分別創建files、 handlers、meta、 tasks、 templates和vars目錄;
用不到的目錄可以創建為空目錄,也可以不創建
(4) 在playbook文件中,調用各自角色
建議的目錄結構
├── roles > 必須是這個名字
│?? ├── git > 具體項目名稱
│?? │?? ├── default > 設定默認變量時使用此目錄中的main.yml文件
│?? │?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
│?? │?? ├── files > 存放有copy或script模塊等調用的文件
│?? │?? ├── handlers > 定義觸發器
│?? │?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
│?? │?? ├── meta > 定義當前角色的特殊設定及其依賴關系
│?? │?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
│?? │?? ├── tasks > 定義任務
│?? │?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
│?? │?? ├── templates > template模塊查找所需要模板文件目錄
│?? │?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
│?? │?? └── vars > 定義變量;;其他的文件需要在此文件中通過include進行包含
│?? │?? └── main.yml > 至少應該包含一個名為main.yml的文件
還是拿一個實例來說:
如果要在一臺初始化的主機上面安裝httpd服務,有以下過程:(這裏不考慮編譯安裝情況,假設yum腳本裏不會創建組和用戶)
1.創建用於httpd服務的組
2.創建用於httpd服務的用戶
3.安裝httpd軟件包
4.啟動httpd服務
把這些過程體現在ansible上面就是對應的具體的tasks,因此,將需要在roles/tasks/下面創建分別用於這些過程的獨立yml文件
1.創建用於httpd服務的
#vim groupadd.yml
- name: groupadd apache
group: name=apache
2.創建用於httpd服務的用戶
#vim useradd.yml
- name: useradd apache
user: name=apache group=apache shell=/sbin/nologin system=yes
3.安裝httpd軟件包
#vim install_httpd.yml
- name: yum install httpd
yum: name=httpd
4.啟動httpd服務
#vim start_httpd.yml
- name: start httpd
service: name=httpd state=started
每個具體的小任務有了,那麽就得有一個主的配置文件,默認劇本就會讀取它,從而確定其他任務的關系。
註意,文件名必須是main.yml
註意,順序不能顛倒,步驟是從上而下順序執行,就像編排電影劇本一樣。有沒有當導演的感覺?
#vim main.yml
- import_tasks: groupadd.yml
- import_tasks: useradd.yml
- import_tasks: install_httpd.yml
- import_tasks: start_httpd.yml
最後,創建一個執行的playbook文件,這個文件與roles目錄是同級目錄。
#vim httpd_roles.yml
---
- hosts: web
remote_user: root
roles:
- httpd > 註意,這個- 後面跟就是roles目錄下的子目錄名稱
當然,也可以寫成
roles:
- role: httpd > 註意,這個- role: 是不可以改變名稱的,後面跟就是roles目錄下的子目錄名稱
至此,此時的目錄結構為:
├── httpd_roles.yml > 執行的playbook文件
└── roles > roles角色目錄
├── httpd > 項目文件夾
│?? ├── default
│?? ├── files
│?? ├── handlers
│?? ├── meta
│?? ├── tasks > 任務文件夾
│?? │?? ├── groupadd.yml
│?? │?? ├── install_httpd.yml
│?? │?? ├── main.yml
│?? │?? ├── start_httpd.yml
│?? │?? └── useradd.yml
│?? ├── templates
│?? └── vars
#ansible web -m shell -a ‘ss -nlt|grep 80‘
6-web-1.hunk.tech | SUCCESS | rc=0 >>
LISTEN 0 128 :::80
7-web-2.hunk.tech | SUCCESS | rc=0 >>
LISTEN 0 128 :::80
7-web-0.hunk.tech | SUCCESS | rc=0 >>
LISTEN 0 128 :::80
調用其他任務
為了更好的復用代碼,可以將一些公共的代碼集中在一個目錄裏,按需要在以後的roles進行調用
├── pubtasks
│?? └── create_nginx_user_and_group.yml
#cat create_nginx_user.yml
- name: create nginx group
group: name=nginx
- name: create nginx user
user: name=nginx shell=/usr/sbin/nologin comment="nginx service" group=nginx createhome=no
調用的時候,在tasks中引入即可
- hosts: dns
remote_user: root
tasks:
- name: test
import_tasks: /app/yml/pubtasks/create_nginx_user_and_group.yml
同理,在別的文件中引入import_role也是可以的。
roles中的tags
前面的章節針對tasks有tags,而roles中也可以運用此方法
- hosts: web
remote_user: root
roles:
- { role: httpd, tags: [ ‘web‘, ‘apache22‘ ] } > 其實,這是字典的一種寫法,前面章節有講到,只不過是寫在一行裏了。
所以,下面的寫法是同等的
roles:
- role: httpd
tags:
- web
- apache22
基於條件判斷的roles的tags
- { role: nginx, tags: [ ‘nginx‘, ‘web‘ ], when: ansible_distribution_major_version == "6" }
當roles中有了tags後,執行時候加上-t tags名稱即可
# ansible-playbook httpd_roles.yml -t web
# ansible-playbook httpd_roles.yml -t apache22
也可以同時調用多個tags
# ansible-playbook httpd_roles.yml -t "web,db"
第 (五) 篇屬於應用級別的。後續再更新了。
運維自動化-Ansible ( 四 )