Ansible中的变量及加密
变量命名
只能包含数字,下划线,字母
只能用下划线或字母开头
变量级别
全局: 从命令行或者配置文件中设定的
剧本(Play): 从Play和相关结构中设定的
主机: 由清单/事实收集或者注册的任务
##变量优先级设定
狭窄范围优先于广域范围
变量设定和使用方式
在PlayBook中直接定义变量
---
- name: Test Var
hosts: all
vars:
USERS: Test
在文件中定义变量
vim userlist.yml
---
user:Test
vim Test.yml
---
- name: Create User
hosts: all
vars_files: ./user_list.yml
tasks:
- name: Create User
user:
name: "{{NAME}}"
state: persent
...
设定主机变量和清单变量
在定义主机变量和清单变量时使用
vim inventory
[Test]
172.25.254.137
172.25.254.237
[Test:vars]
USER=Test
目录定义变量
##目录定义变量的方式分为两种
group_vars ##清单变量,目录中的文件名称与主机清单名称一致
host_vars ##主机变量,目录中的文件名称与主机名称一致
##讲解举例
cat ./group_vars/Test
---
USER: Test
该文件作用于Test清单,当操作对象为Test清单时,可以直接使用而不需要额外声明.
cat ./host_vars/172.25.254.100
---
USER: Test
该文件作用于172.25.254.100主机,当操作对象为主机名/IP,且确实为172.25.254.100时,可以直接使用而不需要额外声明.
用命令覆盖变量
在执行命令时单独赋予变量,只作用于此次命令,但相对的优先级最高.
ansible-playbook User.yml -e "USER=Test"
使用数组设定变量
#vim UserList.yml
---
USER:
Test:
age: 18
obj: linux
NeuWings:
age: 20
obj: java
#vim User.yml
- name: Create User
hosts: all
gather_facts: no
vars_files:
./UserList.yml
tasks:
- name: create user
shell:
echo "{{USER['Test']['age']}}"
echo "{{USER.NeuWings.obj}}"
从上面的例子不难看出,通过调用Userlist
文件中的内容,PlayBook获取了变量,而在这里的存储方式并不是简单的变量存储而是使用了数组.
调用时使用[ ]
和.
的方式都可以的.
注册变量
register会把模块输出注册到指定字符串中.
通过使用该功能,可以实现对于命令输出的变量储存以及传递.
##举例,抓取受控主机的主机名并保存.
---
- name: Test Register
hosts: Test
tasks:
- name: Hostname Command
shell:
hostname
register: Info
- name: Show Stdout
shell:
echo "{{Info['stdout']}}"
- name: Save File
lineinfile:
path: /mnt/Info
line: "{{Info['stdout']}}"
create: yes
- name: Fetch File to Server
fetch:
src: /mnt/Info
dest: /mnt/File
flat: yes
...
事实变量
事实变量是ansible
在受控主机中自动检测出的变量.
事实变量中还有与主机相关的信息.
当执行ansible
命令时,默认会执行setup
模块,同时生成事实变量相关信息.
通过附加gather_facts:no
可以关闭事实变量,但同样,也就无法使用相关功能了.
当需要使用主机相关信息时不需要进行采集赋值,直接调用即可.
因为变量信息为系统信息所以不能随意设定仅为采集信息,故被称为事实变量.
---
- name: Test Register
hosts: Test
tasks:
- debug:
var: ansible_facts['date_time']['date']
- debug:
var: ansible_facts['ens3']['ipv4']['address']
- lineinfile:
path: ./TestFile
line: "{{ansible_facts['fqdn']}}"
create: yes
...
魔法变量
可以理解为ansible
本身具有的环境变量.
hostvars ##ansible软件的内部信息
group_names: ##当前受控主机所在组
groups ##列出清单中所有的主机和组
inventory_hostname ##包含清单中配置的当前受管主机的名称
##部分实验验证
##通过魔法变量显示服务端内部的信息
[root@Node1 .ansible]# ansible localhost -m debug -a "var=hostvars"
localhost | SUCCESS => {
"hostvars": {
"172.25.254.137": {
"ansible_check_mode": false,
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/root/.ansible/hosts"
],
"ansible_playbook_python": "/usr/bin/python3.6",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.18",
"major": 2,
"minor": 9,
"revision": 18,
"string": "2.9.18"
},
"group_names": [
"Test"
],
"groups": {
"Test": [
"172.25.254.137"
],
"all": [
"172.25.254.137"
],
"ungrouped": []
},
"inventory_dir": "/root/.ansible",
"inventory_file": "/root/.ansible/hosts",
"inventory_hostname": "172.25.254.137",
"inventory_hostname_short": "172",
"omit": "__omit_place_holder__df535182d651260d851cf05a59953f51387dfa39",
"playbook_dir": "/root/.ansible"
}
}
}
##显示服务端所在组,理所当然不属于任何组
[root@Node1 .ansible]# ansible localhost -m debug -a "var=group_names"
localhost | SUCCESS => {
"group_names": []
}
##显示受控主机所在组,正确显示了结果
[root@Node1 .ansible]# ansible 172.25.254.137 -m debug -a "var=group_names"
172.25.254.137 | SUCCESS => {
"group_names": [
"Test"
]
}
##显示清单中所有的组和主机
[root@Node1 .ansible]# ansible localhost -m debug -a "var=groups"
localhost | SUCCESS => {
"groups": {
"Test": [
"172.25.254.137"
],
"all": [
"172.25.254.137"
],
"ungrouped": []
}
}
##显示包含清单中配置的受管主机的名称
[root@Node1 .ansible]# ansible localhost -m debug -a "var=inventory_hostname"
localhost | SUCCESS => {
"inventory_hostname": "localhost"
}
JINJA2模板相关内容
介绍
Jinja2时Python下一个被广泛应用的模板引擎.
他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能.
其中最显著的一个是增加了沙箱执行功能和可选的自动转义功能
J2模板的书写规则
{# /etc/hosts line #} ##注释说明文件用途
127.0.0.1 localhost ##文件内容
{{ ansible_facts['all_ipv4_addresses'] }} ##使用事实变量的方法
##循环的使用方法
vim Test.yml
users:
- Test1
- Test2
- Test3
vim Test.j2
{% for NAME in users %}
{{ NAME }}
{% endfor %}
##IF判断的使用方法
{{% for NAME in users if not NAME == "ansible" %}}
User number {{loop.index}} - {{NAME}}
{% endfor %}
loop.index ##循环迭代计数器,从1开始
loop.index0 ##循环迭代计数器,从0开始
{% for user in students %}
name: {{ user['name'] }}
{% if user['age'] is defined %}
age: {{ user['age'] }}
{% endif %}
{% if user['age'] is not defined %}
age: None
{% endif %}
J2模板在PlayBook中的使用
##设置一组变量users,格式化输出其内容,当age为空时使用x表示.
##Test.yml
---
- name: Test
hosts: Test
vars:
users:
- name: Test1
age: 17
- name: Test2
age: 18
- name: Wrong
tasks:
- name: Test J2
template:
src: ./Test.j2
dest: /mnt/hosts
...
##Test.j2
{% for NAME in users %}
name: {{NAME['name']}}
{% if NAME['age'] is defined %}
age: {{NAME['age']}}
{% endif %}
{% if NAME['age'] is not defined %}
age: x
{% endif %}
{% endfor %}
##修改所有受控主机的hosts文件,在其中添加所有受控主机的IP和hostname信息.
##Test.yml
---
- name: Insert Hosts
hosts: Test
tasks:
- name: Test
template:
src: ./Test.j2
dest: /etc/hosts
group: root
owner: root
mode: 0644
...
##Test.j2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups['all'] %}
{{hostvars[host]['ansible_facts']['ens3']['ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }}
{% endfor %}
Ansible的加密控制
上述生成的PlayBook都是明文的,但业务中我们有时希望PlayBook可以加密而不被其他人看到,这时可以使用Ansible的加密控制.
##创建新文件时进行加密(交互式)
ansible-vault create Test.yml
##创建新文件时进行加密(非交互式)
ansible-vault create Test.yml --vault-password-file=TestFile
##加密现有文件
ansible-vault encrypt Test.yml
ansible-vault encrypt Test.yml --vault-password-file=TestFile
##查看加密文件
ansible-vault view Test.yml
ansible-vault view Test.yml --vault-password-file=TestFile
##编辑加密文件
ansible-vault edit Test.yml
ansible-vault view Test.yml --vault-password-file=TestFile
##解密已经被加密的文件
ansible-vault decrypt Test.yml ##永久解密
ansible-vault decrypt Test.yml --vault-password-file=TestFile ##非交互的永久解密
ansible-vault decrypt Test.yml --vault-password-file=TestFile --output=Test2.yml ##并将解密内容保存到新文件
##更改密码
ansible-vault rekey Test.yml
ansible-vault rekey Test.yml --new-vault-password-file=key1
##执行加密过的PlayBook
ansible-playbook Test.yml --ask-vault-pass