如何通过Ansible利用EC2实例变量生成本地状态报告文件?
问题原因分析
你遇到的核心问题是变量作用域不匹配:path和bar是在针对远程EC2实例(hosts: all)的play里注册的变量,这些变量仅属于对应的远程主机;而后续针对localhost的play处于完全独立的执行上下文,无法直接读取远程主机的变量。另外你在localhost的play里直接定义vars引用bar和path,这些变量在localhost环境中根本不存在,自然会读取失败。
解决方案1:单play直接追加结果到本地文件(简单直接)
不需要跨play传递变量,在远程实例的任务中,通过delegate_to: localhost将结果直接追加到本地文件:
--- - hosts: all become: true tasks: - name: 检查/etc/foo目录是否存在 stat: path: /etc/foo register: path_status - name: 获取实例私有IP(用Ansible内置事实替代curl更可靠) set_fact: private_ip: "{{ ansible_default_ipv4.address }}" # 如果未开启事实收集,可保留原curl方式: # shell: curl http://169.254.169.254/latest/meta-data/local-ipv4 # register: private_ip - name: 将结果追加到本地报告文件 lineinfile: path: ./Report.txt line: "IP address: {{ private_ip if private_ip is defined else private_ip.stdout }} directory foo - {{ path_status.stat.exists }}" create: true # 文件不存在则自动创建 delegate_to: localhost become: false
解决方案2:先收集所有实例信息,再统一生成文件(更灵活)
先将所有实例的IP和目录状态收集为全局可访问的事实,再在localhost的play中遍历生成文件:
--- - hosts: all become: true gather_facts: true # 开启事实收集,用于获取IP tasks: - name: 检查/etc/foo目录是否存在 stat: path: /etc/foo register: path_status - name: 存储实例信息为全局事实 set_fact: instance_report: ip: "{{ ansible_default_ipv4.address }}" foo_exists: "{{ path_status.stat.exists }}" - hosts: localhost become: false tasks: - name: 生成汇总报告文件 copy: dest: ./Report.txt content: | {% for host in groups['all'] %} IP address: {{ hostvars[host]['instance_report']['ip'] }} directory foo - {{ hostvars[host]['instance_report']['foo_exists'] }} {% endfor %}
内容的提问来源于stack exchange,提问作者Metro
相关产品推荐
相关产品推荐

