一、管理机密
1 创建加密的文件
- 要创建新的加密文件,可使用ansible-vault create filename命令。该命令将提示输入新的vault密码,然后利用默认编辑器vi打开文件。我们可以设置和导出EDITOR环境变量,通过设置和导出指定其他默认编辑器。例如,若要将默认编辑器设为nano,可设置为export EDITOR=nano。
[root@ansible lamp]# ansible-vault create secret.yml
New Vault password: 123456
Confirm New Vault password: 123456
- 我们还可以用vault密码文件来存储vault密码,而不是通过标准输入途径输入vault密码。这样做需要使用文件权限和其他方式来严密保护该文件。
[root@ansible lamp]# cat haha
123456
[root@ansible lamp]# ansible-vault create --vault-password-file=/root/lamp/haha test.yml
2 查看加密的文件
- 可以使用ansible-vault view filename命令查看ansible Vault加密的文件,而不必打开它进行编辑。
[root@ansible lamp]# ansible-vault view secret.yml
Vault password: 123456
aaaaaaaaaaaaaaaaaaaaaa
[root@ansible lamp]# ansible-vault view --vault-password-file=/root/lamp/haha test.yml
3 编辑现有的加密文件
- 要编辑现有的加密文件,ansible Vault提供了ansible-vault edit filename命令。此命令将文件解密为一个临时文件,并允许编辑。保存时,它将复制其内容并删除临时文件。
[root@ansible lamp]# ansible-vault edit secret.yml
Vault password:
[root@ansible lamp]# ansible-vault edit --vault-password-file=/root/lamp/haha test.yml
4 加密现有的文件
- 要加密已存在的文件,请使用ansible-vault encrypt filename命令。此命令可取多个欲加密文件的名称作为参数。
[root@ansible lamp]# ansible-vault encrypt lamp.yml
New Vault password: 密码
Confirm New Vault password: 确认密码
Encryption successful
- 使用–output=OUTPUT_FILE选项,可将加密文件保存为新的名称。只能通过–output选项使用一个输入文件。
[root@ansible lamp]# ansible-vault encrypt --output=jjyy.yml haha.yml
New Vault password:
Confirm New Vault passwor[root@ansible lamp]# ls
haha.yml jjyy.yml #这可以看出来这种加密,原文件还存在,且不会加密原文件
[root@ansible lamp]# cat haha.yml
adasd:
[root@ansible lamp]# ansible-vault view jjyy.yml
Vault password: 密码
adasd:
5 解密现有的文件
- 现有的加密文件可以通过ansible-vault decrypt filename命令永久解密。
[root@ansible lamp]# ansible-vault decrypt jjyy.yml
Vault password:
Decryption successful
[root@ansible lamp]# cat jjyy.yml
adasd:
6 更改加密文件的密码
- 使用ansible-vault rekey filename命令更改加密文件的密码。此命令可一次性更新多个数据文件的密钥。它将提示提供原始密码和新密码。
[root@ansible lamp]# ansible-vault rekey test.yml
Vault password: 原密码
New Vault password: 新密码
Confirm New Vault password: 确认新密码
Rekey successful
- 在使用vault密码文件时,请使用-vault-password-file选项:
[root@ansible lamp]# ansible-vault encrypt --vault-password-file=/root/lamp/haha jjyy.yml
Encryption successful
[root@ansible lamp]# ansible-vault rekey --vault-password-file=haha jjyy.yml
New Vault password: 新密码
Confirm New Vault password: 确认新密码
Rekey successful
7 运行加密的playbook
- 要运行可访问通过ansible Vault加密的文件的playbook,需要向ansible-playbook命令提供加密密码。如果不提供密码,playbook将返回错误:
[root@ansible lamp]# ansible-playbook lamp.yml
ERROR! Attempting to decrypt but no vault secrets found
- 要为playbook提供vault密码,可使用–vault-id选项。例如,要以交互方式提供vault密码,请使用下例中所示的–vault-id @prompt:
[root@ansible lamp]# ansible-playbook --vault-id one@prompt lamp.yml
Vault password (one): 密码
- 此外,也可使用–vault-password-file选项指定以纯文本存储加密密码的文件。密码应当在该文件中存储为一行字符串。由于该文件包含敏感的纯文本密码,因此务必要通过文件权限和其他安全措施对其加以保护。
[root@ansible lamp]# ansible-playbook --vault-password-file=/root/lamp/haha lamp.yml
- 从ansible2.4开始,可以通过ansible-playbook使用多个ansible Vault密码。要使用多个密码,需要将多个–vault-id或–vault-password-file选项传递给ansible-playbook命令。
ansible-playbook --vault-id one@prompt --vault-id two@prompt site.yml
注意:@prompt前面的vaultIDone和two可以是任何字符,甚至可以完全省略它们。不过,如果在使用ansible-vault命令加密文件时使用–vault-id id选项,则在运行ansible-playbook时,将最先尝试匹配ID的密码。如果不匹配,将会尝试用户提供的其他密码。没有ID的vaultID@prompt实际上是default@prompt的简写,这意味着提示输入vaultIDdefault的密码。
二、管理事实
1 描述ansible事实
事实:就是已经存在的,已经被定义好的
为受管主机收集的一些事实可能包括:
- 主机名称
- 内核版本
- 网络接口
- P地址
- 操作系统版本
- 各种环境变量
- CPU数量
- 提供的或可用的内存
- 可用磁盘空间
借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作
- 可以根据含有受管主机当前内核版本的事实运行条件任务,以此来重启服务器
- 可以根据通过事实报告的可用内存来自定义MySQL配置文件
- 可以根据事实的值设置配置文件中使用的IPv4地址
[root@ansible project]# cat playbook/uu.yml
---
- hosts: httpd
tasks:
- name: Prints various ansible facts
debug:
var: ansible_facts["all_ipv4_addresses"]
[root@ansible project]# ansible-playbook playbook/uu.yml
PLAY [httpd] *******************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************
ok: [192.168.47.159]
TASK [Prints various ansible facts] *******************************************************************************************************************************************************
ok: [192.168.47.159] => {
"ansible_facts[\"all_ipv4_addresses\"]": [
"192.168.47.159",
"192.168.122.1"
]
}
PLAY RECAP *********************************************************************************************************************************************************
192.168.47.159 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible project]# cat playbook/uu.yml
---
- hosts: httpd
tasks:
- name: Prints various ansible facts
debug:
var: ansible_facts["default_ipv4"]
[root@ansible project]# ansible-playbook playbook/uu.yml
PLAY [httpd] *******************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************
ok: [192.168.47.159]
TASK [Prints various ansible facts] *******************************************************************************************************************************************************
ok: [192.168.47.159] => {
"ansible_facts[\"default_ipv4\"]": {
"address": "192.168.47.159",
"alias": "ens160",
"broadcast": "192.168.129.255",
"gateway": "192.168.129.2",
"interface": "ens160",
"macaddress": "00:0c:29:9f:41:29",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.129.0",
"type": "ether"
}
}
[root@ansible project]# cat playbook/uu.yml
---
- hosts: httpd
tasks:
- name: Prints various ansible facts
debug:
var: ansible_facts["default_ipv4"]["address"]
[root@ansible project]# ansible-playbook playbook/uu.yml
PLAY [httpd] **************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************
ok: [192.168.47.159]
TASK [Prints various ansible facts] ****************************************************************************************************************************************
ok: [192.168.47.159] => {
"ansible_facts[\"default_ipv4\"][\"address\"]": "192.168.47.159"
}
PLAY RECAP *******************************************************************************************************************
192.168.47.159 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2 ansible事实的示例
事实 | 变量 |
---|---|
短主机名 | ansible_facts[‘hostname’] |
完全限定域名 | ansible_facts[‘fqdn’] |
IPv4地址 | ansible_facts[‘default_ipv4’][‘address’] |
所有网络接口的名称列表 | ansible_facts[‘interfaces’] |
/dev/vda1磁盘分区的大小 | ansible_facts[‘devices’][‘vda’][‘partitions’][‘vda1’][‘size’] |
DNS服务器列表 | ansible_facts[‘dns’][‘nameservers’] |
当前运行的内核版本 | ansible_facts[‘kernel’] |
如果变量的值为散列/字典类型,则可使用两种语法来获取其值。比如:
- ansible_facts[‘default_ipv4’][‘address’]也可以写成ansible_facts.default_ipv4.address
- ansible_facts[‘dns’][‘nameservers’]也可以写成ansible_facts.dns.nameservers
在playbook中使用事实时,ansible将事实的变量名动态替换为对应的值:
[root@ansible ~]# hostname
ansible.example.com
| |
主机名 完全限定域名
[root@ansible project]# cat playbook/uu.yml
---
- hosts: httpd
tasks:
- name: Prints various ansible facts
debug:
msg: >
The host named {{ ansible_facts["fqdn"] }} is
ip is {{ ansible_facts["default_ipv4"]["address"] }}
[root@ansible project]# ansible-playbook playbook/uu.yml
PLAY [httpd] **********************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************
ok: [192.168.47.159]
TASK [Prints various ansible facts] ****************************************************************************************************************************************
ok: [192.168.47.159] => {
"msg": "The host named ansible.example.com is ip is 192.168.47.159\n"
}
PLAY RECAP *************************************************************************************************************************
192.168.47.159 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
三、循环使用
通过利用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。
ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。
1 简单循环
简单循环对一组项目迭代任务。loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。
- 利用循环使用yum模块一次安装多个服务
- name: server
hosts: all
tasks:
- name: 安装相应包
yum:
name: "{{ item }}"
loop:
- httpd
- php*
- mariadb
- 可以通过一个变量提供loop所使用的列表。在以下示例中,变量 packer 含有需要处于运行状态的服务的列表。
- name: 安装lamp
hosts: all
vars:
packer:
- httpd
- mariadb
- php*
- name: 安装相应包
yum:
name: "{{ item }}"
loop: "{{ packer }}"
- loop列表不需要是简单值列表。在以下示例中,列表中的每个项实际上是散列或字典。示例中的每个散列或字典具有两个键,即name和groups,当前item循环变量中每个键的值可以分别通过item.name和item.groups变量来检索。
- name: user
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- name: tom
groups: wheel
- name: joe
groups: root