zoukankan      html  css  js  c++  java
  • ansible-playbook的YAML语法学习

    YAML:可以将你打算对多机器的批量操作放到一个文件中,顺序执行,可以根据机器做到根据机器信息判断执行,其他命令执行结果判断执行。

    YAML有着严格的层级要求,稍微有个缩进问题就会无法运行,所以学习过程中,需要细心观察。

    命令      指定hosts文件位置     剧本文件     参数

    -C 调试模式,调试剧本是否可以正常运行(这个模式中,任何更改的操作都不会执行)

    ansible-playbook     -i hosts    yaml.file  
    ansible-playbook     -i hosts    yaml.file   -C
    

      

    剧本开始语法

    ---                                     #一个标识符,类似#!/bin/bash
    - hosts: all                            #此剧本作用域
      remote_user: root                     #使用什么用户运行此剧本
      gather_facts: True                    #在远程主机运行setup模块,并将收集的信息记录起来(等于命令ansible  all -m setup#查看系统信息),可以通过系统信息来判断是否执行
      vars:                                 #定义变量          
        variable: values
      tasks:                                #任务开始标签
       - name: task_name
         model_name: values
    

      

      

    每一个任务,可以指定一定的操作,定义一个任务基础参数如下

    #一个用name模块被'命名'任务下只允许有一个同级的模块存在(不包括辅助功能,后面会讲)

    - name: task_name
    model_name: values

    yaml语法中结构:

    [
    {
    'name': 'task_name', 
    'model_name': 'values'
    }
    ]
    

      

      

    以下这种情况,命名任务与模块是同级的情况下,可以正常执行,只是不在命名任务模块下的模块执行起来显示的是是模块名称,而不是任务名称(例子1-1),任务多了无法判断

    - model_name: values
    - name: task_name
    model_name: values
    - model_name: values

    yaml语法中结构:

    [
    {'model_name': 'values'},
    {
    'name': 'task_name',
     'model_name': 'values'
    }, 
    {'model_name': 'values'}
    ]
    

      

     例子1-1

    [root@host1 [10:02:30]/yaml/test]#cat test.yaml 
    ---
    - hosts: all
      remote_user: root
      gather_facts: True
      tasks:
        - name: "ping test"
          ping:
        - ping:
    
    [root@host1 [10:02:32]/yaml/test]#ansible-playbook -i hosts test.yaml  
    
    PLAY [all] ***********************************************************************************************************************************************************
    
    TASK [Gathering Facts] ***********************************************************************************************************************************************
    ok: [192.168.100.3]
    
    TASK [ping test] *****************************************************************************************************************************************************
    ok: [192.168.100.3]
    
    TASK [ping] **********************************************************************************************************************************************************
    ok: [192.168.100.3]
    
    PLAY RECAP ***********************************************************************************************************************************************************
    192.168.100.3              : ok=3    changed=0    unreachable=0    failed=0   
    
    [root@host1 [10:02:41]/yaml/test]#

      

    实际情况演练

    新建下方文件:

    [root@host1 [18:32:56]/yaml/test]#cat test.yaml 
    ---
    - hosts: all
      remote_user: root
      gather_facts: True
      tasks:
        - name: "ping test"
          ping:

    上方意思是新建ping test的任务,并执行ping模块,测试连通性,看下方结果,可以看到任务标签,并且状态也是成功的。(Gathering Facts 代表或许系统信息,也是成功的)

     #以下以"情况"的形式,向大家讲解如何使用常用方法

    情况1:你的环境中有多台机器,分别有CentOS6系统和CentOS7系列系统,两类系统在某些方面可能是不一样的,你现在两台机器上执行不同的操作,让我们来看看怎么实现。

    hosts文件内容

    100.3为centos6 秘钥对认证,可以免密连接

    100.7为centos7 没做过密钥对认证,通过密码认证

    192.168.100.3                          
    192.168.100.7 ansible_user=root ansible_password=nihao123!     

      

    执行下方命令

    ansible  all -m setup
    

    返回的是主机的信息,如系统类型,ip地址等,ansible可以根据这些做过滤

    在此情况下,我们可以通过 ansible_distribution和ansible_distribution_major_version进行匹配(以下是两台主机的信息组合,因为我使用的grep过滤的我需要的字段)

    [root@host1 [14:30:55]/yaml/test]#ansible -i hosts all  -m setup |grep "ansible_distribution" 
            "ansible_distribution": "CentOS", 
            "ansible_distribution_file_parsed": true, 
            "ansible_distribution_file_path": "/etc/redhat-release", 
            "ansible_distribution_file_variety": "RedHat", 
            "ansible_distribution_major_version": "7", 
            "ansible_distribution_release": "Core", 
            "ansible_distribution_version": "7.2.1511", 
            "ansible_distribution": "CentOS", 
            "ansible_distribution_file_parsed": true, 
            "ansible_distribution_file_path": "/etc/redhat-release", 
            "ansible_distribution_file_variety": "RedHat", 
            "ansible_distribution_major_version": "6", 
            "ansible_distribution_release": "Final", 
            "ansible_distribution_version": "6.5", 

    编写下方剧本。

    根据when执行判断条件,当系统版本为6时执行对应的任务,为7时执行对应的任务。

    [root@host1 [15:37:42]/yaml/test]#cat test2.yaml 
    ---
    - hosts: all
      remote_user: root
      gather_facts: True
      tasks:
        - name: "ping test"
          ping:
        - name: "only on Centos6"
          shell: "echo 'ON THE Centos6'"
          when: ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '6'
        - name: "only on Centos7"
          shell: "echo 'ON THE Centos7'"
          when: ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '7'

    执行测试,可以看到,任务执行时,都执行了对应的匹配条件,只有条件通过才执行对应的shell模块指定的命令,不通过时跳过执行。

    when匹配方式有多种,除了我们使用的a=a and b=b之外,大致常用的如下

    when: (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') or 
    (ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '5')
    
    #等同于and,匹配多个条件
    when:
          -ansible_distribution== "CentOS" 
          -ansible_distribution_major_version== "6"
    #对数字做大于小于的判断
    when:ansible_distribution_major_version|int >= 6
    #定义变量,并根据变量来判断对应任务是否是否执行
    vars:
      epic: true
    
    
    when: epic
    when not epic
    #通过上个模块执行结果来判断此模块是否执行(result|failed 可以替换为result is failed ),此方法使用方法详见例子1-2
    tasks:
      - command: /bin/false
        register: result
        ignore_errors: True              
      - command: /bin/something
        when: result|failed              
      - command: /bin/something_else
        when: result|success
      - command: /bin/still/something_else
        when: result|skipped
    

      

    例子1-2

    新建下方剧本,

    剧本含义:当cat /etc/fapweifjapewijfapwejfpawjf成立时,判断"when: result is success"才成立 

    (需要配合

    register: result #将执行结果记录到result变量上,给when提供判断条件

    ignore_errors: True #跳过错误,错误时继续执行,给when提供判断机会

    使用)

    ---
    - hosts: all
      remote_user: root
      gather_facts: True
      tasks:
        - shell: "cat /etc/fapweifjapewijfapwejfpawjf"
          register: result
          ignore_errors: True
    
        - shell: "head -10 /etc/fapweifjapewijfapwejfpawjf"
          when: result is success
    

    执行结果

    情况2:需要给多台机器添加yum源配置

    像这种问题,就是需要使用echo "" >> ..repo 到文件中去,但是,yum仓库的配置可不是只是一项,有什么能写的更简洁的方法呢。

    with_items  一个迭代器,你可以在里面定义很多的东西,然后在某处引用时,里面的东西会循环的输出,直到定义的值输出完。

    类似下方例子

    items=[1,2,3,4,5,6,7,8]
    
    for i in items:
        print(i)
    

    新建下方剧本

    gather_facts: no  在不需要获取机器信息时,根据信息做判断时,将其关闭,避免影响执行速度。

    定义名称:with_items,调用名称:item都是固定的,不能更改.

    {{variable}} 调用变量的方法,也是调用迭代器的方法。

    ---
    - hosts: all
      remote_user: root
      gather_facts: no
      tasks:
        - name: "setting yum"
          shell: "echo {{ item }} >> /etc/yum.repos.d/base.repo"
          with_items:
             - "[base]"
             - "name=base"
             - "baseurl=ftp://10.124.164.114/pub/Server"
             - "enabled=1"
             - "gpgcheck=0"

    在客户端上查看结果,已经正常写入。

    情况3:你需要一次操作多个服务,如启动,重启等。

    你可以使用情况2中的,定义with_items方法,但是你需要去with_items字段中定义,代码量多了难免有点麻烦,我们可以结合变量使用(在文首就直接定义了),定义一个列表,然后将列表传给with_items,交由它来做一个迭代器,当引用item时引用多个值。

    问:为什么不直接在{{}}中引用变量,而要引用迭代器

    因为变量无法在引用时被循环,就算列表里面有多个值,它引用时也只会识别一个列表,就是[nginx,ntpd]。

    ---
    - hosts: all
      remote_user: root
      gather_facts: no
      vars:
        service_list: [nginx,ntpd]
        service_state: restarted
      tasks:
        - service: name="{{item}}" state="{{service_state}}" 
          with_items: '{{ service_list }}'

    情况4:你的剧本文件中,定义了很多功能,但是这次,你只想运行某个功能,该如何实现呢。

    debug模块,只是一个功能,在此情况中,可以用任何模块替换,此模块是将msg定义的消息回显到终端,供我们调试。

    tags标签,定义在模块下,标签名称建议有意义,无难输入的特殊字符,无空格

    ---
    - hosts: all
      remote_user: root
      gather_facts: no
      tasks:
        - debug: msg="task 1"
          tags: task1
        - debug: msg="task two"
          tags: task2

    执行测试

     

    此情况重点来了,单独运行某个标签。使用如下命令

    只运行task1标签的任务

    [root@host1 [18:17:53]/yaml/test]#ansible-playbook -i hosts  --tags=task1   test5.yaml  
    

    学习了上面的使用情况,你已经可以写一个属于你的yaml剧本,使用什么模块实现什么功能,这个你可以边学边用,你可以试着完成下方我根据我工作环境自制的精简版ansible yaml剧本练习作业,巩固你的学习。

    以下要求需要在你写时,写在同一剧本中

    1.新建用户 admin,deployer,并定义密码

    2.设置用户永不过期

    3.备份/home/admin/   的所有文件(包括隐藏文件) ,(假设你有一个叫/dev/vdb的磁盘),判断/dev/vdb是否挂载,如果挂载了,就不用管,如果没有挂载,将其挂载到/home/admin/ ,恢复你备份的文件至/home/admin/

    4.同步服务器的时间,将时间同步服务设置为自启动

    5.先零时,后永久的增加ulimit ("max user processes", "open files", "pending signals")这三个值的大小,具体大小自定义,达到更改效果即可。

    6.先零时关闭防火墙,selinux,后设置永久关闭。

    7.将hostname 和本机ip的对应关系增加至/etc/hosts文件中

    8.设置yum仓库,让其能正常下载软件,

    9,支持运行此剧本时,指定值运行[同步时间]任务,而不设置时间同步服务自启动

  • 相关阅读:
    C#中判断为空
    ArcGIS中的AddIn开发示例
    当前不会命中断点,还没有加载该文档加载任何符号
    设置ArcGIS的外观改回到出厂
    读取Style符号库样式的方法
    ArcEngine中的缩放地图
    修改字段结构之GP工具
    修改字段结构之ArcGIS Diagrammer
    merage语句
    Windows下Redis的安装使用
  • 原文地址:https://www.cnblogs.com/xiaodai12138/p/10104065.html
Copyright © 2011-2022 走看看