playbook特殊用法、变量(variables)的使用

playbook特殊用法、变量的使用

    • 1.Playbook语法变化
    • 2.变量的使用
      • 2.1 Ansible变量简介
        • 2.1.1 命名变量
        • 2.1.2 定义变量
      • 2.2 playbook中的变量
        • 2.2.1 在Playbook中定义变量
        • 2.2.2 在Playbook中使用变量
      • 2.3 主机变量和组变量
        • 2.3.1 在清单文件中定义变量
        • 2.3.2 使用目录填充主机和组变量
      • 2.4 从命令行覆盖变量
      • 2.5 使用数组作为变量
      • 2.6 使用已注册变量捕获命令输出

1.Playbook语法变化

YAML注释
注释也可以用于提高可读性。在YAML中,编号或井号字符(#)右侧的所有内容都是注释(推荐使用这一种注释方式)。如果注释的左侧有内容,请在该编号符号的前面加一个空格。

# This is a YAML comment

YAML字符串
内容中有空格或特殊字符(*)建议使用引号。双引号或单引号都行。

编写多行字符串有两种方式。

  • 管道符 (|) 追加的方式写入内容,结尾处留有一行空行
[root@localhost playbook]# cat test.yml 
---
  - hosts: "*"
    gather_facts: no
    tasks:
      - name: sync hosts file
        lineinfile: 
          path: /tmp/abc
          line: |
            hello word
            dft
            dsdf
          create: yes
[root@localhost ansible]# ansible-playbook playbook/test.yml 

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

TASK [sync hosts file] **********************************************************************************
changed: [192.168.237.168]

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

[root@localhost ~]# cat /tmp/abc 
hello word
dft
dsdf

  • 大于号字符(>)字符后面的内容只是一行内容,在playbook中多行显示利于提高可读性。结尾处也会留有一行空行,也是用追加方式写入内容。
[root@localhost ansible]# cat playbook/test.yml
---
  - hosts: "*"
    gather_facts: no
    tasks:
      - name: sync hosts file
        lineinfile: 
          path: /tmp/abc
          line: >
            hello word
            dft
            dsdf
          state: present
          create: yes
[root@localhost ansible]# ansible-playbook playbook/test.yml 

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

TASK [sync hosts file] **********************************************************************************
changed: [192.168.237.168]

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

[root@localhost ~]# cat /tmp/abc 
hello word dft dsdf

YAML字典
下面是一个简单的字典形式:

name: svcrole
svcservice: httpd
svcport: 80

字典也可以使用以大括号括起的内联块格式编写,如下所示:

{name: svcrole, svcservice: httpd, svcport: 80}

当playbook中包含角色列表时,较常使用这种语法,从而更加容易区分play中包含的角色和传递给角色的变量。

YAML列表
最简单的列表如下:

hosts:
  - servera
  - serverb
  - serverc

列表也有以中括号括起的内联格式,如下所示:

hosts: [servera, serverb, serverc]

playbook简写
通过将模块的键值对放在与模块名称相同的行上来定义任务,即“键=值”

简写形式:

tasks:
  - name: shorthand form
    service: name=httpd enabled=true state=started

普通形式:

tasks:
  - name: normal form
    service:
      name: httpd
      enabled: true
      state: started

普通形式的行数较多,但更容易操作。

2.变量的使用

2.1 Ansible变量简介

Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。

变量可能包含值:

  • 要创建的用户
  • 要安装的软件包
  • 要重新启动的服务
  • 要删除的文件
  • 要从互联网检索的存档

变量的作用:

  • 存储数据
  • 引用数据

2.1.1 命名变量

变量的名称必须以字母开头,并且只能包含字母、数字和下划线。

示例:

无效的变量名称 有效的变量名称
web server web_server
remote.file remote_file
1st file file_1
file1
remoteserver$1 remote_server_1
remote_server1

2.1.2 定义变量

可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:

  • 全局范围:从命令行或Ansible配置设置的变量
  • Play范围:在play和相关结构中设置的变量
  • 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量

优先级:命令行中定义的变量>playbook定义的变量>清单定义的变量

2.2 playbook中的变量

变量在Ansible Playbook中发挥着重要作用,因为它们可以简化playbook中变量数据的管理。

2.2.1 在Playbook中定义变量

Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:

[root@localhost ansible]# cat playbook/test.yml 
---
  - hosts: "*"
    gather_facts: no
    vars: 				//定义变量
      name: tom
      uid: 2000
    tasks:
      - name: create user
        user: 
          name: "{
    { name }}"		// {
    {}}表示引用变量,如果直接跟在键的后面就用引号
          uid: "{
    { uid }}"
          state: present
[root@localhost ansible]# ansible-playbook playbook/test.yml 
[WARNING]: Found variable using reserved name: name

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

TASK [create user] **************************************************************************************
changed: [192.168.237.168]

PLAY RECAP **********************************************************************************************
192.168.237.168            : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@localhost ~]# id tom 
uid=2000(tom) gid=2000(tom) 组=2000(tom)

也可以在外部文件中定义playbook变量。此时不使用playbook中的vars块,可以改为使用vars_files指令,后面跟上相对于playbook位置的外部变量文件名称列表:

//playbook文件test.yml与变量文件runtime.yml所在目录同级
[root@localhost ansible]# cat playbook/test.yml 
---
  - hosts: "*"
    gather_facts: no
    vars_files: 
      - vars/runtime.yml
    tasks:
      - name: create user
        shell: "echo {
    { content }} > /tmp/abc"
[root@localhost ansible]# cat playbook/vars/runtime.yml 
content: hello world

[root@localhost ansible]# ansible-playbook playbook/test.yml 

[root@localhost ~]# cat /tmp/abc 
hello world

2.2.2 在Playbook中使用变量

若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。

vars:
  user: joe
  
tasks:
  # This line will read: Creates the user joe
  - name: Creates the user {
    { user }}
    user:
      # This line will create the user named joe
      name: "{
    { user }}"

2.3 主机变量和组变量

直接应用于主机的清单变量分为两类:

  • 主机变量,应用于特定主机
  • 组管理,应用于一个主机组或一组主机组中的所有主机

主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。

2.3.1 在清单文件中定义变量

定义主机变量和组变量第一种方法是,直接在清单文件中定义主机变量和组变量,这是较旧的做法,不建议采用。

  • 定义172.16.103.129的ansible_user主机变量:
[servers]
172.16.103.129 ansible_user=joe
  • 定义servers主机组的user组变量:
[servers]
172.16.103.129
172.16.103.130

[servers:vars]
user=joe
  • 定义servers组的user组变量,该组由两个主机组成,每个主机组有两个服务器:
[servers1]
node1.example.com
node2.example.com

[servers2]
node3.example.com
node4.example.com

[servers:children]
servers1
servers2

[servers:vars]
user=joe

2.3.2 使用目录填充主机和组变量

定义主机变量和组变量第二种方法是在与清单文件或目录相同的工作目录中,创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。这是定义此变量的首选。

  • 定义主机变量:
[root@localhost ansible]# tree 
.								//host_vars与清单文件inventory同级
├── ansible.cfg
├── hosts
├── host_vars
│   └── 192.168.237.168
├── inventory
├── playbook
│   ├── lamp
│   │   ├── httpd.conf
│   │   ├── httpd-vhosts.conf
│   │   ├── lamp.yml
│   │   └── www.conf
│   └── test.yml
└── roles

[root@localhost ansible]# cat host_vars/192.168.237.168 
server: httpd*
state: latest
[root@localhost ansible]# cat playbook/test.yml 
---
  - hosts: "192.168.237.168"
    gather_facts: no
    tasks:
      - name: install server 
        yum: 
          name: "{
    { server }}"
          state: "{
    { state }}"
[root@localhost ansible]# ansible-playbook playbook/test.yml 
[root@localhost ~]# rpm -qa | grep httpd
httpd-2.4.37-39.module_el8.4.0+778+c970deab.x86_64
httpd-tools-2.4.37-39.module_el8.4.0+778+c970deab.x86_64
httpd-filesystem-2.4.37-39.module_el8.4.0+778+c970deab.noarch
httpd-devel-2.4.37-39.module_el8.4.0+778+c970deab.x86_64
centos-logos-httpd-85.8-1.el8.noarch
httpd-manual-2.4.37-39.module_el8.4.0+778+c970deab.noarch
  • 定义主机组变量:
[root@localhost ansible]# cat group_vars/webserver	//group_vars与清单文件同级
ansible_user: root
ansible_passwd: runtime
[root@localhost ansible]# cat inventory 
[webserver]
192.168.237.168

2.4 从命令行覆盖变量

清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible或ansible-playbook命令来覆盖。在命令行上设置的变量称为额外变量

ansible-playbook main.yml -e "package=apache2"

2.5 使用数组作为变量

除了将同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,也可以使用数组。这种做法的一个好处在于,数组是可以浏览的。

例如,假设下列代码片段:

user1_first_name: Bob
user1_last_name: Jones
user1_home_dir: /users/bjones
user2_first_name: Anne
user2_last_name: Cook
user2_home_dir: /users/acook

这将可以改写成名为users的数组:

users:
  bjones:
    first_name: Bob
    last_name: jones
    home_dir: /users/bjones
  acook:
    first_name: Anne
    last_name: Cook
    home_dir: /users/acook

使用以下变量来访问用户数据:

users.bjones.first_name
users.acook.home_dir

由于变量被定义为Python字典,因此可以使用替代语法:

users['bjones']['first-name']
users['acook']['home_dir']

上面两种语法都有效,但为了方便故障排除,建以使用第二种以中括号括起来的。

2.6 使用已注册变量捕获命令输出

使用register语句捕获命令输出。输出保存在一个临时变量中,然后在playbook中可用于调试用途或者达成其他目的,例如基于命令输出的特定配置。

[root@localhost ansible]# cat playbook/test.yml 
---
  - hosts: "*"
    gather_facts: no
    tasks:
      - name: register variables
        command: "df -h" 
        register: result 

      - debug: var=result

运行该playbook时,debug模块用于将install_result注册变量的值转储到终端。

[root@localhost ansible]# ansible-playbook playbook/test.yml 

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

TASK [register variables] *******************************************************************************
changed: [192.168.237.168]

TASK [debug] ********************************************************************************************
ok: [192.168.237.168] => {
    "result": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": true,
        "cmd": [
            "df",
            "-h"
        ],
        "delta": "0:00:00.002516",
        "end": "2021-07-24 01:12:57.945083",
        "failed": false,
        "rc": 0,
        "start": "2021-07-24 01:12:57.942567",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "文件系统               容量  已用  可用 已用% 挂载点\ndevtmpfs               379M     0  379M    0% /dev\ntmpfs                  396M     0  396M    0% /dev/shm\ntmpfs                  396M   11M  386M    3% /run\ntmpfs                  396M     0  396M    0% /sys/fs/cgroup\n/dev/mapper/rhel-root   17G  1.7G   16G   10% /\n/dev/nvme0n1p1        1014M  179M  836M   18% /boot\ntmpfs                   80M     0   80M    0% /run/user/0",
        "stdout_lines": [
            "文件系统               容量  已用  可用 已用% 挂载点",
            "devtmpfs               379M     0  379M    0% /dev",
            "tmpfs                  396M     0  396M    0% /dev/shm",
            "tmpfs                  396M   11M  386M    3% /run",
            "tmpfs                  396M     0  396M    0% /sys/fs/cgroup",
            "/dev/mapper/rhel-root   17G  1.7G   16G   10% /",
            "/dev/nvme0n1p1        1014M  179M  836M   18% /boot",
            "tmpfs                   80M     0   80M    0% /run/user/0"
        ]
    }
}

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

也可以在debug模块后面指定想要打印至终端的数据

[root@localhost ansible]# cat playbook/test.yml
---
  - hosts: "*"
    gather_facts: no
    tasks:
      - name: register variables
        command: "df -h" 
        register: result 

      - debug: var=result['stdout_lines']

[root@localhost ansible]# ansible-playbook playbook/test.yml 

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

TASK [register variables] *******************************************************************************
changed: [192.168.237.168]

TASK [debug] ********************************************************************************************
ok: [192.168.237.168] => {
    "result['stdout_lines']": [
        "文件系统               容量  已用  可用 已用% 挂载点",
        "devtmpfs               379M     0  379M    0% /dev",
        "tmpfs                  396M     0  396M    0% /dev/shm",
        "tmpfs                  396M   11M  386M    3% /run",
        "tmpfs                  396M     0  396M    0% /sys/fs/cgroup",
        "/dev/mapper/rhel-root   17G  1.7G   16G   10% /",
        "/dev/nvme0n1p1        1014M  179M  836M   18% /boot",
        "tmpfs                   80M     0   80M    0% /run/user/0"
    ]
}

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

你可能感兴趣的:(linux)