AWX动态库存脚本如何从EXTRA_VARS获取instance_id?
如何在Ansible动态库存脚本中获取EXTRA_VARS传入的instance_id?
我尝试通过EXTRA_VARS传入的instance_id生成Ansible库存数据,执行命令如下:
ansible-inventory -i inventory/my_inventory.py --list -e "instance_id=198"
需要访问URL https://api.myapp.com/id=<instance_id>(示例:https://api.myapp.com/id=198)获取主机列表,再构建JSON格式的库存数据。步骤如下:
- 1a. 从EXTRA_VARS中获取instance_id(此处值为198)
- 1b. 请求上述URL
- 1c. 获取主机列表
- 1d. 构建JSON格式库存数据
我卡在了步骤1a,不知道如何在动态库存脚本中获取这个instance_id,请问该怎么实现?或者有没有其他可行方法?
解决方法
方法1:直接解析命令行参数
Ansible会将-e传入的变量作为命令行参数传递给动态库存脚本,你可以直接遍历sys.argv提取目标变量:
#!/usr/bin/env python3 import sys import json import requests def get_instance_id(): for arg in sys.argv: if arg.startswith('instance_id='): return arg.split('=', 1)[1] return None def main(): instance_id = get_instance_id() if not instance_id: # 未传入instance_id时返回空库存,避免Ansible报错 print('{"_meta": {"hostvars": {}}}') sys.exit(1) # 请求API获取主机列表 api_url = f"https://api.myapp.com/id={instance_id}" response = requests.get(api_url) hosts = response.json() # 假设API返回主机列表的JSON数组 # 构建Ansible库存JSON inventory = { 'all': { 'hosts': hosts }, '_meta': { 'hostvars': {} } } print(json.dumps(inventory)) if __name__ == '__main__': main()
方法2:读取Ansible导出的环境变量
Ansible会将extra_vars转换为大写的环境变量,前缀为ANSIBLE_PARAMETER_,你可以通过os.environ直接获取:
#!/usr/bin/env python3 import os import json import requests def main(): instance_id = os.environ.get('ANSIBLE_PARAMETER_INSTANCE_ID') if not instance_id: print('{"_meta": {"hostvars": {}}}') sys.exit(1) api_url = f"https://api.myapp.com/id={instance_id}" hosts = requests.get(api_url).json() inventory = { 'all': {'hosts': hosts}, '_meta': {'hostvars': {}} } print(json.dumps(inventory)) if __name__ == '__main__': main()
方法3:使用Ansible模块工具解析参数
如果希望更规范地处理参数,可以使用ansible.module_utils.basic中的AnsibleModule,它会自动解析传入的变量:
#!/usr/bin/env python3 from ansible.module_utils.basic import AnsibleModule import requests def main(): module = AnsibleModule( argument_spec={ 'instance_id': {'required': True, 'type': 'str'} } ) instance_id = module.params['instance_id'] api_url = f"https://api.myapp.com/id={instance_id}" hosts = requests.get(api_url).json() inventory = { 'all': {'hosts': hosts}, '_meta': {'hostvars': {}} } module.exit_json(**inventory) if __name__ == '__main__': main()
注意事项
- 动态库存脚本必须添加可执行权限:
chmod +x inventory/my_inventory.py - 脚本开头必须包含shebang(如
#!/usr/bin/env python3),确保Ansible能正确识别执行环境 - 无论是否获取到
instance_id,脚本最终都要输出合法的JSON格式,否则Ansible会抛出错误
内容的提问来源于stack exchange,提问作者Mohamed Javeed
相关产品推荐
相关产品推荐

