playbook的特殊用法及变量的使用

目录

  • playbook的特殊用法
    • 1、YAML注释
    • 2、YAML字符串
    • 3、YAML字典
    • 4、YAML列表
  • 变量的使用
    • 1、Ansible变量简介
    • 2、命名变量
    • 3、定义变量
    • 4、playbook中的变量
    • 5、主机变量和组变量
    • 6、从命令行覆盖变量
    • 7、使用数组作为变量
    • 8、使用已注册变量捕获命令输出

playbook的特殊用法

1、YAML注释

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

#This is a YAML comment
[defaults]   # This is also a YAML comment

# some basic default values...

2、YAML字符串

YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。字符串可以用双引号或单引号括起。

This is a string

'This is another string'

"This is yet another a string"

编写多行字符串有两种方式。可以使用管道符表示要保留字符串中的换行字符。

line: |
  LoadModule proxy_module modules/mod_proxy.so
  LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

要编写多行字符串,还可以使用大于号字符来表示换行字符转换成空格并且行内的引导空白将被删除。这种方法通常用于将很长的字符串在空格字符处断行,使它们跨占多行来提高可读性。

line: >
  LoadModule proxy_module modules/mod_proxy.so,
  LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
查看:
LoadModule proxy_module modules/mod_proxy.so,LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

3、YAML字典

简单的字典形式:

name:role
service:httpd
port:80

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

{name: role, service: httpd, port: 80}

大多数情况下应避免内联块格式,因为其可读性较低。不过,至少有一种情形中会较常使用它。当playbook中包含角色列表时,较常使用这种语法,从而更加容易区分play中包含的角色和传递给角色的变量。

4、YAML列表

最简单的列表如下:

hosts:

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

hosts: [servera, serverb, serverc]
我们应该避免使用此语法,因为它通常更难阅读。

变量的使用

1、Ansible变量简介

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

通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。

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

2、命名变量

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

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

3、定义变量

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

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

如果在多个xeklh定义了相同名称的变量,则采用优先级别最高的变量。窄范围优先于更广泛的范围:由清单定义的变量将被playbook定义的变量覆盖,后者将被命令行中定义的变量覆盖。

4、playbook中的变量

编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。

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

[root@ansible playbook]# cat user.yml 
---
- hosts: apache
  vars:
    name: yy
    uid: 2000
  tasks: 
    - name: create user
      user:
        name: "{{ name }}"
        uid: "{{ uid }}"
        state: present 
[root@apache ~]# id yy
uid=2000(yy) gid=1002(yy)=1002(yy)

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

[root@ansible playbook]# mkdir vars
[root@ansible playbook]# cat vars/yy.yml 
content: hello,my name is meinv!
[root@ansible playbook]# cat user.yml 
---
- hosts: apache
  vars_files:
    - vars/yy.yml
  tasks: 
    - name: 
      shell: "echo {{ content }} > /tmp/abc"

[root@apache tmp]# cat /tmp/abc 
hello,my name is meinv!

5、主机变量和组变量

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

  • 主机变量,应用于特定主机
    组管理,应用于一个主机组或一组主机组中的所有主机
  • 主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。

若要定义主机变量和组变量,一种方法是直接在清单文件中定义。这是较旧的做法,不建议采用,但你可能会在未来的工作当中遇到。
定义192.168.235.141的ansible_user主机变量:

[servers]
192.168.235.141 ansible_user=root ansible_password=1

定义servers主机组的user组变量:

192.168.235.141
192.168.235.142

[servers:vars]
user=root

定义servers组的user组变量,该组由两个主机组成,每个主机组有两个服务器:

[servers1]
node1.example.com
node2.example.com

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

[servers:children]
servers1
servers2

[servers:vars]
user=joe

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

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

建议的做法是使用host_vars和group_vars目录定义清单变量,而不直接在清单文件中定义它们。

6、从命令行覆盖变量

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

当需要覆盖一次性运行的playbook的变量的已定义值时,额外变量非常有用。例如:

[root@ansible playbook]# cat user.yml 
---
- name: task1
  hosts: apache
  tasks: 
    - name: 创建用户
      user:
        name: "{{user}}"
        state: present
        
[root@ansible playbook]# ansible-playbook -e "user=lhh" user.yml 
PLAY [task1] *********************************************************************************

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

TASK [创建用户] **********************************************************************************
changed: [192.168.235.141]

PLAY RECAP ***********************************************************************************
192.168.235.141            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@apache ~]# id lhh
uid=2001(lhh) gid=2001(lhh)=2001(lhh)
[root@apache ~]#

7、使用数组作为变量

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

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

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

# Returns 'Bob'
users.bjones.first_name

# Returns '/users/acook'
users.acook.home_dir

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

# Returns 'Bob'
users['bjones']['first-name']

# Returns '/users/acook'
users['acook']['home_dir']

如果键名与python方法或属性的名称(如discard、copy和add)相同,点表示法可能会造成问题。使用中括号表示法有助于避免冲突和错误。

但要声明的是,上面介绍的两种语法都有效,但为了方便故障排除,建议在任何给定Ansible项目的所有文件中一致地采用一种语法,不要混用。

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

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

以下playbook演示了如何为调试用途捕获命令输出:

---
name: Installs a package and prints the result
  hosts: all
  tasks:
    - name: Install the package
      yum:
        name: httpd
        state: installed
      register: install_result
                                                        
    - debug: var=install_result

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

[root@localhost ~]# ansible-playbook playbook.yml 
PLAY [Installs a package and prints the result] *************************************

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

TASK [Install the package] **********************************************************
ok: [172.16.103.129]

TASK [debug] ************************************************************************
ok: [172.16.103.129] => {
    "install_result": {
        "changed": false,
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "httpd-2.4.6-93.el7.centos.x86_64 providing httpd is already installed"
        ]
    }
}

PLAY RECAP **************************************************************************
t129                       : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ig

你可能感兴趣的:(Linux自动化)