天天看点

ansible剧本执行基础 playbook变量使用

文章目录

    • playbook
      • sudo提权
        • 配置文件
        • ansible配置用户提权
          • 分析
          • 测试
      • 修改ansible配置(配合sudo使用)
        • 测试
        • inventory补充
      • ansible-playbook使用
        • YAML
        • YAML格式要求
        • YAML格式理解
        • YAML简单总结
        • playbook语法格式要求
        • 实际测试
          • ansible-playbook ping模块
          • ansible-playbook 单play多任务执行
          • ansible-playbook 多play执行多任务
          • 剧本格式总结
            • 格式
      • setup 和 debug模块
        • 说明
        • 测试
          • setup测试 filter过滤
          • debug测试 显示信息
        • 自定义变量的方法
          • 总结

playbook

sudo提权

  • 管理员需要先授权(修改/etc/sudoers)
  • 普通用户用sudo命令来提权执行相应的命令

配置文件

  • 位置
    • /etc/sudoers
  • 格式
    • vim /etc/sudoers
      ====================================
      # 用户名(%组名)    主机名=(提权用户名)  提权命令
         root		         ALL=(ALL)		NOPASSWD:ALL   #NOPASSWD   不需要输入密码
      ====================================
                 

ansible配置用户提权

分析
  • 创建用户使用user模块
  • 提权修改文件使用lineInfile模块
测试
#控制端
cd ansible #cd到ansible目录下  目的使用ansible目录下的主机清单文件
ansible all -m user -a "name=alice password={{'123456' | password_hash('sha512')}}"
#创建alice用户密码设置为123456
#全部CHANGED  成功

#提权操作
ansible all -m lineinfile -a "path=/etc/sudoers line='alice	ALL=(ALL) NOPASSWD:ALL'"

#全部CHANGED 成功
#测试验证
ssh [email protected]
#输入123456
sudo systemctl restart sshd    #执行成功  说明alice提权成功
exit  #退出ssh
           

修改ansible配置(配合sudo使用)

测试

#控制端
vim ~/ansible/ansible.cfg
=================================
[defaults]
inventory = ~/ansible/inventory
remote_user = alice                    #远程管理时候使用的用户名(是被控制端的用户)
[privilege_escalation]
become = True						#为真  需要提权
become_method = sudo				#切换用户的方式  有sudo  su
become_user = root					#切换成什么用户  sudo -u 用户名/uid 来指定变成谁
become_ask_pass = no				#执行sudo命令提权时是否需要输入密码(设置了NOPASSWD就不需要了)
=================================
#配置好了  赶紧测试下
ansible all -m command -a "who"
#失败了 
node1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: [email protected]: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
    "unreachable": true
}
#看完msg  发现ssh  alice不被允许   思考下.......好像是没给ssh密钥!
#赶紧给
for i in node1 node2 node3 node4 node5
>do
	ssh-copy-id  alice@$i
>done
#输入alice密码    完成发送
#再来测试下
ansible all -m command -a "who"
node2 | CHANGED | rc=0 >>
alice    pts/0        2020-12-21 04:42 (192.168.4.253)
#成功了  并且返回了alice从控制端4.253进入的情况
           

inventory补充

#清单文件补充
vim ~/ansible/inventory
=============================
[test]
node1    ansible_ssh_port=端口号  ansible_ssh_user=用户名 ansible_ssh_pass=密码
#主机名	ssh端口号  具体看被控制端ssh在哪个端口  指定登录用户 优先级比主配置文件高  远程连接密码(不是用户密码!) 之前测试用的ssh密码都是为空的

#怪不得一行只能定义一个主机名  后面要加参数  所以一行只能写一个或者切片方式同时赋予参数
=============================
           

ansible-playbook使用

YAML

  • YAML是一个可读性高、用来表达数据序列的格式语言
  • YAML:YAML Ain’t a Markup Language
  • YAML以数据为中心,重点描述数据的关系和结构

YAML格式要求

  • ‘#’代表注释,一般第一行为三个横杠(—)
  • 键值(key/value)对使用’:‘表示,数组使用’-‘表示,’-'后面有空格
  • key和value之间使用’:'分隔
  • 一般缩进由两个或以上空格组成
  • 相同层级的缩进必须对齐,缩进代表层级关系
  • 全文不可以使用tab键~~(??? tab不香吗)~~
  • 区分大小写
  • 扩展名为yml或者yaml
  • 跨行数据需要使用**>或者|**,其中|会保留换行符

YAML格式理解

  • 普通键值对
---
"师仙": "李白"                      #:后面有空格

---
"师仙":
  "李白"                        	#两个以上空格 不能tab
  									#最简单键值对形式
           
  • 数组 [苹果,香蕉]
---
- "苹果"
- "香蕉"		
           
  • 键值对 值为数组
---
"水果": ["苹果","梨","香蕉"]

---
"水果":
  - "苹果"
  - "梨"
  - "香蕉"
           
  • 键值对套键值对 值为数组 水果 :[热带水果:[香蕉], 亚热带水果:[我不知道]]
---
- "水果":
  - 热带水果:
    - "香蕉"
  - 亚热带水果:
    - "我不知道"
           
  • 键值对数组 [{产品名:维达 卫生标准: GB15979 主要原料: 100%原生木浆}]
---
- 产品名: 维达
  卫生标准: GB15979
  主要原料: 100%原生木浆
           
  • 跨行文本
---
开场宣言: >                        #理解为一行   >不会记录换行符  所以就是一行
  白洞白色的明天			#白洞白色的明天在等着我们就是这样 喵
  在等着我们
  就是这样 喵
  
---
开场宣言: |                           #理解为多行   |会记录换行符 所以就是看到的这样
  武藏							#武藏
  小次郎							#小次郎
  喵喵							#喵喵
           

YAML简单总结

  • YAML数据格式是键值对和数组相互嵌套
  • 用两个以上空格 相同空格数来区分层级

playbook语法格式要求

  • playbook采用YAML格式编写
  • playbook文件中由一个或多个play组成
  • 每个play中可以包含:
    • name (描述信息)
    • hosts(主机)
    • tasks(任务)
    • vars(变量)
    • 等等
  • 使用ansible-playbook命令运行playbook剧本
  • -f 选项自定义并发量
  • 顺序执行.yml里面的play
  • 默认会执行Gathering Facts的任务 是setup模块的功能 收集被管理的系统信息并保存在变量中 可以通过setup模块查看

实际测试

ansible-playbook ping模块
vim ~/ansible/test.yml
==========================
---    #默认开头三个横
- hosts: all        #数组 键值对 hosts的值为主机  all全部具体看inventory  :后面要有空格
  tasks:            #开头两个空格
    - name: 描述信息        #再缩进两个空格 不能tab 描述信息
      ping:				  #调用ping模块
==========================
#调用ansible-playbook执行.yml
ansible-playbook test.yml
PLAY [all] ***************      #一个剧本  控制的主机是all hosts的值

TASK [Gathering Facts] **************   #默认会执行Gathering Facts这个任务 获取每个控制主机的Facts值
ok: [node5]							#可以在.yml(执行的剧本中取消执行)
ok: [node3]						# - hosts: all
ok: [node2]						#   gather_facts: flase     #设定为flase取消执行 加快任务执行		
ok: [node1]
ok: [node4]

TASK [描述信息] **********   #name的值    任务执行结果  全是ok
ok: [node5]
ok: [node4]
ok: [node1]
ok: [node3]
ok: [node2]

PLAY RECAP **************  #返回具体参数
node1        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node2        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node4        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node5        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

           
ansible-playbook 单play多任务执行
vim ~/ansible/test2.yml  #写个剧本
=============================
---
- hosts: test,webserver
  tasks:
    - name: 任务一 测试是否能够执行
      ping:                         #ping模块不需要参数
    - name:  任务二 创建shell.txt文件
      shell:                   #执行shell模块来创建文件
        touch ~/shell.txt
=============================

ansible-playbook test2.yml   #执行
PLAY [test,webserver] ***************#剧本执行主机为test,webserver

TASK [Gathering Facts] *******************
ok: [node3]
ok: [node4]
ok: [node1]

TASK [任务一 测试是否能够执行] **************#执行ping模块
ok: [node3]
ok: [node4]
ok: [node1]

TASK [任务二 创建shell.txt] ************#执行shell模块 创建文件  有警告的
 [WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.

changed: [node3]
changed: [node4]
changed: [node1]

PLAY RECAP ************#本次剧本状态汇总
node1        : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3        : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node4        : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

           
ansible-playbook 多play执行多任务
vim ~/ansible/test3.yml  #用户创建 修改  删除
==============================
---
#第一个Play剧本  创建用户
- hosts: webserver
  tasks:
    - name: 创建用户
      user:          #调用user模块
        name: johnd    #user模块参数
        uid: 1040
        password: "{{'123456' | password_hash('sha512')}}"
 #第二个play剧本  修改用户的解释器
 - hosts: webserver
   tasks:
     - name: 修改用户的解释器
       user:     #调用user模块
         name: johnd
         shell: /sbin/nologin
 #第三个play剧本  删除用户
 - hosts: webserver
   tasks:
     - name: 删除用户
       user:
         state: absent
         name: johnd
===============================
ansible-playbook ~/ansible/test3.yml   #启动
#成功了  4个PLAY 6个TASK
#最后一个PLAY RECAP输出结果状态
#多的三个TASK是默认的 Gathering Facts
           
剧本格式总结

格式

====================================  #主要看对齐
---
- hosts: 主机名                                        # p
  ...   #有很多参数任意选择                             # l                    
  tasks:     #任务                                     # a
    - name:  #任务描述信息                             # y        #任
      模块名:                                          # 块       #务
        模块变量:  模块变量值                           # 一        #一
    - name:    #任务描述信息   第二个任务的描述          #                #任
      模块名:                                          #                #务
        模块变量: 模块变量值                            #                #二

- hosts: 主机名                                      #play  
  ...                                               #块二
=======================================
#主要看- 确定块的范围
           

setup 和 debug模块

说明

  • setup
    • Gathering Facts 在每个剧本执行的时候都会默认执行 获取被控制端的一些信息保存到变量中
    • 变量保存格式是JSON格式
    • filter 参数 模糊匹配信息 过滤出需要的信息 实际是检索JSON格式的键而且只支持通配符* 不能正则好像
  • debug
    • 每个任务都可以执行 输出相应变量来达到调试的作用
    • 变量用{{}}来表示
    • msg参数输出

测试

setup测试 filter过滤
ansible test -m setup -a "filter=*ipv4*"  #获取test主机信息 过滤出ipv4相关信息

node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [   #过滤出来一个ipv4
            "192.168.4.11"
        ],
        "ansible_default_ipv4": {           #过滤出来另一个ipv4    过滤的键
            "address": "192.168.4.11",
            "alias": "ens33",
            "broadcast": "192.168.4.255",
            "gateway": "192.168.4.254",
            "interface": "ens33",
            "macaddress": "00:0c:29:72:29:ba",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "192.168.4.0",
            "type": "ether"
        },
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
           
debug测试 显示信息
vim ~/ansible/debug.yml
=========================
---
- hosts: test
  tasks:
    - debug:
      msg: "主机名是:{{ansible_hostname}}"
    - debug:
      msg: "总内存大小:{{ansible_memtotal_mb}}"
=========================
#执行
ansible-playbook debug.yml

PLAY [test] **************

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

TASK [debug] ***********          #任务一   输出了主机名
ok: [node1] => {
    "msg": "主机名是:test"
}

TASK [debug] ***********************#任务二   输出了内存大小
ok: [node1] => {
    "msg": "总内存大小:798"
}

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

#可能会有疑问  变量的值哪来的    上面仔细看看   会发现执行了一个Gathering Facts的任务 就是这个任务带来的  setup模块的功能 默认执行


#修改下debug.yml测试下上面的说法
vim ~/ansible/debug.yml
================================
---
- hosts: test
  gather_facts: false    #加这个  目的是取消获取变量的任务
================================
ansible-playbook debug.yml #执行


PLAY [test] ***************

TASK [debug] **********#直接执行我们的任务了
fatal: [node1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible_hostname' is undefined\n\nThe error appears to be in '/root/ansible/debug.yml': line 5, column 13, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n          - debug:\n            ^ here\n"}

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

#发现报错了  msg中提到 ansible_hostname 没有定义!!! 变相说明Gathering Facts是获取变量的
           

自定义变量的方法

已经知道了debug模块是通过输出变量来辅助检查每个任务执行情况的 那么除了上面Gathering Facts获取的变量 有没有自己定义或者其他变量呢? 有的

  • inventory变量

还记得主机清单文件吗? 上面Inventory补充还提到了几个变量呢 我们还能在这些文件中设置自定义变量

vim ~/ansible/inventory
====================================
[test]
node1      my_variable="我自己定义的变量"
[webserver:vars]
my_variable="我给webserver定义的变量"                    #两种自定义变量的方式
			#给test,webserver都定义了对应专属变量my_variable  但是值是不一样的
====================================

vim ~/ansible/variable_test.yml   #写个测试剧本 测试两个专属变量是不同的
==============================
---
- hosts: test,webserver
  tasks:
    - name: 输出
      debug:
        msg: "我要输出:{{my_variable}}"
================================
ansible-playbook variable_test.yml  #使用测试剧本

PLAY [test,webserver] **********

TASK [Gathering Facts] ****************
ok: [node1]
ok: [node3]
ok: [node4]

TASK [输出] ***************
ok: [node1] => {
    "msg": "我要输出:我自己定义的变量"             #node1属于test    输出了专属变量
}
ok: [node3] => {
    "msg": "我要输出:我给webserver定义的变量"    #node3,4属于webserver 输出了专属变量
}
ok: [node4] => {
    "msg": "我要输出:我给webserver定义的变量"
}

PLAY RECAP ****************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node4                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

#效果达到了  每个组专属的变量
           
  • host facts变量

往上翻debug测试显示信息就是host facts变量的使用

  • playbook变量

在.yml文件中定义

vim ~/ansible/variable_test.yml  #直接在inventory变量那个剧本里面改好了 码不动了
====================================
---
- hosts: test,webserver
  vars:
    my_variable="我是playbook变量"   #自定义  我还是叫my_variable  看看优先级
  tasks:
    - name: 输出
      debug:
        msg: "我要输出:{{my_variable}}"
====================================
ansible-playbook variable_test.yml   #改了测试

PLAY [test,webserver] *********

TASK [Gathering Facts] **********
ok: [node3]
ok: [node1]
ok: [node4]

TASK [输出] **************
ok: [node1] => {                        #发现都是我在playbook中自定义的
    "msg": "我要输出:我是playbook变量"  
}
ok: [node3] => {     #说明了一个问题  playbook中的自定义变量优先级是高于清单文件的变量的
    "msg": "我要输出:我是playbook变量"
}
ok: [node4] => {
    "msg": "我要输出:我是playbook变量"
}

PLAY RECAP ***************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node4                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

           
  • 单独定义一个变量文件

playbook通过var_files来指定变量文件

vim ~/ansible/file_var.yml
===========================
---
- hosts: test
  vars_files: ~/ansible/variables.yml   #自己定义的一个变量文件
  tasks:
    - name: files_variable
      user:                               #user模块调用变量赋值
        name: "{{iname}}"                  #赋值用户名
        password: "{{ipass | password_hash('sha512')}}"  #ipass密码变量
============================

vim ~/ansible/variables.yml   #上面var_files指定的
=========================
---
iname: cloud                 #定义用户名
ipass: '123456'               #定义密码
=========================

ansible-playbook file_var.yml  #测试

#node1查看    
id cloud   #查看用户是否创建了
uid=1002(cloud) gid=1002(cloud) groups=1002(cloud)   #创建成功了   文件中变量引用成功
           
  • 交互输入变量

playbook中的vars_prompt参数来交互读取变量

vim   ~/ansible/vars_prompt.yml
==================================
---
- hosts: test
  vars_prompt:
    - name: "your_name" #定义一个变量叫your_name
      prompt: "what is you name?"#提示信息  等待用户输入
      private: no    #不回显输入值
      default: "我是默认名字"   #默认值 为空时自动顶上
      						#类似shell的 read -p "提示信息" 变量名
===================================
           
  • 任务返回结果键值对当成变量

playbook中的register

vim ~/ansible/register.yml
============================
---
- hosts: test
  tasks:
    - name: 获取返回结果当成变量
      shell: "echo test > /mnt/test.txt"
      register: test_return  #将shell模块执行结果作为变量保存
=============================
           
总结

变量的使用,利于playbook的灵活使用,还能通过debug模块输出来辅助查看变量信息达到排错的功能

继续阅读