Ansible lookup仅在localhost执行,terraform场景求远程文件读取替代方案
问题核心原因
所有Ansible lookup插件默认都在**控制节点(即运行Terraform、执行Ansible命令的本地主机)**执行,完全不会访问远程目标实例的文件系统,因此无论用file还是fileglob类lookup,都无法读取远程主机上克隆仓库的文件内容,自然会报本地路径不存在的错误。
你之前改用find模块枚举远程.pub文件路径的思路完全正确——find是在远程节点执行的模块,能够正确拿到远程的文件路径,只需要替换读取远程文件内容的逻辑即可。
推荐实现方案(原生模块、幂等性最佳)
使用Ansible原生提供的slurp模块读取远程文件内容,这是专门用于拉取远程节点文件内容的官方模块,不会在控制机执行路径查找。
具体修改后的playbook逻辑如下:
- 保留原有步骤:安装git、克隆代码仓库、枚举远程目录下的
.pub文件 - 新增批量读取远程公钥文件内容的步骤
- 遍历读取到的公钥内容,幂等追加到目标
authorized_keys文件
完整修改片段:
# 原有步骤保持不变 - name: Install git apt: name: git state: present update_cache: yes - name: Clone the git repository become_user: "{{ SSH_USER }}" git: repo: "{{ REPO_URL }}" dest: "{{ SRC_DIR }}" - name: Find files with .pub extension become_user: "{{ SSH_USER }}" find: paths: "{{ SRC_DIR }}" patterns: '*.pub' register: pub_files # 新增步骤:循环读取远程所有.pub文件的内容 - name: Read content of all remote public key files become_user: "{{ SSH_USER }}" slurp: path: "{{ item.path }}" register: pub_file_contents loop: "{{ pub_files.files }}" # 替换原有带lookup的lineinfile步骤 - name: Append public keys to authorized_keys with idempotency become_user: "{{ SSH_USER }}" lineinfile: path: "{{ DEST_FILE }}" line: "{{ item.content | b64decode | trim }}" insertafter: EOF create: "yes" state: present loop: "{{ pub_file_contents.results }}" # 原有后续打印步骤保持不变,补充只读标记避免误报变更 - name: Display destinationFile contents become_user: "{{ SSH_USER }}" command: cat "{{ DEST_FILE }}" register: command_output changed_when: false - name: Print to console become_user: "{{ SSH_USER }}" debug: msg: "{{ command_output.stdout }}"
方案说明:
slurp模块会在远程节点读取文件内容,将结果以base64编码格式返回,通过b64decode过滤器即可拿到明文内容,加trim是为了去掉文件末尾的换行符,避免生成空行lineinfile的原生幂等逻辑会自动判断公钥是否已经存在于目标文件中,不会重复追加,重复执行playbook不会产生多余内容- 全程没有使用任何lookup插件,所有文件枚举、读取操作都在远程节点执行,不会触发控制机路径查找的逻辑
可选简易方案(适合快速临时场景)
如果不需要严格的模块级幂等,也可以直接在远程节点用组合命令完成公钥追加,逻辑更短:
- name: Append all .pub keys to authorized_keys directly on remote become_user: "{{ SSH_USER }}" shell: | shopt -s nullglob for pubfile in {{ SRC_DIR }}/*.pub; do grep -qxF "$(cat $pubfile)" {{ DEST_FILE }} || cat $pubfile >> {{ DEST_FILE }} done touch {{ DEST_FILE }}
注意:这个方案依赖远程shell逻辑,幂等性不如原生Ansible模块适合长期生产用,仅适合临时快速部署场景。
内容的提问来源于stack exchange,提问作者AnjK
相关产品推荐
相关产品推荐

