王杰

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

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  阅读(149)  评论(0)    收藏  举报