ansible之playbook

一、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

格式

  1. 文件的第一行應該以 “—” (三個連字符)開始,表明YMAL文件的開始。
  2. 在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。
  3. YMAL中的列表元素以”-”開頭然後緊跟着一個空格,後面爲元素內容。
  4. 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
  5. 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 

在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章