管理变量、机密

管理变量、机密

1. 管理变量

1.1 Ansible变量简介

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

通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:

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

####. 1.1.1 命名变量
变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
无效和有效的Ansible变量名称示例

无效的变量名称有效的变量名称
web serverweb_server
remote.fileremote_file
1st filefile_1 file1
remoteserver$1remote_server_1 remote_server1
1.1.2 定义变量

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

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

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

1.2 playbook中的变量

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

#1.2.1 在playbook中定义变量

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

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

[root@node1 opt]# vim test.yml
 
---
  - hosts: 192.168.200.154
    vars:
      user: dd
      home: /home/dd

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

- hosts: 192.168.200.154
  vars_files:
    - vars/test.yml

而后,可以使用YAML格式在这一/这些文件中定义playbook变量:

user: dd
home: /home/dd
1.2.2 在playbook中使用变量

声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。

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

注意:当变量用作开始一个值的第一元素时,必须使用引号。这可以防止Ansible将变量引用视为YAML字典的开头。

1.3 主机变量和组变量

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

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

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

[servers]
192.168.200.154 ansible_user=dd

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

[servers]
192.168.200.153
192.168.200.154

[servers:vars]
user=dd

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

[servers1]
node1
node2

[servers2]
node3
node4

[servers:children]
servers1
servers2

[servers:vars]
user=dd

此做法存在一些缺点,它使得清单文件更难以处理,在同一文件中混合提供了主机和变量信息,而且采用的也是过时的语法。

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

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

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

为了定义用于servers组的组变量,需要创建名为group_vars/servers的YAML文件,然后该文件的内容将使用与playbook相同的语法将变量设置为值:

user: dd

类似的,为了定义用于特定主机的主机变量,需要在host_vars目录中创建名称与主机匹配的文件来存放主机变量。

下面的示例更加详细的说明了这一做法。例如在一个场景中,需要管理两个数据中心,并在~/project/inventory清单文件中定义数据中心主机:

[root@syb ~]# vim /opt/inventory
[datacenter1]
node1
node2

[datacenter2]
node3
node4

[datacenters:children]
datacenter1
datacenter2

如果需要为两个数据中心的所有服务器定义一个通用值,可以为datacenters主机组设置一个组变量:

[root@node1 opt]# mkdir /opt/group_vars/
[root@node1 opt]# vim /opt/group_vars/datacenters
[root@node1 opt]# cat /opt/group_vars/datacenters
package: apache

如果要为每个数据中心定义不同的值,可以为每个数据中心主机组设置组变量:

[root@syb ~]# vim ~/project/groupo_vars/datacenter1
package: apache
[root@syb ~]# vim ~/project/groupo_vars/datacenter2
package: apache2

如果要为每一数据中心的各个主机定义不同的值,则在单独的主机变量文件中定义变量:

[root@localhost ~]# mkdir ~/project/host_vars
[root@localhost ~]# vim ~/project/host_vars/node1
package: apache
[root@localhost ~]# vim ~/project/host_vars/node2
package: apache2
[root@localhost ~]# vim ~/project/host_vars/node3
package: mariadb-server
[root@localhost ~]# vim ~/project/host_vars/node4
package: mysql-server

以上示例项目project的目录结构如果包含上面所有示例文件,将如下所示:

root@lsyb ~]# tree ~/project
/root/project
├── ansible.cfg
├── group_vars
│   ├── datacenters
│   ├── datacenters1
│   └── datecenters2
├── host_vars
│   ├── node1
│   ├── node2
│   ├── node3
│   └── node4
├── inventory

1.4 从命令行覆盖变量

[root@syb ~]# cd /opt/
[root@syb opt]# ansible-playbook test.yml  -e "package=vim"

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

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

TASK [yum] ****************************************************************************************************
changed: [node1]

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

1.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

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

# 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项目的所有文件中一致地采用一种语法,不要混用。

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

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

[root@syb ~]# vim /opt/test.yml 
---
- 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@syb ~]# cd /opt/
[root@syb opt]# ansible-playbook test.yml  

PLAY [Installs a package and prints the result] ***************************************************************

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

TASK [Install the package] ************************************************************************************
ok: [node1]
ok: [node3]
ok: [node2]

TASK [debug] **************************************************************************************************
ok: [node1] => {
    "install_result": {
        "changed": false,
        "failed": false,
        "msg": "Nothing to do",
        "rc": 0,
        "results": []
    }
}
ok: [node2] => {
    "install_result": {
        "changed": false,
        "failed": false,
        "msg": "Nothing to do",
        "rc": 0,
        "results": []
    }
}
ok: [node3] => {
    "install_result": {
        "changed": false,
        "failed": false,
        "msg": "Nothing to do",
        "rc": 0,
        "results": []
    }
}

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

2. 管理机密

2.1 Ansible Vault

Ansible可能需要访问密码或API密钥等敏感数据,以便能配置受管主机。通常,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。这显示存在安全风险。

Ansible提供的Ansible Vault可以加密和解密任何由Ansible使用的结构化数据文件。若要使用Ansible Vault,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件。Ansible Vault可以加密任何由Ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者Ansible角色中定义的变量。

2.1.1 创建加密文件

要创建新的加密文件,可使用ansible-vault create filename命令。该命令将提示输入新的vault密码,然后利用默认编辑器vi打开文件。我们可以设置和导出EDITOR环境变量,通过设置和导出指定其他默认编辑器。例如,若要将默认编辑器设为nano,可设置为export EDITOR=nano。

[root@localhost ~]# ansible-vault create secret.yml
New Vault password: redhat
Confirm New Vault password: redhat

我们还可以用vault密码文件来存储vault密码,而不是通过标准输入途径输入vault密码。这样做需要使用文件权限和其他方式来严密保护该文件。

[root@ansible opt]# ansible-vault create --vault-password-file=vault-pass secret.yml
we are the best one!
2.1.2 查看加密的文件

可以使用ansible-vault view filename命令查看Ansible Vault加密的文件,而不必打开它进行编辑。

[root@syb opt]# ansible-vault view secret.yml
Vault password: 
we are the best one!

查看时需要输入加密文件的加密密码。

2.1.3 编辑现有的加密文件

要编辑现有的加密文件,Ansible Vault提供了ansible-vault edit filename命令。此命令将文件解密为一个临时文件,并允许编辑。保存时,它将复制其内容并删除临时文件。

[root@syb opt]# ansible-vault edit secret.yml 
Vault password: 
we are the best one!  
123             #此行为写入内容

[root@syb opt]# ansible-vault view secret.yml   
Vault password: 
we are the best one!
123

辑时需要输入加密文件的加密密码。

edit子命令始终重写文件,因此只应在进行更改时使用它。要查看文件的内容而不进行更改时,应使用view子命令。

2.1.4 加密现有的文件

要加密已存在的文件,请使用ansible-vault encrypt filename命令。此命令可取多个欲加密文件的名称作为参数。

[root@syb opt]# ansible-vault  encrypt inventory 
New Vault password: 
Confirm New Vault password: 
Encryption successful

使用–output=OUTPUT_FILE选项,可将加密文件保存为新的名称。只能通过–output选项使用一个输入文件。

2.1.5 解密现有的文件

现有的加密文件可以通过ansible-vault decrypt filename命令永久解密。在解密单个文件时,可使用–output选项以其他名称保存解密的文件。

[root@syb opt]# ansible-vault  decrypt inventory --output=secret-inventory
Vault password: 
Decryption successful
2.1.6 更改加密文件的密码

使用ansible-vault rekey filename命令更改加密文件的密码。此命令可一次性更新多个数据文件的密钥。它将提示提供原始密码和新密码。

[root@syb opt]# cat vault-pass  查看旧密码
123

[root@syb opt]# ansible-vault rekey secret.yml  
Vault password: 
New Vault password:   #新密码syb
Confirm New Vault password: 
Rekey successful

在使用vault密码文件时,请使用–new-vault-password-file选项:

[root@syb opt]# ansible-vault  rekey --new-vault-password-file=passwd-new secret.yml 
Vault password:  #旧密码syb
Rekey successful

[root@syb opt]# ansible-vault  view secret.yml 
Vault password: 
we are the best one!
123
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值