功能:根據模塊文件動態生成對應的配置文件ios
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
.j2文件nginx
server { worker_connectios {{ ansible_processor_vcpus *2 }}; }
yml文件git
- hosts: dns remote_user: root tasks: - template: src=/app/1.conf.j2 dest=/app/2.conf
生成的配置文件web
server { worker_connectios 4; > ansible_processor_vcpus=2,因此2*2=4 }
語法:shell
{% for i in nginx_vhosts %} 語句塊 {% endfor %} {% if vhost.root is defined %} root {{ vhost.root }}; {% endif %}
以實例來說:apache
- 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; }
語法:vim
{% if i is defined %} 語句塊 {% endif %}
playbook文件:app
- 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文件:ide
{% 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; }
用於層次性、結構化地組織playbook。 roles可以根據層次型結構自動裝載變量文件、tasks以及handlers等。
要使用roles只須要在playbook中使用import_tasks指令便可。(include也能夠用,官方明確聲明此命令將會淘汰)
簡單來說,roles就是經過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並能夠便捷地
include它們的一種機制。角色通常用於基於主機構建服務的場景中,但也能夠是用於構建守護進程等場景中
複雜場景:建議使用roles,代碼複用度高
(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也是能夠的。
前面的章節針對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"
第 (五) 篇屬於應用級別的。後續再更新了。