假设我有一台主机,其中包括一台 Web 服务器,其中安装了相关的 Ansible 角色nginx
,执行了一些必要的配置/etc/nginx
,并在防火墙中打开了端口 80 和 443。
有时候,我希望该特定主机不再是 Web 服务器,因为出于某种原因,我将这项服务移到了其他地方。仅从[webservers]
清单中删除服务器会将垃圾留在服务器中。理想情况下,我想卸载nginx
、删除/etc/nginx
目录(和一些其他目录),并关闭防火墙中的端口 80 和 443。
在 Puppet 中我可以做到这一点。作为 Web 服务器的主机的配置如下:
class { 'nginx':
ensure => present,
}
我所要做的就是将“present”替换为“absent”。如果类nginx
写得好,它将撤消所做的更改。(通常,管理员会将“present”替换为“absent”,然后,当他确定所有受影响的主机都已撤消配置时,他会从清单中删除该项目。)
而且,我认为 Puppet 防火墙模块会自动删除清单中不再能找到的防火墙规则;所以我认为,对于防火墙,你甚至不需要做上面那个“缺席”的事情,防火墙无论如何都会自动关闭。
我如何使用 Ansible 实现这些目标?
答案1
使用 Ansible,您执行此操作的方式与使用 Puppet 执行的操作并没有什么不同。
在您的示例中,您将设置
class { 'nginx':
ensure => absent,
}
你依赖于该 puppet 模块的作者编写了必要的代码来处理删除所有内容。并非每个 puppet 模块都有这个。
类似地,使用 Ansible,您可能拥有既具有安装所需步骤又具有删除所需步骤的角色。区别仅在于如何调用两者。
一种方法是让相关角色公开一个变量来切换行为。例如,该 nginx 角色可能采用一个变量nginx_state
,该变量取值installed
和absent
。
在角色中tasks/main.yml
,角色作者可能有类似的内容......
- include: install.yml
when: nginx_state|default('present') == "present"
- include: uninstall.yml
when: nginx_state|default('present') == "absent"
..相应的安装/卸载逻辑被拆分到这两个有条件包含的文件中。
Ansible 角色也可以嵌套。另一种方法是,角色作者可以例如提供一个角色,nginx
其中包含另一个角色,称为uninstalled
。然后您可以执行以下操作:
- name: Uninstall nginx
hosts: some_group
roles:
- nginx/uninstalled
与 Puppet 相比,Ansible 在如何完成任务方面的规则和指导方针可以说更少,因此实际操作会有所不同,但适用的概念是相同的。
答案2
由于您已经在 Ansible 中进行了配置/配置,因此您可以简单地删除整个服务器,重新安装/配置一个新的服务器,并获得一个干净的已知状态来运行它。
如果您确实想为了其他目的而“重新配置”它,那么您需要创建一个执行必要清理任务的新剧本。
据我所知,所有 Ansible包装模块支持state=absent
确保给定的包未安装在您的服务器上。此外,apt
模块具有purge=yes
将清除任何剩余的自定义配置文件的参数。
您还可以创建任务来确认端口 80 是否已设置防火墙。但是,由于您不会在该端口上运行任何进程,因此设置防火墙不会对服务器的安全性产生任何影响。