ansible:playbook詳解
概述
playbook是由一個或者多個play
組成的列表。
主要功能是將預定義的一組主機裝扮成事先通過ansible中的task定義好的角色。task實際是調用ansible的一個模組,將多個play組織在一個playbook中,即可以讓它們聯合起來,將事先編排的機制執行預定義的動作。
playbook文件是使用YAML語言編寫的。
YAML語言
官網://yaml.org/
YAML(Yet another Markup Language,仍是一種標記語言)是一個可讀性高的用來表達資料序列的格式。
目前很多軟體採用了此格式,如ansible、docker、k8s等。
語法說明
- YAML 的配置文件後綴為
.yml
- 大小寫敏感
- 使用縮進表示層級關係
- 縮進不允許使用tab,只允許空格
- 縮進的空格數不重要,只要相同層級的元素左對齊即可
#
表示注釋,從這個字元一直到行尾,都會被解析器忽略
數據結構
YAML 支援的數據結構有三種。
- 對象:鍵值對的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 數組:一組按次序排列的值,又稱為序列(sequence) / 列表(list)
- 純量(scalars):單個的、不可再分的值
對象
對象的一組鍵值對,使用冒號:
結構表示。例如:
name: 'Rohn'
Yaml 也允許另一種寫法,將所有鍵值對寫成一個行內對象。例如:
{ hash: { name: 'Steve', foo: 'bar' } }
數組
一組連詞線-
開頭的行,構成一個數組。例如:
- Cat
- Dog
- Goldfish
純量
純量是最基本的、不可再分的值。
純量的類型:
- 字元串
- 布爾值
- 整數
- 浮點數
- Null
- 時間
- 日期
字元串
- 字元串默認不使用引號表示。
- 如果字元串之中包含空格或特殊字元,需要放在引號之中。
- 單引號和雙引號都可以使用,雙引號不會對特殊字元轉義。
- 單引號之中如果還有單引號,必須連續使用兩個單引號轉義。
- 字元串可以寫成多行,從第二行開始,必須有一個單空格縮進。換行符會被轉為空格。
- 多行字元串可以使用
|
保留換行符,也可以使用>
摺疊換行。 +
表示保留文字塊末尾的換行,-
表示刪除字元串末尾的換行。- 字元串之中可以插入 HTML 標記。
核心元素
元素 | 說明 |
---|---|
hosts | 遠程主機列表 |
tasks | 任務集 |
variables | 內置變數或自定義變數,用於playbook中調用 |
templates | 模板 |
handlers和notify | handlers和notify配合使用,由特定條件觸發的操作,滿足條件則執行,否則不執行 |
tags | 標籤 |
hosts
playbook中的每一個play的目的是為了讓特定主機以某個指定用戶身份執行任務。hosts用於指定要執行指定任務的主機,需事先定義在主機清單中。例如:
- hosts: websrvs:dbsrvs # 或者,兩個組的並集
- hosts: websrvs:&dbsrvs # 與,兩個組的交集
- hosts: websrvs:!dbsrvs # 在websrvs組,但不在dbsrvs組
remote_user
可以用於host和task中。也可通過指定其通過sudo的方式在遠程主機上執行任務,其可用於play全局或某任務;此外,甚至可以在sudo時使用sudo_user指定sudo時切換的用戶。
task列表和action組件
play的主體部分是task list。task list中有一個或者多個task,各個task按順序逐個在hosts指定的所有主機上執行、也就是所有主機完成一個task後,再開始下一個task。
task的目的是使用指定的參數執行模組,而在模組參數中可以使用變數。模組執行是冪等的,這意味著多次執行是安全的,因為其結果均一致。
每個task都應該有name,用於playbook的執行結果輸出,建議其內容能清晰地描述任務執行步驟。若未能提供name,則action的結果將用於輸出。
task格式有兩種:
- action: module arguments
- module: arguments # 推薦使用這種
Tips:shell模組和command的模組後面跟的是命令,而非
key=value
的方式。
其他組件
若有任務的狀態在運行後為changed時,可通過notify通知給相應的handlers。
shell腳本和playbook對比
部署Nginx
Shell腳本:
#!/bin/bash
yum -y install nginx
\cp /tmp/nginx.conf /etc/nginx/
\cp /tmp/web.conf /etc/nginx/conf.d/
systemctl enable nginx
nginx -t
systemctl start nginx
playbook實現:
---
- hosts: web_server
remote_user: root
tasks:
- name: "部署nginx"
yum: name=nginx
- name: "複製配置文件"
copy: src=/tmp/nginx.conf dest=/etc/nginx/
- name: "複製配置文件"
copy: src=/tmp/web.conf dest=/etc/nginc/conf.d/
- name: "啟動nginx,並設置開機啟動"
service: name=nginx state=started enable=yes
playbook命令
語法格式
usage: ansible-playbook [-h] [--version] [-v] [-k]
[--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
[-c CONNECTION] [-T TIMEOUT]
[--ssh-common-args SSH_COMMON_ARGS]
[--sftp-extra-args SFTP_EXTRA_ARGS]
[--scp-extra-args SCP_EXTRA_ARGS]
[--ssh-extra-args SSH_EXTRA_ARGS] [--force-handlers]
[--flush-cache] [-b] [--become-method BECOME_METHOD]
[--become-user BECOME_USER] [-K] [-t TAGS]
[--skip-tags SKIP_TAGS] [-C] [--syntax-check] [-D]
[-i INVENTORY] [--list-hosts] [-l SUBSET]
[-e EXTRA_VARS] [--vault-id VAULT_IDS]
[--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
[-f FORKS] [-M MODULE_PATH] [--list-tasks]
[--list-tags] [--step] [--start-at-task START_AT_TASK]
playbook [playbook ...]
精簡為:
ansible-playbook <filename.yml> ... [options]
常用參數
參數 | 說明 |
---|---|
-C | 只檢測可能發生的改變,並不真正執行操作 |
–list-hosts | 列出運行任務的主機 |
–list-tags | 列出tag |
–list-taks | 列出task |
–limit | 只針對主機列表中的主機執行 |
-v | 顯示過程 |
例子
安裝MariaDB
---
#Installing MariaDB Binary Tarballs
- hosts: db_server
remote_user: root
gather_facts: no
tasks:
- name: create group
group: name=mysql gid=27 system=yes
- name: create user
user: name=mysql uid=27 system=yes group=mysql shell=/sbin/nologin home=/data/mysql create_home=no
- name: mkdir datadir
file: path=/data/mysql owner=mysql group=mysql state=directory
- name: unarchive package
unarchive: src=/data/ansible/files/mariadb-10.2.27-linux-x86_64.tar.gz dest=/usr/local/ owner=root group=root
- name: link
file: src=/usr/local/mariadb-10.2.27-linux-x86_64 path=/usr/local/mysql state=link
- name: install database
shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
- name: config file
copy: src=/data/ansible/files/my.cnf dest=/etc/ backup=yes
- name: service script
shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
- name: start service
service: name=mysqld state=started enabled=yes
- name: PATH variable
copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
變數
變數名:僅能由字母、數字和下劃線組成,且只能以字母開頭。
語法格式
var=value
例如:
db_port=3306
變數調用方式
"{{ variable_name }}"
變數來源
-
ansible 的 setup facts 遠程主機的所有變數都可直接調用;
-
通過命令行指定變數,優先順序最高:
ansible-playbook -e var=value
-
在playbook文件中定義:
vars: - var1: value1 - var2: value2
-
在獨立的變數YAML文件中定義:
- hosts: all vars_files: - vars.yml
-
在
/etc/ansible/hosts
中定義:- 主機(普通)變數:主機組中主機單獨定義,優先順序高於公共變數;
- 組(公共)變數:針對主機組中所有主機定義同一變數;
-
在role中定義
template模板
模板是一個文本文件,可以作為生成文件的模板,並且模板文件中還可以嵌套jinja語法。
jinja語言
- jinja2 語言使用字面量,有下面形式:
- 字元串:使用單引號或雙引號
- 數字:整數,浮點數
- 列表:[item1, item2, …]
- 元組:(item1, item2, …)
- 字典:{key1:value1, key2:value2, …}
- 布爾型:true/false
- 算術運算:+, -, *, /, //, %, **
- 比較操作:==, !=, >, >=, <, <=
- 邏輯運算:and,or,not
- 流表達式:For,If,When
流程式控制制
template中也可以使用流程式控制制 for 循環和 if 條件判斷,實現動態生成文件功能。
例如:
#temlnginx2.yml
---
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- 81
- 82
- 83
tasks:
- name: template config
template: src=nginx.conf.j2 dest=/data/nginx.conf
#templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost }}
}
{% endfor %}
ansible-playbook -C templnginx2.yml --limit 10.0.0.8
#生成的結果:
server {
listen 81
}
server {
listen 82
}
server {
listen 83
}
實例
同步nginx配置文件:
---
- hosts: web_server
remote_user: root
tasks:
- name: "config"
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf