王杰

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

9-AnsiblePlaybook

07.Ansible 自动化配置进阶

  1. Playbook剧本初识
  2. Playbook变量使用
  3. Playbook变量注册
  4. Playbook条件语句
  5. Playbook循环语句
  6. Playbook异常处理
  7. Playbook tabs标签
  8. Playbook Handlers
  9. Playbook Include
  10. Playbook项目实践

 

1.Playbook, playbook 翻译过来就是“剧本”,那 playbook组成如下

play:定义的是主机的角色

task:定义的是具体执行的任务

playbook:由一个或多个play组成,一个play可以包含多个任务

简单理解为:使用不同的模块完成一件事情

 

Playbook组成
--- -hosts:all remote_user:root vars: file_name:username tasks: -name:touch new files shell:touch /tmp/{{file_name}}

 

2.playbook的优势

  1. 功能比ad-hoc更全
  2. 能很好的控制先后顺序,以及依赖关系
  3. 语法展现更加的直观
  4. ad-hoc 无法持久使用,playbook 可以持久使用

 

3.paaybook的配置语法是由yaml语法描述的,扩展名是yaml

缩进:YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用 tabs。

冒号:以冒号结尾的除外,其他所有冒号后面所有必须有空格。

短横线:表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表。

- host: nfs
  tsaks:
  - name: Installed NFS
    yum: name=nfs-utils state=present
 
  - name: Copy File exports
    copy: src=./exports.template dest=/etc/exports

  - name: Start NFS Server
    service: name=nfs-server state=started enabled=yes

 

4.playbook示例

在一个playbook里面写一个play, 一个task任务

[root@manager ~]#cat f1.yml
---
- hosts: all
  remote_user: root
  vars:
      file_name: yuyu
  tasks:
     - name: Create New File
       file: name=/tmp/{{ file_name }} state=touch

#playbook执行方式
[root@manager ~]#ansible-playbook f1.yml

 

5.Playbook 执行结果返回

红色:表示有task执行失败或者提醒的信息

黄色:表示执行了且改变了远程主机状态

绿色:表示执行成功

 

[root@manager ~]# cat 1.yml 
---
#play
- hosts: nfs
  tasks:
    - name: Create New File
      file: path=/tmp/test.txt state=touch owner=root group=root mode=400

  [root@manager ~]# ansible-playbook --syntax-check 1.yml   检查ansible-playbook 语法

   playbook: 1.yml


[root@manager ~]ansible-playbook -C 1.yml  模拟执行playbook

[root@manager ~]# ansible-playbook 1.yml 

PLAY [nfs] *******************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************
ok: [172.26.73.197]

TASK [Create New File] *******************************************************************************************************************
changed: [172.26.73.197]

PLAY RECAP *******************************************************************************************************************************
172.26.73.197              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

用ansible 命令检查结果

[root@manager ~]# ansible nfs -m shell -a "ls /tmp/test.txt"
172.26.73.197 | CHANGED | rc=0 >>
/tmp/test.txt

[root@manager ~]# ansible nfs -m shell -a "ls /tmp/"
172.26.73.197 | CHANGED | rc=0 >>
ansible_command_payload_iDPoma
systemd-private-1d90ff6fe63b499d848ce28248137b36-chronyd.service-tbXpdx
test.txt
this_is_nfs_file

在一个playbook里面写一个play,多个task任务

[root@manager ~]# cat 1.yml 
---
#play
- hosts: all
  tasks:
    - name: Create New File
      file: path=/tmp/test.txt state=touch owner=root group=root mode=400

    - name: Creat New Directory
      file: path=/tmp/exam_dir state=dirctory owner=root grout=root mode=700

在一个playbook里面写多个play, 多个task 任务【不建议】

[root@manager ~]# cat 1.yml 
---
#play
- hosts: all
  tasks:
    - name: Create New File
      file: path=/tmp/test.txt state=touch owner=root group=root mode=400

    - name: Creat New Directory
      file: path=/tmp/exam_dir state=dirctory owner=root grout=root mode=700

- hosts: nfs
  tasks:
    - name: Create NFS New File
      file: path=/opt/test.txt state=touch owner=root group=root mode=400
[root@manager ~]# ansible-playbook --syntax-check 1.yml 

playbook: 1.yml
[root@manager ~]# 

 

2.Playbook变量使用

Playbook定义变量有三种方式

1)playbook的yaml文件中定义亦是赋值

2)--extra-vars执行参数赋给变量

3)在文件中定义变量 vars_files

4)在主机清单中定义 

 

1. playbook的yaml文件中定义变量赋值

[root@manager ~]# cat f2.yml 
---
- hosts: nfs
  vars:  #定义变量
    file_name:bgx_yaml_vars

  tasks:
  - name:  #{{ file_name }}引用上面定义的变量
    file: path=/tmp/{{ file_name }} state=touch

#playbook执行,在/tmp 目录创建bgx_yaml_vars文件

 

2、 --extra-vars执行参数赋给变量

[root@manager ~]# ansible-playbook --syntax-check f3.yml 

playbook: f3.yml
[root@manager ~]# cat f3.yml 
---
- hosts: nfs

  tasks:
  - name: Create New File
    file: path=/tmp/{{ file_name }} state=touch


#playbook 执行时传入file_name变量的参数,在/tmp目录创建bgx_extra-avrs文件

[root@manager ~] ansible-playbook f3.yml --extra-vars "file_name=temp_extra"

 

3、在文件中定义变量:可以在 /etc/ansible/hosts 主机组中定义,然后使用 playbook进行调度该变量

 在文件中定义变量

[root@manager ~]# cat /etc/ansible/hosts 

[backup]
172.26.73.200

[nfs]
172.26.73.197
[nfs:vars]
file_name=bgx_filename

[web]
172.26.73.198

在playbook中使用变量

[root@manager ~]# cat f4.yml 
---
- hosts: all

  tasks:
  - name: Create New File
    file: path=/tmp/{{ file_name }} state=touch

 

如果定义的变量出现重复,且造成冲突,优先级如下:

1. extra-vars 外置传参的优先级最高【所有执行的主机都生效】

2.定义在yml文件中的优先级其次【所有执行的主机都生效】

3.hosts文件中定义的变量优先级最低【当前主机组定义会生效】

 

3.Playbook变量注册

1)注册变量:register关键字可以存储指定命令的输出结果到一个自定义的变量中

 

[root@manager ~]# cat f5.yml 
---
- hosts: all
  tasks:
    - name: Network Status
      shell: netstat -lntp|grep sshd
      register: Net_Status

    - name: Output Status
      debug: msg={{ Net_Status.stdout_lines }}


[root@manager ~]# ansible-playbook f5.yml 

PLAY [all] *******************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************
ok: [172.26.73.197]

TASK [Network Status] ********************************************************************************************************************
changed: [172.26.73.197]

TASK [Output Status] *********************************************************************************************************************
ok: [172.26.73.197] => {
    "msg": [
        "tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1208/sshd           "
    ]
}

PLAY RECAP *******************************************************************************************************************************
172.26.73.197              : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

 

 

 

 

4.Playbook条件语句

playbook中的条件判断语句使用when

[root@manager ~]# cat f6.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: Create File
      file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch
      when: (ansible_hostname == "nfs") or (ansible_hostname == "backup")

#系统为centos的主机才会执行
    - name: Centos Install httpd
      yum: name=httpd state=present
      when: (ansible_distribution == "CentOS")

#系统为ubuntu的主机才会执行
    - name: Ubuntu Install httpd
      yum: name=httpd2 state=present
      when: (ansible_distribution == "Ubuntu")



[root@manager ~]# ansible-playbook f6.yml 

PLAY [all] *******************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************
ok: [172.26.73.197]
fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true}
fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true}

TASK [Create File] ***********************************************************************************************************************
changed: [172.26.73.197]

TASK [Centos Install httpd] **************************************************************************************************************
changed: [172.26.73.197]

TASK [Ubuntu Install httpd] **************************************************************************************************************
skipping: [172.26.73.197]

PLAY RECAP *******************************************************************************************************************************
172.26.73.197              : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
172.26.73.198              : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   
172.26.73.200              : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0 

 使用when来实现判断

[root@manager ~]# ansible nfs -m shell -a 'ls /tmp/this*'
172.26.73.197 | CHANGED | rc=0 >>
/tmp/this_is_nfs_file

[root@manager ~]# vim 4.yml
[root@manager ~]# ansible-playbook --syntax-check 4.yml 

playbook: 4.yml
[root@manager ~]# cat 4.yml 
---
- hosts: all
  tasks:
    - name: Create New File {{ ansible_hostname }}
      file: path=/tmp/this_is _{{ ansible_hostname }}_when state=touch
      when: (ansible_hostname == "nfs") or (ansible_hostname == "backup")

 

 

获取主机名

[root@manager ~]# ansible nfs -m setup |grep hostname
        "ansible_hostname": "nfs", 
[root@manager ~]# ansible nfs -m setup -a 'filter=ansible_hostname'
172.26.73.197 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "nfs", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
[root@manager ~]# ansible nfs -m shell -a 'ls /tmp/this*'
172.26.73.197 | CHANGED | rc=0 >>
/tmp/this_is_nfs_file

 

 

 

 

 

 

5.Playbook循环语句

1、标准循环使用场景-批量安装软件

[root@manager ~]# cat f7.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: Installed Pkg
      yum: name={{ item }} state=present
      with_items:
        - wget
        - tree
        - lrzsz

- hosts: backup
  tasks:
- name: Copy
copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }}
with_items:
- {src: "./rsyncd.conf.template",dest: "/etc/rsyncd.conf",mode: "0644"}
- {src: "./rsync.pass.template",dest: "/etc/rsync.pass",mode:"0600"}

[root@manager ~]# ansible-playbook f7.yml

 

 

 

2、标准循环使用场景-批量创建用户

[root@manager ~]# cat f7.yml 
---
- hosts: nfs
  remote_user: root
  tasks:
    - name: Add Users
      user: name={{ item.name }} groups={{ item.groups }} state=present
      with_items:
        - { name: 'testuser1', groups: 'bin' }
        - { name: 'testuser2', groups: 'root' }

[root@manager
~]# ansible-playbook f7.yml PLAY [all] ******************************************************************************************************************************* TASK [Gathering Facts] ******************************************************************************************************************* ok: [172.26.73.197] fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true} fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true} TASK [Add Users] ************************************************************************************************************************* changed: [172.26.73.197] => (item={u'name': u'testuser1', u'groups': u'bin'}) changed: [172.26.73.197] => (item={u'name': u'testuser2', u'groups': u'root'}) PLAY RECAP ******************************************************************************************************************************* 172.26.73.197 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.198 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 172.26.73.200 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0

 

3、标准循环使用场景-拷贝多个目录

- hosts: backup
  remote_user: root
  tasks:
    - name: Configure Rsync Server
      copy: src={{ item.src }} dest=/etc/{{ item.dest }} mode={{ item.mode }}
      with_items:
        - {src: "./rsyncd.conf",dest: "rsyncd.conf",mode: "0644"}
        - {src: "./rsync.passwd",dest: "rsync.passwd",mode:"0600"}

 

6.Playbook异常处理

 

默认Playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行加入参数:ignore_errors: yes 忽略错误

 

[root@manager ~]# cat f9.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: Ignore False
      command: /bin/false
      ignore_errors: yes

    - name: touch new file
      file: path=/tmp/bgx_ignore state=touch

 

 

playbook过程中会跳过错误

 

[root@manager ~]# ansible-playbook f9.yml 

PLAY [all] *******************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************
ok: [172.26.73.197]
fatal: [172.26.73.200]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.200 port 22: Connection timed out", "unreachable": true}
fatal: [172.26.73.198]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.26.73.198 port 22: Connection timed out", "unreachable": true}

TASK [Ignore False] **********************************************************************************************************************
fatal: [172.26.73.197]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.020915", "end": "2020-04-25 23:24:22.610287", "msg": "non-zero return code", "rc": 1, "start": "2020-04-25 23:24:22.589372", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [touch new file] ********************************************************************************************************************
changed: [172.26.73.197]

PLAY RECAP *******************************************************************************************************************************
172.26.73.197              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   
172.26.73.198              : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   
172.26.73.200              : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   

 

 

 

 

 

 

7.Playbook tags标签

1.打标签

对一个对象打一个标签,最常用

对一个对象打多个标签

对多个对象打一个标签

2. 标签使用,通过tags和任务对象进行捆绑,控制部分或者指定的task 执行

-t: 执行指定的 tag 标签任务

--skip-tags: 执行--skip-tags之外的标签任务

 

[root@manager ~]# cat f10.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: Install NFS Server
      yum: name=nfs-utils state=present
      tags:
        - install_nfs
        - install_nfs-server

        - name: Service NFS Server
          service: name=nfs-server state=started enabled=yes
          tags: start_nfs-server
[root@manager ~]# 

[root@manager ~]# ansible-playbook --syntax-check 8.yml 

playbook: f10-1.yml
[root@manager ~]# cat 8.yml 
---
- hosts: all
  tasks:
    - name: Installed Package
      yum: name={{ item }} state=present
      with_items:
        - httpd
        - httpd-tools
      tags:
        - install
        - install_httpd

    - name: Service Start
      service: name=httpd state=started enabled=yes
      tags: start_httpd
[root@manager ~]# 

 

 执行8.yml的playbook,仅执行install_httpd标签的任务

[root@manager ~]# ansible-playbook 8.yml -t install_httpd

 

执行8.yml的playbook,除了install_httpd标签外的任务都执行

[root@manager ~]# ansible-playbook 8.yml --skip-tags install_httpd

 

8.Playbook Handlers

playbook 安装 Apache 示例

 

[root@manager ~]# cat webserver.yml 
---
- hosts: web
  remote_user: root
#1.定义变量,在配置文件中调用
  vars:
    http_port: 80

#2.安装httpd服务
  tasks:
    - name: Install Httpd Server
      yum: name=httpd state=present

#3.使用template模板,引用上面vars定义的变量至配置文件中
    - name: Configure Httpd Server
      template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify: Restart Httpd Server

#4.启动Httpd服务
    - name: Start Httpd Server
      service: name=httpd state=started enabled=yes

#5.检查Httpd服务当前的运行端口状态
    - name: Out Httpd Server Status
      debug: msg={{ Httpd_Port.stdout_lines }}
      ignore_errors: yes

#6.如果配置文件发生变化会调用该handlers下面的模块
  handlers:
    - name: Restart Httpd Server
      service: name=httpd state=restarted
[root@manager ~]# 

 

playbook中的handlers, 当copy的配置文件发生变化时,会触发notify后面的名称,名称对应的是handlers中定义的

 

[root@manager ~]# cat 9.yml 
---
- hosts: web
  tasks:
    - name: Install Httpd Server
      yum: name=httpd state=present

    - name: Configure Httpd Server
      copy: src=./httpd.conf.template dest=/etc/httpd/conf/httpd.conf backup=yes
      notify: Restart Httpd Server
        - Restart Httpd
        - Restart Rsyncd
- name: Start Httpd Server
      service: name=httpd state=started enabled=yes

  handlers:
    - name: Restart Httpd Server
      service: name=httpd state=restarted

    - name: Restart Rsyncd
      service: name=httpd state=restarted
[root@manager ~]# 

 

9.Playbook Include

include 用来动态的包含 tasks任务列表, include_tasks 新版/include老版

include 调用任务方式

 #主入口文件

[root@manager ~]# ansible-playbook --syntax-check main.yml 

playbook: main.yml
[root@manager ~]# vim f20.yml
[root@manager ~]# 
[root@manager ~]# cat f20.yml 
- name: create file1
  command: touch file1
[root@manager ~]# vim f21.yml
[root@manager ~]# cat f21.yml 
- name: create file2
  command: touch file2
[root@manager ~]# cat main.yml 
- hosts: all
  remote_user: root
  tasks:
    - include_tasks: f20.yml
    - include_tasks: f21.yml
       
[root@manager ~]# 

 

include包含文件,包含的文件必须都是一个完整的playbook

[root@manager ~]# vim site.yml
[root@manager ~]# 
[root@manager ~]# cat site.yml 
- include:
    1.yml
    2.yml
    3.yml
[root@manager ~]# 

 

 

posted on 2020-04-20 17:00  Sunjingjing  阅读(191)  评论(0)    收藏  举报