一、playbooks 組成
1、playbooks本身由以下各部分組成
(1) Tasks: 任務,即通過task調用ansible的模板將多個操作組織在一個playbook 中運行
(2) Variables: 變量
(3) Templates: 模板
(4) Handlers: 處理器,當changed狀態條件滿足時, (notify) 觸發執行的操作
(5) Roles: 角色
2、操作示例一:
2.1 編寫yaml文件也就是playbook
vim test1.yaml
--- #yaml文件以---開頭,以表明這是一個yaml文件,可省略
- name: first play #定義一個play的名稱,可省略
gather_facts: false #設置不進行facts信息收集,這可以加快執行速度,可省略
hosts: webservers #指定要執行任務的被管理主機組,如多個主機組用冒號分隔
remote_user: root #指定被管理主機上執行任務的用戶
tasks: #定義任務列表,任務列表中的各任務按次序逐個在hosts中指定的主機上執行
- name: test connection # 自定義任務名稱
ping: #使用 module: [options] 格式來定義一個任務
- name: disable selinux
command: '/sbin/setenforce 0' #command模塊和shell模塊無需使用key=value格式
ignore_errors: True #如執行命令的返回值不為0,就會報錯,tasks停止,可使用ignore_errors忽略失敗的任務
- name: disable firewalld
service: name=firewalld state=stopped #使用 module: options 格式來定義任務,option使用key=value格式
- name: install httpd
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #這里需要一個事先准備好的/opt/httpd.conf文件
notify: "restart httpd" #如以上操作后為changed的狀態時,會通過notify指定的名稱觸發對應名稱的handlers操作
- name: start httpd service
service: enabled=true name=httpd state=started
handlers: #handlers中定義的就是任務,此處handlers中的任務使用的是service模塊
- name: restart httpd #notify和handlers中任務的名稱必須一致
service: name=httpd state=restarted
#Ansible在執行完某個任務之后並不會立即去執行對應的handler,而是在當前play中所有普通任務都執行完后再去執行handler,
這樣的好處是可以多次觸發notify,但最后只執行一次對應的handler,從而避免多次重啟。
---
- name: first play
gather_facts: false
hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
- name: disable selinux
command: '/sbin/setenforce 0'
ignore_errors: True
- name: disable firewalld
service: name=firewalld state=stopped
- name: install httpd
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: "restart httpd"
- name: start httpd service
service: enabled=true name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
2.2 修改配置文件並放入/opt/目錄下
vim httpd.conf #在/opt/目錄下放入修改之后的配置文件
#42行,指定端口
Listen 8080
#95行,指定域名
ServerName www.ly.com:8080
2.3 運行playbook
ansible-playbook test1.yaml
//補充參數:
-k(–ask-pass):用來交互輸入ssh密碼
-K(-ask-become-pass):用來交互輸入sudo密碼
-u:指定用戶
ansible-playbook test1.yaml --syntax-check #檢查yaml文件的語法是否正確
ansible-playbook test1.yaml --list-task #檢查tasks任務
ansible-playbook test1.yaml --list-hosts #檢查生效的主機
ansible-playbook test1.yaml --start-at-task='install httpd' #指定從某個task開始運行
3、操作實例二:定義、引用變量
- name: second play
hosts: dbservers
remote_user: root
vars: #定義變量
- groupname: mysql #格式為 key: value
- username: nginx
tasks:
- name: create group
group: name={{groupname}} system=yes gid=306 #使用 {{key}} 引用變量的值
- name: create user
user: name={{username}} uid=306 group={{groupname}}
- name: copy file
copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt #在setup模塊中可以獲取facts變量信息
ansible-playbook test2.yaml -e "username=nginx" #在命令行里定義變量
- name: second play
hosts: dbservers
remote_user: root
vars:
- groupname: mysql
- username: nginx
tasks:
- name: create group
group: name={{groupname}} system=yes gid=3000
- name: create user
user: name={{username}} uid=2512 group={{groupname}}
- name: copy file
copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt
4、操作示例三:指定遠程主機sudo切換用戶
---
- hosts: dbservers
remote_user: zhangsan
become: yes #2.6版本以后的參數,之前是sudo,意思為切換用戶運行
become_user: root #指定sudo用戶為root
執行playbook時:ansible-playbook test3.yml -K <密碼>
---
- hosts: dbservers
remote_user: lisi
become: yes
become_user: root
5、操作示例四:when條件判斷
在Ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則該任務執行,否則不執行該任務。
//when一個比較常見的應用場景是實現跳過某個主機不執行任務或者只有滿足條件的主機執行任務
vim test4.yaml
---
- hosts: all
remote_user: root
tasks:
- name: shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.229.80" #when指令中的變量名不需要手動加上 {{}}
或
when: inventory_hostname == "<主機名>"
ansible-playbook test4.yaml
---
- hosts: all
remote_user: root
tasks:
- name: shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.237.20"
6、操作示例:五:迭代
Ansible提供了很多種循環結構,一般都命名為with_items,作用等同於 loop 循環。
vim test5.yaml
---
- name: play5
hosts: dbservers
gather_facts: false
tasks:
- name: create directories ##創建目錄。目錄名使用with_items里的循環
file:
path: "{{item}}" ##由於值是{{....}} ,所以為了防止被認為是字典,要加上雙引號.
state: directory
with_items: #等同於 loop:
- /tmp/test1
- /tmp/test2
- name: add users ###使用循環創建用戶,並添加附加組
user: name={{item.name}} state=present groups={{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
或
with_items:
- {name:'test1', groups:'wheel'}
- {name:'test2', groups:'root'}
ansible-playbook test5.yaml
---
- name: playbook5
hosts: dbservers
gather_facts: flase
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items:
- /tmp/test1
- /tmp/test2
- name: add users
user: name={{item.name}} state=present groups={{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
二、playbook的模塊
1、Templates 模塊
Jinja是基於Python的模板引擎。Template類是Jinja的一個重要組件,可以看作是一個編譯過的模板文件,用來產生目標文本,傳遞Python的變量給模板去替換模板中的標記。
1.1.先准備一個以 .j2 為后綴的 template 模板文件,設置引用的變量
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
vim /opt/httpd.conf.j2
Listen {{http_port}} #42行,修改
ServerName {{server_name}} #95行,修改
DocumentRoot "{{root_dir}}" #119行,修改 <Directory "{{root_dir}}"> #131修改 配置目錄訪問權限
1.2.修改主機清單文件,使用主機變量定義一個變量名相同,而值不同的變量
vim /etc/ansible/hosts
[webservers]
192.168.237.20 http_port=192.168.237.20:80 server_name=www.lsq.com:80 root_dir=/etc/httpd/htdocs
[dbservers]
192.168.237.30 http_port=192.168.237.30:80 server_name=www.test.com:80 root_dir=/etc/httpd/htdocs
1.3、編寫 playbook
---
- hosts: all
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest
- name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: create root dir
file: path=/etc/httpd/htdocs state=directory
- name: start httpd server
service: name={{service}} enabled=true state=started
handlers:
- name: restart httpd
service: name={{service}} state=restarted
1.4、制作測試網頁
ansible 192.168.237.20 -m shell -a "echo 'this is test1' > /etc/httpd/htdocs/index.html" #制作網頁測試文件
ansible 192.168.237.30 -m shell -a "echo 'this is test2' > /etc/httpd/htdocs/index.html" #登錄訪問查看
2、tags 模塊
可以在一個playbook中為某個或某些任務定義“標簽”,在執行此playbook時通過ansible-playbook命令使用--tags選項能實現僅運行指定的tasks。
playbook還提供了一個特殊的tags為always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。
vim webhosts.yaml
---
- hosts: webservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only #可自定義
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always #表示始終要運行的代碼
ansible-playbook webhosts.yaml --tags="only"
vim dbhosts.yaml
---
- hosts: dbservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
ansible-playbook dbhosts.yaml --tags="only"
---
- hosts: webservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always
分別去兩台被管理主機上去查看文件創建情況
3、Roles 模塊
Ansible為了層次化、結構化地組織Playbook,使用了角色(roles),roles可以根據層次型結構自動裝載變量文件、task以及handlers等。簡單來講,roles就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷地include它們。roles一般用於基於主機構建服務的場景中,但也可以用於構建守護進程等場景中。
3.1 roles 的目錄結構:
cd /etc/ansible/
tree roles/
roles/
├── web/
│ ├── files/
│ ├── templates/
│ ├── tasks/
│ ├── handlers/
│ ├── vars/
│ ├── defaults/
│ └── meta/
└── db/
├── files/
├── templates/
├── tasks/
├── handlers/
├── vars/
├── defaults/
└── meta/
3.2 roles 內各目錄含義解釋
●files
用來存放由 copy 模塊或 script 模塊調用的文件。
●templates
用來存放 jinjia2 模板,template 模塊會自動在此目錄中尋找 jinjia2 模板文件。
●tasks
此目錄應當包含一個 main.yml 文件,用於定義此角色的任務列表,此文件可以使用 include 包含其它的位於此目錄的 task 文件。
●handlers
此目錄應當包含一個 main.yml 文件,用於定義此角色中觸發條件時執行的動作。
●vars
此目錄應當包含一個 main.yml 文件,用於定義此角色用到的變量。
●defaults
此目錄應當包含一個 main.yml 文件,用於為當前角色設定默認變量。
●meta
此目錄應當包含一個 main.yml 文件,用於定義此角色的特殊設定及其依賴關系。
3.3 在一個 playbook 中使用 roles 的步驟:
(1)創建以 roles 命名的目錄
mkdir /etc/ansible/roles/ -p #yum裝完默認就有
(2)創建全局變量目錄(可選)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定義,引用的時候注意
(3)在 roles 目錄中分別創建以各角色名稱命令的目錄,如 httpd、mysql
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
mkdir /etc/ansible/roles/php
(4)在每個角色命令的目錄中分別創建files、handlers、tasks、templates、meta、defaults和vars目錄,用不到的目錄可以創建為空目錄,也可以不創建
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta}
(5)在每個角色的 handlers、tasks、meta、defaults、vars 目錄下創建 main.yml 文件,千萬不能自定義文件名
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml
(6)修改 site.yml 文件,針對不同主機去調用不同的角色
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- hosts: dbservers
remote_user: root
roles:
- mysql
示例范本
(7)運行 ansible-playbook
cd /etc/ansible
ansible-playbook site.yml
三、roles在LAMP中的應用
1、編寫httpd模塊
寫一個簡單的tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
//定義變量:可以定義在全局變量中,也可以定義在roles角色變量中,一般定義在角色變量中
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
這里我們定義在角色變量中
2、編寫mysql模塊
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysql
yum: name={{pkg}} state=latest
- name: start mysql
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/mysql/vars/main.yml
pkg:
- mariadb
- mariadb-server
svc: mariadb
3、編寫php模塊
vim /etc/ansible/roles/php/tasks/main.yml
- name: install php
yum: name={{pkg}} state=latest
- name: start php-fpm
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/php/vars/main.yml
pkg:
- php
- php-fpm
svc: php-fpm
4、編寫roles示例
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- mysql
- php
cd /etc/ansible
ansible-playbook site.yml