ansible學習筆記二:playbook


繼續接上一章,上一章記錄了常用的模塊,這裏就開始把模塊應用到ansible-playbook內。

環境:

因爲自己筆記本性能問題,這裏只用兩臺虛擬機做測試:

服務器名 IP
ansible-server 192.168.31.53
ansible-client 192.168.31.167

測試ansible-playbook

1. 測試一例:

ansible-playbook的文件是yml格式的,這裏先說下yml裏的格式:

格式 說明
默認開頭以3個-開頭
host 指定劇本運行在什麼主機組
remote_user 指定以什麼用戶去執行下面的動作
tasks 動作開始
name 說明當前動作是做什麼的

這裏需要注意的是,每一個name下,只能跟一個動作

寫yml,執行完之後檢查各項,用-C去檢查
示例:在/root/下創建newfile文件,增加test99用戶,指定爲系統用戶,shell類型爲:/sbin/nologin,安裝httpd服務,拷貝本機/var/www/html/index.html到指定機器/var/www/html目錄下,開啓httpd服務,並設爲開機自啓

[root@ansible ~]# cat file.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: create new file
      file: name=/root/newfile state=touch

    - name: create new user
      user: name=test99 system=yes shell=/sbin/nologin

    - name: install package
      yum:  name=httpd

    - name: copy html
      copy: src=/var/www/html/index.html dest=/var/www/html/

    - name: start service
      service: name=httpd state=started enabled=yes

當運行完上面的之後,檢查

[root@ansible ~]# ansible all -m shell -a ‘ls /root/ -l’
192.168.31.167 | CHANGED | rc=0 >>
total 8
-rw-r–r-- 1 root root 21 Feb 8 22:19 123
-rw-r–r-- 1 root root 1190 Feb 5 22:57 ks.cfg
-rw-r–r-- 1 root root 0 Feb 9 04:13 newfile

[root@ansible ~]# ansible all -m shell -a ‘getent passwd test99’
192.168.31.167 | CHANGED | rc=0 >>
test99❌987:981::/home/test99:/sbin/nologin

[root@ansible ~]# ansible all -m shell -a ‘ss -tln| grep :80’
192.168.31.167 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 ::😗

2. 在yml內增加tags及handlers

這裏增加tags,主要是可以通過在只是ansible-playbook的時候,可以通過-t 指定tags名,做指定動作。handlers需要配合notify,下面的文件內做了註釋了。

[root@ansible ~]# cat http.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: install httpd package
      yum:  name=httpd
      # 這裏給動作打上標籤之後,可以在執行劇本的時候,通過 ansible-playbook -t installhttpd,starthttpd http.yml 命令只執行指定標籤的操作,同時tags可以寫成一樣的,
      # 即,一個標籤指定多個動作的情況。
      tags: installhttpd

    - name: copy conf file
      copy: src=/root/httpd.conf dest=/etc/httpd/conf/ backup=yes
      # 當文件有變更的時候,會執行下面handlers裏的 restart service動作
      notify: restart service

    - name: start service
      service: name=httpd state=started enabled=yes
      tags: starthttpd

  handlers:
    - name: restart service
      service: name=httpd state=restarted

3. 在yml內增加變量:

ansible-playbook在執行的時候,爲了更方便的運行,可以增加變量,以增加靈活性。下面測試了增加變量的方法。

3.1 方法1,外部通過-e去指定:

安裝指定的服務,變量的寫法: {{ }} 內部爲變量名,類似寫html裏的方式,下面的表達式的也是這樣的方式。

[root@ansible ~]# cat app.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: install  package
      yum:  name={{ pkname }}

    - name: start service
      service: name={{ pkname }} state=started

[root@ansible ~]# ansible-playbook app.yml -e pkname=httpd
PLAY [all] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [install package] *****************************************************************************************************************************************************************************************
changed: [192.168.31.167]
TASK [start service] ********************************************************************************************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ******************************************************************************************************************************************************************************************************
192.168.31.167 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

檢查

[root@ansible ~]# ansible all -m shell -a ‘ss -ntl| grep 80’
192.168.31.167 | CHANGED | rc=0 >>
LISTEN 0 128 :::80 ::😗

3.2 方法2,內部指定:

通過vars指定變量。

[root@ansible ~]# cat app.yml

---
- hosts: all
  remote_user: root
  vars:
    - pkname: nginx

  tasks:
    - name: install  package
      yum:  name={{ pkname }}

    - name: start service
      service: name={{ pkname }} state=started

[root@ansible ~]# ansible-playbook app.yml
PLAY [all] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [install package] *****************************************************************************************************************************************************************************************
changed: [192.168.31.167]
TASK [start service] ********************************************************************************************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ******************************************************************************************************************************************************************************************************
192.168.31.167 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

檢查

[root@ansible ~]# ansible all -m shell -a ‘ss -ntl| grep 80’
192.168.31.167 | CHANGED | rc=0 >>
LISTEN 0 128 :80 :
LISTEN 0 128 :::80 :::

3.3 方法3,用setup模塊裏的變量:

setup模塊,在上一章內已經說過了,其實這裏使用,相當於使用anisble自帶的變量。

[root@ansible ~]# cat var.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: create log file
      file: name=/root/{{ ansible_fqdn }}.log state=touch mode=600 owner=test

[root@ansible ~]# ansible-playbook var.yml
PLAY [all] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [create log file] ******************************************************************************************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ******************************************************************************************************************************************************************************************************
192.168.31.167 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

檢查

[root@ansible ~]# ansible all -m shell -a ‘ls /root/*.log’
192.168.31.167 | CHANGED | rc=0 >>
/root/client.log

3.4 方法4,在其他文件內指定變量:

這裏類似於上面的在yml內直接指定,只是這樣把vars拿出來,方到單獨的文件內,類似於下一章要寫的roles,這裏提前寫下。寫法爲:key:vaule

[root@ansible ~]# cat vars.yml
var1: httpd
var2: nginx

[root@ansible ~]# cat testvar.yml

---
- hosts: all
  remote_user: root
  vars_files:
    - vars.yml

  tasks:
    - name: install package
      yum: name={{ var1 }}

    - name: create file
      file: name=/root/{{ var2 }} state=touch

[root@ansible ~]# ansible-playbook testvar.yml
PLAY [all] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [install package] ****************************************************************************************************************
changed: [192.168.31.167]
TASK [create file] ********************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

檢查

[root@ansible ~]# ansible all -m shell -a ‘rpm -q httpd ; ls /root/nginx’
192.168.31.167 | CHANGED | rc=0 >>
httpd-2.4.6-90.el7.centos.x86_64
/root/nginx

4. 通過template生成模板,在模板文件內修改成變量模式,以實現各機器的不一致:

在模板內添加變量,setup模塊的自帶變量ansible_processor_vcpus,和在/etc/ansible/hosts內定義的http_port變量

[root@ansible ansible]# egrep ‘worker_processes|listen’ templates/nginx.conf.j2 | grep -v ^#

worker_processes {{ ansible_processor_vcpus**2 }};
        listen       {{ http_port }} default_server;
        listen       [::]:{{ http_port }} default_server;

[root@ansible ansible]# grep 192.168.31.167 /etc/ansible/hosts
192.168.31.167 http_port=8080

把變量寫入yml內,以實現不通機器設置不通nginx監聽進程及開啓不同端口的效果

[root@ansible ansible]# cat tetempl.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: install package
      yum: name=nginx

    - name: copy template
      template: src=/root/ansible/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service

    - name: start service
      service: name=nginx state=started

  handlers:
    - name: restart service
      service: name=nginx state=restarted

[root@ansible ansible]# ansible-playbook tetempl.yml
PLAY [all] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [install package] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [copy template] ******************************************************************************************************************
changed: [192.168.31.167]
TASK [start service] ******************************************************************************************************************
changed: [192.168.31.167]
RUNNING HANDLER [restart service] *****************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

檢查是否安裝nginx,是否複製過去新的nginx.conf文件,啓動的端口,啓動的worker監聽進程

[root@ansible ansible]# ansible all -m shell -a ‘rpm -q nginx;ls -l /etc/nginx/nginx.conf; ss -ntl| grep 80;ps aux | grep nginx | grep worker’
192.168.31.167 | CHANGED | rc=0 >>
nginx-1.16.1-1.el7.x86_64
-rw-r–r-- 1 root root 2473 Feb 10 13:30 /etc/nginx/nginx.conf
LISTEN 0 128 :8080 :
LISTEN 0 128 :::8080 :::

nginx 3444 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3445 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3446 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3447 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3448 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3449 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3450 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3451 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3452 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3453 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3454 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3455 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3456 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3457 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3458 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
nginx 3459 0.0 0.0 121236 3512 ? S 13:30 0:00 nginx: worker process
root 3571 2.0 0.0 113120 1360 pts/1 S+ 13:33 0:00 /bin/sh -c rpm -q nginx;ls -l /etc/nginx/nginx.conf; ss -ntl| grep 80;ps aux | grep nginx | grep worker

通過以上測試,發現ansible的變量優先級:
ansible-playbook變量的優先級: -e 指定變量 > 要執行的playbook內的變量 > 主機清單內的變量

5. playbook內添加when:

5.1 相當於if判斷

[root@ansible ansible]# cat tetempl.yml

---
- hosts: all
  remote_user: root

  tasks:
    - name: install package
      yum: name=nginx

    - name: copy template
      template: src=/root/ansible/templates/nginx7.conf.j2 dest=/etc/nginx/nginx.conf
      # 當操作系統版本爲 7 的時候,執行當前操作,複製 nginx7.conf 到主機內
      when: ansible_distribution_major_version == "7"
      notify: restart service

    - name: copy template
      template: src=/root/ansible/templates/nginx6.conf.j2 dest=/etc/nginx/nginx.conf
      # 當操作系統版本爲 6 的時候,執行當前操作,複製 nginx6.conf 到主機內
      when: ansible_distribution_major_version == "6"
      notify: restart service

    - name: start service
      service: name=nginx state=started

  handlers:
    - name: restart service
      service: name=nginx state=restarted

[root@ansible ansible]# ansible-playbook tetempl.yml
PLAY [all] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [install package] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [copy template] ********************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [copy template] ********************************************************************************************************************************************************************************************
skipping: [192.168.31.167]
TASK [start service] ********************************************************************************************************************************************************************************************
ok: [192.168.31.167]
PLAY RECAP ******************************************************************************************************************************************************************************************************
192.168.31.167 : ok=4 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

5.2 相當於shell裏的for循環:

5.2.1 測試1,迭代:

[root@ansible ansible]# cat testitem.yml

---
- hosts: web
  remote_user: root

  tasks:
    - name: create some file
      file: name=/root/{{ item }}  state=touch
      when: ansible_distribution_major_version == "7"
      with_items:
        - file1
        - file2
        - file3
    - name: install some package
      yum: name={{ item }}
      with_items:
        - htop
        - sl
        - hping3

[root@ansible ansible]# ansible-playbook testitem.yml
PLAY [web] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [create some file] ***************************************************************************************************************
changed: [192.168.31.167] => (item=file1)
changed: [192.168.31.167] => (item=file2)
changed: [192.168.31.167] => (item=file3)
TASK [install some package] ***********************************************************************************************************
changed: [192.168.31.167] => (item=[u’htop’, u’sl’, u’hping3’])
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible ansible]# ansible web -m shell -a ‘ls /root/file* ; rpm -q sl hping3 htop’
192.168.31.167 | CHANGED | rc=0 >>
/root/file1
/root/file2
/root/file3
sl-5.02-1.el7.x86_64
hping3-0.0.20051105-24.el7.x86_64
htop-2.2.0-3.el7.x86_64

5.2.2 測試2,迭代嵌套子變量:

[root@ansible ansible]# cat testitem2.yml

---
- hosts: web
  remote_user: root

  tasks:
    - name: create some groups
      group: name={{ item }}
      when: ansible_distribution_major_version == "7"
      with_items:
        - g1
        - g2
        - g3

    - name: create some users
      user: name={{ item.name }} group={{ item.group }}
      with_items:
        # 把創建好的用戶,添加到指定的用戶組內
        - { name: 'user1', group: 'g1' }
        - { name: 'user2', group: 'g2' }
        - { name: 'user3', group: 'g3' }

[root@ansible ansible]# ansible-playbook testitem2.yml
PLAY [web] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [create some groups] *************************************************************************************************************
ok: [192.168.31.167] => (item=g1)
ok: [192.168.31.167] => (item=g2)
ok: [192.168.31.167] => (item=g3)
TASK [create some users] **************************************************************************************************************
changed: [192.168.31.167] => (item={u’group’: u’g1’, u’name’: u’user1’})
changed: [192.168.31.167] => (item={u’group’: u’g2’, u’name’: u’user2’})
changed: [192.168.31.167] => (item={u’group’: u’g3’, u’name’: u’user3’})
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible ansible]# ansible web -m shell -a ‘getent passwd | grep ^user; getent group | grep ^g’
192.168.31.167 | CHANGED | rc=0 >>
user1❌1002:1002::/home/user1:/bin/bash
user2❌1003:1003::/home/user2:/bin/bash
user3❌1004:1004::/home/user3:/bin/bash
g1❌1002:
g2❌1003:
g3❌1004:

5.3.1 寫成表達式的方式:

[root@ansible ansible]# cat templates/for1.conf.j2
{% for port in ports %}
server{
listen {{ port }}
}
{% endfor%}

[root@ansible ansible]# cat testfor.yml

---
- hosts: web
  remote_user: root
  vars:
    ports:
      - 81
      - 82
      - 83

  tasks:
    - name: copy conf
      template: src=for1.conf.j2 dest=/root/for1.conf

[root@ansible ansible]# ansible-playbook testfor.yml
PLAY [web] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [copy conf] **********************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible ansible]# ansible web -m shell -a ‘cat /root/for1.conf’
192.168.31.167 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}

5.3.2 或者可以寫成下面的方式

[root@ansible ansible]# cat testfor2.yml

---
- hosts: web
  remote_user: root
  vars:
    ports:
      - listen_port: 81
      - listen_port: 82
      - listen_port: 83

  tasks:
    - name: copy conf
      template: src=for2.conf.j2 dest=/root/for1.conf

[root@ansible ansible]# cat templates/for2.conf.j2
{% for port in ports %}
server{
listen {{ port.listen_port }}
}
{% endfor%}

5.4 比較複雜的

[root@ansible ansible]# cat testfor3.yml

---
- hosts: web
  remote_user: root
  vars:
    ports:
      - web1:
        port: 81
        name: web1.test.com
        rootdir: /root/website1

      - web2:
        port: 82
        name: web2.test.com
        rootdir: /root/website2

      - web3:
        port: 83
        name: web3.test.com
        rootdir: /root/website3

  tasks:
    - name: copy conf
      template: src=for3.conf.j2 dest=/root/for3.conf

[root@ansible ansible]# cat templates/for3.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
servername {{ p.name }}
documentroot {{ p.rootdir }}
}
{% endfor%}

[root@ansible ansible]# ansible-playbook testfor3.yml
PLAY [web] ****************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.31.167]
TASK [copy conf] **********************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ****************************************************************************************************************************
192.168.31.167 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible ansible]# ansible web -m shell -a ‘cat /root/for3.conf’
192.168.31.167 | CHANGED | rc=0 >>
server{
listen 81
servername web1.test.com
documentroot /root/website1
}
server{
listen 82
servername web2.test.com
documentroot /root/website2
}
server{
listen 83
servername web3.test.com
documentroot /root/website3
}

5.5 在for循環內添加if判斷

[root@ansible ansible]# cat templates/for4.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
{% if p.name is defined %}
servername {{ p.name }}
{% endif %}
documentroot {{ p.rootdir }}
}
{% endfor%}

[root@ansible ansible]# cat testfor4.yml

---
- hosts: web
  remote_user: root
  vars:
    ports:
      - web1:
        port: 81
        #name: web1.test.com
        rootdir: /root/website1

      - web2:
        port: 82
        name: web2.test.com
        rootdir: /root/website2

      - web3:
        port: 83
        #name: web3.test.com
        rootdir: /root/website3

  tasks:
    - name: copy conf
      template: src=for4.conf.j2 dest=/root/for4.conf

[root@ansible ansible]# ansible-playbook testfor4.yml
PLAY [web] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [192.168.31.167]
TASK [copy conf] ************************************************************************************************************************************************************************************************
changed: [192.168.31.167]
PLAY RECAP ******************************************************************************************************************************************************************************************************
192.168.31.167 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible ansible]# ansible web -m shell -a ‘cat /root/for4.conf’
192.168.31.167 | CHANGED | rc=0 >>
server{
listen 81
documentroot /root/website1
}
server{
listen 82
servername web2.test.com
documentroot /root/website2
}
server{
listen 83
documentroot /root/website3
}

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