Ansible管理变量和机密
1.1Ansible变量简介
Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。
- 要创建的用户
- 要安装的软件包
- 要重新启动的服务
- 要删除的文件
- 要从互联网检索的存档
1. 2命名变量
变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
无效和有效的Ansible变量名称示例
无效的变量名称 | 有效的变量名称 |
---|---|
web server | web_server |
remote.file | remote_file |
1st file | file_1 file1 |
remoteserver$1 | remote_server_1 remote_server1 |
1.3定义变量
可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:
- 全局范围:从命令行或Ansible配置设置的变量
- Play范围:在play和相关结构中设置的变量
- 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
注意:如果多个级别上定义了相同名称的变量,优先采用级别最
在playbook中定义变量
编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。
Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:
[root@master playbook]# cat hosts.yml
--- //文件开头
- hosts: 192.168.8.132 //执行任务的主机ip
vars: //变量
IP: 1.1.1.1 //定义IP变量
NAME: node1 //定义NAME变量
tasks: //任务列表
- name: test //任务描述
lineinfile: //使用lineingile模块
path: /etc/hosts //指定路径
line: '{{ IP }} {{ NAME }}' //调用上面定义的变量,注意格式
state: present //状态为存在
在运行这条命令前检查受控机的配置文件
[root@master project]# ansible httpd -m shell -a 'cat /etc/hosts'
192.168.8.132 | CHANGED | rc=0 >>
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@master project]#
//发现在受控主机上插入了最下面一行内容
[root@master project]# ansible httpd -m shell -a 'cat /etc/hosts'
192.168.8.132 | CHANGED | rc=0 >>
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1.1.1.1 node1
[root@master project]#
在也可以在外部文件中定义playbook变量。此时不使用playbook中的vars块,可以改为使用vars_files指令,后面跟上相对于playbook位置的外部变量文件名称列表:
[root@master playbook]# cat hosts/hos.yml
IP: 2.2.2.2
NAME: node2
[root@master playbook]# cat hosts.yml
---
- hosts: 192.168.8.132
vars_files:
- hosts/hos.yml
tasks:
- name: test
lineinfile:
path: /etc/hosts
line: '{{ IP }} {{ NAME }}'
state: present
[root@master playbook]# tree /opt/project/playbook/ //变量文件必须与hosts.yml在同一路径下
/opt/project/playbook/
├── hosts
│ └── hos.yml
└── hosts.yml
1 directory, 2 files
[root@master playbook]#
可以发现下面新增加了一行
[root@master project]# ansible 192.168.8.132 -m shell -a 'cat /etc/hosts'
192.168.8.132 | CHANGED | rc=0 >>
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1.1.1.1 node1
2.2.2.2 node2
[root@master project]#
在playbook中使用变量
声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible会将变量替换为其值。
注意:当变量用作开始一个值的第一元素时,必须使用引号
vars:
user: test
tasks:
- name: Creates the user {{ user }}
user:
name: "{{ user }}"
1.4主机变量和组管理
直接应用于主机的清单变量分为两在类:
主机变量,应用于特定主机
组管理,应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。
方式一:比较旧,不建议采用
缺点:这种做法使的清单文件难以处理,在同一文件中混合提供主机和变量信息,语法也过时
//定义 server1.example.com 的 ansible_user 主机变量:
[webservers]
node1.example.com ansible_user=pyd
//定义 dbservers 主机组的 user 组变量:
[dbserver]
node1.example.com
node2.example.com
[dbservers:vars]
user=pyd
//定义嵌套组 user 变量:
[servers1]
node1.example.com
node2.example.com
[servers2]
node3.example.com
node4.example.com
[servers:children]
servers1
servers2
[servers:vars]
user=pyd
1.5从命令行覆盖变量
清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible或ansible-playbook命令来覆盖。在命令行上设置的变量称为额外变量。
当需要覆盖一次性运行的playbook的变量的已定义值时,额外变量非常有用。例如:
//编辑一个主机变量文件(此文件在host_vars目录里)
ansible_user: root
ansible_password:
ip: 1.1.1.1
name: node1
//再编写一个test.yml文件
**注意:此文件的优先级要大一级你所编写的配置文件,即test.yml和host_vars在同一目录**
---
- hosts: 192.168.8.132
tasks:
- name: test
lineinfile:
path: /etc/hosts
line: "{{ ip }} {{ name }}"
state: present
//执行结果
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1.1.1.1 node1
//在test.yml配置文件里添加一行IP,发现主机清单变量可被playbook中设置的变量覆盖
---
- hosts: 192.168.8.132
vars:
ip: 2.2.2.2
tasks:
- name: test
lineinfile:
path: /etc/hosts
line: "{{ ip }} {{ name }}"
state: present
//主机清单变量和playbook设置的变量又能被ansible-playbook在命令行中传递参数到ansible或ansible-playbook命令来覆盖。
[root@localhost project]# ansible-playbook -e "ip=3.3.3.3" test.yml
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1.1.1.1 node1
2.2.2.2 node1
3.3.3.3 node1
1.6使用数组作为变量
除了将同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,也可以使用数组。这种做法的一个好处在于,数组是可以浏览的。
假设下列代码片段:
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
示例:
//test.yml文件配置
---
- hosts: 192.168.200.136
gather_facts: no
tasks:
- name: test
lineinfile:
path: /etc/hosts
line: "{{ info.node4.ip }} {{ info.node4.domain }}"
state: present
//主机清单配置
ansible_user: root
ansible_password:
info:
node4:
ip: 4.4.4.4
domain: www.example.com
//执行结果
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1.1.1.1 node1
2.2.2.2 node1
3.3.3.3 node1
4.4.4.4 www.example.com
2. Ansible Vault的简介
Ansible可能需要访问密码或API密钥等敏感数据,以便能配置受管主机。通常,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。这显示存在安全风险。
Ansible提供的Ansible Vault可以加密和解密任何由Ansible使用的结构化数据文件。若要使用Ansible Vault,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件。Ansible Vault可以加密任何由Ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者Ansible角色中定义的变量。
要创建新的加密文件,可使用ansible-vault create filename命令。该命令将提示输入新的vault密码,然后利用默认编辑器vi打开文件。我们可以设置和导出EDITOR环境变量,通过设置和导出指定其他默认编辑器。例如,若要将默认编辑器设为nano,可设置为export EDITOR=nano。
2.1加密文件
[root@master project]# ansible-vault create pyd.yml
New Vault password: //密码1
Confirm New Vault password: //密码1
[root@master project]#
//在配置文件里写入自己设置的密码 //密码是1
[root@master project]# cat pyd.yml //用cat命令查看被加密的密码,发现被加密了
$ANSIBLE_VAULT;1.1;AES256
32373066663538333636353961393165383934333465666662356263326331616434306461623334
3939623965323064623338323239396635396436306364310a623031646261366230303939373033
62323232363664313763323037336637316536333832343565663739353565663233393666636332
6635346531653133390a393466323563663765343932356466366430663236623330653039333033
6236
[root@master project]#
#我们还可以用vault密码文件来存储vault密码,而不是通过标准输入途径输入vault密码。这样做需要使用文件权限和其他方式来严密保护该文件。
[root@master project]# vim .vault_password
[root@master project]# cat .vault_password
1 //被加密密码
[root@master project]# ansible-vault create --vault-password-file=.vault_password pydd.yml
//输入加密密码
[root@master project]#
2.2查看加密的文件
可以使用ansible-vault view filename命令查看Ansible Vault加密的文件,而不必打开它进行编辑。
[root@master project]# ansible-vault create --vault-password-file=.vault_password pydd.yml
[root@master project]# ansible-vault view pydd.yml
Vault password:
pengyudong
[root@master project]#
2.3编辑加密文件
要编辑现有的加密文件,Ansible Vault提供了ansible-vault edit filename命令。此命令将文件解密为一个临时文件,并允许编辑。保存时,它将复制其内容并删除临时文件。
//编辑时需要输入加密文件的加密密码。
[root@master project]# ansible-vault edit pyd.yml
Vault password:
[root@master project]#
2.4加密现有的文件
[root@master project]# ansible-vault encrypt --vault-password-file=.vault_password inventory
Encryption successful
[root@master project]#
2.5 解密现有的文件
现有的加密文件可以通过ansible-vault decrypt filename命令永久解密。在解密单个文件时,可使用–output选项以其他名称保存解密的文件。
[root@master project]# ansible-vault decrypt pyd.yml --output=secret1-pyd.yml
Vault password:
Decryption successful
[root@master project]#
2.6更改加密文件的密码
使用ansible-vault rekey filename命令更改加密文件的密码。此命令可一次性更新多个数据文件的密钥。它将提示提供原始密码和新密码。
[root@master project]# ansible-vault rekey pyd.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful
[root@master project]#
在使用vault密码文件时,可以使用–new-vault-password-file选项:
先将新密码写入一个文件中,然后在指定这个文件,并输入现有密码,自动更新为文件里面的新密码
[root@master project]# echo "123" > abc
[root@master project]# ansible-vault rekey --new-vault-password-file=abc pyd.yml
Vault password:
Rekey successful
[root@master project]#