我对Ansible相当新,我试图创建一个将文件复制到远程服务器的角色。每次我运行playbook时,本地文件都可以有不同的名称,但需要远程复制到同一名称,如下所示:
- name: copy file
copy:
src=*.txt
dest=/path/to/fixedname.txt
Ansible不允许使用通配符,所以当我用主要剧本中的任务编写一个简单的剧本时,我可以这样做:
- name: find the filename
connection: local
shell: "ls -1 files/*.txt"
register: myfile
- name: copy file
copy:
src="files/{{ item }}"
dest=/path/to/fixedname.txt
with_items:
- myfile.stdout_lines
然而,当我将任务移动到某个角色时,第一个动作不再起作用,因为相对路径是相对于角色的,而剧本在角色的根目录中执行&# 39;目录。我可以添加角色文件目录的路径,但是有更优雅的方式吗?
答案 0 :(得分:13)
看起来您需要访问在本地查找信息的任务,然后将该信息用作复制模块的输入。
获取本地信息有两种方法。
使用local_action:
。再次运行任务的简写为127.0.0.1,找到了更多信息here。 (这是你一直在使用的)
使用lookup
。这是一个专门用于在本地获取信息的插件系统。更多信息here。
在你的情况下,我会使用lookup
来寻找第二种方法。您可以将其设置为example:
vars:
local_file_name: "{{ lookup('pipe', 'ls -1 files/*.txt') }}"
tasks:
- name: copy file
copy: src="{{ local_file_name }}" dest=/path/to/fixedname.txt
或者,更直接地说:
tasks:
- name: copy file
copy: src="{{ lookup('pipe', 'ls -1 files/*.txt') }}" dest=/path/to/fixedname.txt
查找插件从任务的上下文(playbook vs role)运行。这意味着它的行为会有所不同,具体取决于它的使用位置。
在上面的设置中,任务直接从剧本中运行,因此工作目录将是:
/path/to/project
- 这是您的剧本所在的文件夹。
如果您将任务添加到角色,则工作目录将为:
/path/to/project/roles/role_name/tasks
此外,file
和pipe
插件在角色/文件文件夹中运行:
/path/to/project/roles/role_name/files
- 这表示您的命令为ls -1 *.txt
每次访问变量时都会调用该插件。这意味着你不能相信你在剧本中调试变量,然后在角色稍后使用时依赖变量来获得相同的值!
我确实想知道关于项目ansible文件夹中的文件的用例,但事先并不知道谁的名字。这样的文件来自哪里?是不是可以在文件的生成和在Ansible中使用它或在固定的本地路径作为变量之间添加一个层?只是好奇;)
答案 1 :(得分:8)
只是想提出一个额外的答案......我遇到了和你一样的问题,我在飞行中构建一个ansible软件包并将工件(rpms)复制到一个角色的文件夹中,我的rpms中有版本文件名。
当我运行ansible游戏时,我希望它安装所有的rpms,无论文件名如何。
我在ansible中使用with_fileglob
机制解决了这个问题:
- name: Copy RPMs
copy: src="{{ item }}" dest="{{ rpm_cache }}"
with_fileglob: "*.rpm"
register: rpm_files
- name: Install RPMs
yum: name={{ item }} state=present
with_items: "{{ rpm_files.results | map(attribute='dest') | list }}"
我发现它比查找机制更清晰。