如何在Ansible中实现密码管理器选择的可配置化
解决方案
方案1:纯配置动态参数方案(无需开发新插件)
利用Jinja2的字典解包特性,预定义各密钥管理器的配置映射,完全解决参数不兼容问题,同时保持playbook简洁。
步骤1:定义统一配置映射
在playbook的vars或group_vars中添加如下配置:
vars: # 用户仅需修改该值切换密钥管理器 secret_manager: bitwarden # 各密钥管理器配置集合,新增管理器仅需在此添加条目 secret_manager_configs: bitwarden: lookup_name: bitwarden default_params: custom_field: false required_role: ansible-modules-bitwarden 1password: lookup_name: community.general.onepassword default_params: {} required_role: "" lastpass: lookup_name: community.general.lastpass default_params: {} required_role: "" aws_secrets: lookup_name: amazon.aws.secretsmanager_secret default_params: {} required_role: ""
步骤2:动态加载依赖角色
roles: - role: "{{ secret_manager_configs[secret_manager].required_role }}" when: secret_manager_configs[secret_manager].required_role | length > 0
步骤3:统一调用密钥
调用时动态解包对应管理器的默认参数,需要自定义参数时直接合并即可:
# 查询标准字段 - name: 获取Pi-hole管理员用户名 debug: msg: "{{ lookup( secret_manager_configs[secret_manager].lookup_name, 'pi-hole', field='username', **secret_manager_configs[secret_manager].default_params ) }}" # 查询自定义字段,可覆盖默认参数 - name: 获取Pi-hole自定义API密钥 debug: msg: "{{ lookup( secret_manager_configs[secret_manager].lookup_name, 'pi-hole', field='api_key', **(secret_manager_configs[secret_manager].default_params | combine({'custom_field': true})) ) }}"
方案2:自定义通用lookup插件(调用更简洁)
如果想要完全实现你理想中的调用形式,可以写一个极简的自定义lookup插件,不需要修改现有任何插件逻辑。
步骤1:创建自定义lookup
在playbook目录下新建lookup_plugins/get_secret.py,内容如下:
from ansible.plugins.lookup import LookupBase from ansible.errors import AnsibleError class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): secret_manager = variables.get("secret_manager", "1password") sm_config = variables.get("secret_manager_configs", {}).get(secret_manager) if not sm_config: raise AnsibleError(f"不支持的密钥管理器类型:{secret_manager}") # 合并默认参数和传入参数 params = sm_config.get("default_params", {}).copy() params.update(kwargs) # 调用对应原生lookup插件 lookup_plugin = self._loader.find_lookup_plugin(sm_config["lookup_name"]) return lookup_plugin.run(terms, variables=variables, **params)
步骤2:调用方式完全符合预期
# 查询标准字段 - name: 获取Pi-hole管理员用户名 debug: msg: "{{ lookup('get_secret', 'pi-hole', field='username') }}" # 查询自定义字段 - name: 获取Pi-hole自定义API密钥 debug: msg: "{{ lookup('get_secret', 'pi-hole', field='api_key', custom_field=true) }}"
两种方案都完全符合DRY原则,新增密钥管理器仅需在secret_manager_configs中添加对应配置即可,无需修改现有业务逻辑,扩展性极强。
内容的提问来源于stack exchange,提问作者Pierre D
相关产品推荐
相关产品推荐

