Ansible playbook进阶

playbook进阶
语法进阶
变量
error
handlers
when
register
with_items
with_nested
tags
include-and-roles
调试
debug

playbook进阶

语法进阶

变量

  • 添加用户

给所有主机添加用户srv ,设置默认密码123456
要求第次登录修改密码 ( 使用变量 )

[root@web1 ~]# vim user.yml
---
- hosts: xl
  remote_user: root
  vars:
    username: bb # 变量 username = bb
  tasks:

    - name: 创建用户名 "{{username}}"
      user:
        name: "{{username}}"
    - name: 设置密码
      shell: echo 123 | passwd --stdin "{{username}}"
    - shell: chage -d 0 "{{username}}"
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

[root@web1 ~]# vim user.yml
---
- hosts: xl
  remote_user: root
  vars:
  tasks:

    - name: 创建用户名 "{{username}}"
      user:
        name: "{{username}}"
    - name: 设置密码
      shell: echo 123 | passwd --stdin "{{username}}"
    - shell: chage -d 0 "{{username}}"
[root@web1 ~]# ansible-playbook user.yml -e '{"username": "cc"}'

在这里插入图片描述

  • 设密码

解决密码明文问题
user模块的password为什么不能设置密码呢
经过测试发现, password是把字符串直接写入shadow,并没有改变,而Linux的shadow密码是经过加密的,所以不能使用

  • 解决方案

变量过滤器password_hash

[root@web1 ~]# ansible-doc user

在这里插入图片描述

[root@web1 ~]# 
---
- hosts: xl
  remote_user: root
  vars:
    username: dd
  tasks:

    - name: 创建用户名 "{{username}}"
      user:
        name: "{{username}}"
        password: "123"
    - shell: chage -d 0 "{{username}}"
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

[root@web1 ~]# ssh -l dd xl

在这里插入图片描述
让我们来看看id和密码文件

[root@web1 ~]# ssh xl
[root@xl ~]# id dd

在这里插入图片描述

[root@xl ~]# vim /etc/shadow

在这里插入图片描述

  • 变量过滤器

那我们来帮dd用户加密

[root@web1 ~]# vim user.yml
---
- hosts: xl
  remote_user: root
  vars:
    username: dd
  tasks:

    - name: 创建用户名 "{{username}}"
      user:
        name: "{{username}}"
        password: "{{'123' | password_hash('sha512')}}"
    - shell: chage -d 0 "{{username}}"
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述
测试

[root@web1 ~]# ssh xl
[root@xl ~]# cat /etc/shadow

在这里插入图片描述

error

  • ansible-playbook对错误的处理

默认情况判断$? ,如果值不为0就停止执行
但某些情况我们需要忽略错误继续执行

[root@web1 ~]# vim user.yml
---
- hosts: xl
  remote_user: root
  vars:
    username: aa
  tasks:
    - shell:
      ignore_errors: True
    - shell: echo 123 | passwd --stdin aa
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

  • 错误处理方法

关闭selinux ,如果selinux已经关闭, 返回1,若之前已经关闭则不算错误,可以忽略错误继续运行,忽略错误有两种方法
第一种方式:

    shell: /usr/bin/somecommand || /bin/true

第二种方式:

  - name: run some command
    shell: /usr/bin/somecommand
	ignore_errors: True
  • 完整的playbook
[root@web1 ~]# vim user.yml

---
- hosts: xl
  remote_user: root
  tasks:
    - user:
        name: aa
        password: "{{'123'|password_hash('sha512')}}"
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

handlers

  • 当关注的资源发生变化时采取的操作
  • notify这个action可用于在每个play的最后被触发,这样可以避免有多次改变发生时每次都执行指定的操作,取而代之仅在所有的变化发生完成后一次性地执行指定操作
  • 在notify中列出的操作称为handler,即notify调用handler中定义的操作
  • 前面安装了Apache ,修改httpd的配置文件,重新载入配置文件让服务生效
  • 使用handers来实现
[root@web1 ~]# lftp sftp://web2
lftp web2:~> cd /etc/httpd/conf
lftp web2:/etc/httpd/conf> get httpd.conf
lftp web2:/etc/httpd/conf> bye

在这里插入图片描述

[root@web1 ~]# vim httpd.conf
Listen 88                           # 42行
[root@web1 ~]# vim httpconf.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - copy:
        src: /root/httpd.conf
        dest: /etc/httpd/conf/httpd.conf
        owner: root
        group: root
        mode: 0644
    - service:
        name: httpd
        state: restarted
[root@web1 ~]# ansible-playbook httpconf.yml

在这里插入图片描述

[root@web1 ~]# curl mysql1:88

在这里插入图片描述

  • 结合之前实验,完整的playbook
[root@web1 ~]# vim httpd.conf
Listen 80                           # 42行
[root@web1 ~]# vim httpconf.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - copy:
        src: /root/httpd.conf
        dest: /etc/httpd/conf/httpd.conf
        owner: root
        group: root
        mode: 0644
      tags: aabb
      notify: reloadhttp
  handlers:
    - name: reloadhttp
      service:
        name: httpd
        state: restarted
[root@web1 ~]# ansible-playbook httpconf.yml -t aabb

在这里插入图片描述

[root@web1 ~]# curl mysql1:80
hello ansible
  • 注意事项:

notify调用的是handler段的name定义的串,必须一致,否则达不到触发的效果
多个task触发同一个notify的时候,同一个服务只会触发一次
notify可以触发多个条件,在生产环境中往往涉及到某一个配置文件的改变要重启若干服务的场景, handler用到这里非常适合
结合vars可以写出非常普适的服务管理脚本

when

  • 有些时候需要在满足特定的条件后再触发某一项操作,或在特定的条件下终止某个行为,这个时候需要进行条件判断,when正是解决这个问题的最佳选择,远程中的系统变量facts作为when的条件,可以通过setup模块查看

when的样例

[root@web1 ~]# ansible xl -m setup -a 'filter=ansible_os_family'

在这里插入图片描述

  • 一个使用when的例子
[root@web1 ~]# vim user.yml
---
- hosts: xl
  remote_user: root
  tasks:
    - shell: id aa
      register: result
    - user:
        name: aa
        password: "{{'123'|password_hash('sha512')}}"
      when: result
[root@web1 ~]# uptime | awk '{print $(NF-2)}'
0.00,
[root@web1 ~]# printf "aaaaa"
aaaaa[root@web1 ~]# 
[root@web1 ~]# uptime | awk '{printf("%f",$(NF-2))}'
0.020000[root@web1 ~]# 
[root@web1 ~]# uptime | awk '{printf("%.2f",$(NF-2))}'
0.01[root@web1 ~]# 
[root@web1 ~]# vim load.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - shell: uptime | awk '{printf("%.2f",$(NF-2))}'
      register: result
    - service:
        name: httpd
        state: stopped
      when: result.stdout|float > 0.7
[root@web1 ~]# ansible-playbook load.yml

在这里插入图片描述

register

  • register

有时候我们还需要更复杂的例子,如判断前一个命令的执行结果去处理后面的操作,这时候就需要register模块来保存前一个命令的返回状态,在后面进行调用
针对运行命令结果的返回值做判定
当系统负载超过一定值的时候做特殊处理

[root@mysql2 ~]# awk 'BEGIN{while(1){}}' &
[root@mysql2 ~]# watch -n 1 'uptime'
[root@web1 ~]# vim load.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - shell: uptime | awk '{printf("%.2f",$(NF-2))}'
      register: result
    - service:
        name: httpd
        state: stopped
      when: result.stdout|float > 0.7
[root@web1 ~]# ansible-playbook load.yml

在这里插入图片描述

  • with_items进阶

为不同用户定义不同组

[root@web1 ~]# vim user.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - user:
        name: "{{item}}"
        group: root
        password: "{{'123'|password_hash('sha512')}}"
      with_items:
        - aa
        - bb
        - cc
        - dd
        - ee
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

[root@web1 ~]# vim user.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - user:
        name: "{{item.username}}"
        group: "{{item.group}}"
        password: "{{item.password|password_hash('sha512')}}"
      with_items:
        - 
          username: nb
          password: bn
          group: users
        - 
          username: wk
          password: kw
          group: man
        - 
          username: dd
          password: dd
          group: daemon
        - 
          username: ww
          password: 123qqq...A
          group: mysql
        - 
          username: xx
          password: oo
          group: root
[root@web1 ~]# ansible-playbook user.yml

在这里插入图片描述

with_nested

  • 嵌套循环:
[root@web1 ~]# vim test.yml
---
- hosts: mysql
  remote_user: root
  vars:
    id: [1, 2, 3]
    un: ['a', 'b', 'c']
  tasks:
    - shell: echo {{item}}
      with_nested:
        - "{{id}}"
        - "{{un}}"
[root@web1 ~]# ansible-playbook test.yml 

在这里插入图片描述

tags

  • tags: 给指定的任务定义一个调用标识
  • 使用格式:

name: NAME
module: arguments
tags: TAG_ID

  • playbook调用方式

-t TAGS, --tags=TAGS
–skip-tags=SKIP_TAGS
–start-at-task=START_AT

include and roles

  • 在编写playbook的时候随着项目越来越大, playbook越来越复杂,修改也很麻烦。这时可以把一些play、task 或 handler放到其他文件中,通过include指令包含进来是一个不错的选择
????
  • roles像是加强版的include ,它可以引入一个项目的文件和目录
  • 一般所需的目录层级有

vars : 变量层
tasks : 任务层
handlers : 触发条件
files : 文件
template : 模板
default : 默认,优先级最低

  • 假如有一个play包含了一个叫"x"的role ,则
????

x/tasks/main.yml
x/vars/main.yml
x/handler/main.yml
x/… …main.yml
都会自动添加进这个play

测试

debug

  • 对于Python语法不熟悉的同学, playbook书写起来容易出错,且排错困难,这里介绍几种简单的排错调试方法

检测语法

[root@web1 ~]# vim dubug.yml
---
- hosts: mysql
  remote_user: root
  tasks:
    - shell: uptime | awk '{printf("%.2f",$(NF-2))}'
      register: result
    - service: 
        name: httpd
        state: stopped
      when: result.stdout|float > 0.7
    - name: debug info
      debug: var=result
[root@web1 ~]# ansible-playbook dubug.yml

在这里插入图片描述
测试运行


显示受到影响的主机–list-hosts
显示I作的task --list-tasks
显示将要运行的tag --list tags

  • debug模块可以在运行时输出更为详细的信息,帮助我们排错
  • debug使用样例

发布了96 篇原创文章 · 获赞 100 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43395428/article/details/104888940