with_items and register in a role/main.yml

245 views
Skip to first unread message

stewar...@gmail.com

unread,
Dec 1, 2016, 11:16:06 AM12/1/16
to Ansible Project
Hi,

I've created a small demo below which demonstrates my problem. 
I can't seem to invoke the with_items and call {{item}} later on. What am I doing wrong? I've tried searching obviously but I can't find the direct answer, sorry for the newbie question.

My playbook invokes a role, and below is my role:
  - name: Mytest to register a variable
    find: paths="/tmp/demo/" patterns="*.txt"
    register: r

  - name: mytest to show my results
    debug: msg="{{item}}"
    with_items: r

The above doesn't give the desired result. When i change my task mytest into 
  - name: mytest
    debug: msg={{r.files.0.path}}
then i do get the first .txt file found, I can't seem to make it dynamically.


Ultimately I'm trying to create a loop true a directory, and based on the file extension I want to invoke a certain action. For example, if the file extension is .sh, then invoke shell. If it's .sql, then invoke sqlplus, and more extensions. If the extension is not listed then copy the file. Perhaps my whole approach is wrong in the first place, I'm trying to take it step by step of course, which might lead me in a wrong direction? 

Again, thanks so much.

fr...@tom.nl

unread,
Dec 1, 2016, 11:59:10 AM12/1/16
to Ansible Project
r is avariable after registering.
So i think you sgould use "{{ r }}"

Kai Stian Olstad

unread,
Dec 1, 2016, 2:22:03 PM12/1/16
to ansible...@googlegroups.com
On 30. nov. 2016 03:29, stewar...@gmail.com wrote:
> I've created a small demo below which demonstrates my problem.
> I can't seem to invoke the with_items and call {{item}} later on. What am I
> doing wrong? I've tried searching obviously but I can't find the direct
> answer, sorry for the newbie question.
>
> My playbook invokes a role, and below is my role:
> - name: Mytest to register a variable
> find: paths="/tmp/demo/" patterns="*.txt"
> register: r
>
> - name: mytest to show my results
> debug: msg="{{item}}"
> with_items: r
>
> The above doesn't give the desired result. When i change my task mytest
> into
> - name: mytest
> debug: msg={{r.files.0.path}}
> then i do get the first .txt file found, I can't seem to make it
> dynamically.

- name: mytest to show my results
debug: msg="{{ item.path }}"
with_items: r.files


> Ultimately I'm trying to create a loop true a directory, and based on the
> file extension I want to invoke a certain action. For example, if the file
> extension is .sh, then invoke shell. If it's .sql, then invoke sqlplus, and
> more extensions. If the extension is not listed then copy the file. Perhaps
> my whole approach is wrong in the first place, I'm trying to take it step
> by step of course, which might lead me in a wrong direction?

It sounds like a wrong approach, but that doesn't mean that is wrong.
But there may be better ways reach your objective.

You could try explaining what you are trying to achieve and maybe
someone on the list could help you toward a more correct direction.

--
Kai Stian Olstad

stewar...@gmail.com

unread,
Dec 7, 2016, 9:31:02 AM12/7/16
to Ansible Project
Hi,

Thanks for your reply, what I'm trying to do is a simple copy and paste (deploy a release).
Specifically, I want to list thru the directory and copy all files that are not in the ./ins directory.

problem one: I couldn't figure that out with the copy command, so i used "command: "find ./demo_deploy -type f ! -path './demo_deploy/ins/*' "
problem two: i cant seem to figure out how to execute the above in a with_items, so i thought to place the result in an register. As followed:

  - name: Register - Copy files
    command: "find ./demo_deploy -type f ! -path './demo_deploy/ins/*' ! -path './demo_deploy/roles/*' ! -path './demo_deploy/host_vars/*'"
    register: copy_files

  - name: Copy files
    command: cp {{ item }} /tmp/bb/
    with_items:
      - "{{copy_files.stdout_lines}}"
    tags:
      - copy_release

This works fine.. however, if I place them in a role, then my register isnt loaded when i run my plabook with --copy_release tag.


I guess I'm getting lost here, where the original challenge is simple: copy all files except 1 directory.

Any help is appreciated!

Stankovic, Marko

unread,
Dec 7, 2016, 11:02:28 AM12/7/16
to ansible...@googlegroups.com
Hi Stewart,


First: including only "copy_release" tag makes ansible skip the first task, as it's tagged only with "copy_files".


Second: you can also use with_filetree<https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/lookup/filetree.py> lookup (introduced in Ansible 2.2) or with_fileglob<http://docs.ansible.com/ansible/playbooks_loops.html#id4> (if you don't need to iterate a directory recursively).
Then use separate tasks for different actions/extensions with 'when' directive.
This way you'll skip the register task.
Note that these lookups return different data structures for {{ item }}.
fileglob's item is a string containing the file/directory absolute path, while filetree's item is a dict.
Some "documentation" can be found in original pull request<https://github.com/ansible/ansible/pull/14332>'s description.

When executed as "with_filetree: /tmp", it looks like this for a file (or a link with "state":"link"):
"item": {
"ctime": 1479723235.151,
"gid": 501,
"group": "xxx",
"mode": "0664",
"mtime": 1479723235.151,
"owner": "xxx",
"path": "ansible-debug.log",
"root": "/tmp",
"selevel": "s0",
"serole": "object_r",
"setype": "user_tmp_t",
"seuser": "unconfined_u",
"size": 4104,
"src": "/tmp/ansible-debug.log",
"state": "file",
"uid": 501
}
And like this for a directory (there's no "src"):
"item": {
"ctime": 1479810261.0929983,
"gid": 501,
"group": "xxx",
"mode": "0775",
"mtime": 1479810261.0929983,
"owner": "xxx",
"path": "test",
"root": "/tmp",
"selevel": "s0",
"serole": "object_r",
"setype": "user_tmp_t",
"seuser": "unconfined_u",
"size": 4096,
"state": "directory",
"uid": 501
}


This example copies files only:

- name: Copy files
command: cp {{ item.src }} /tmp/bb/{{ item.path }}
with_filetree: ./demo_deploy
when: item.state == 'file' and item.path.split('/')[0] not in ['ins', 'roles', 'host_vars']
tags:
- copy_release
if you need to preserve the same directory structure, then add this before the task above:
- name: Create directories
file:
dest: /tmp/bb/{{ item.path }}
state: directory
with_filetree: ./demo_deploy
when: item.state == 'directory' and item.path.split('/')[0] not in ['ins', 'roles', 'host_vars']
tags:
- copy_release

Cheers,
Marko


______________________________________________________________________________________________________

CONFIDENTIALITY NOTICE: This message is the property of International Game Technology PLC and/or
its subsidiaries and may contain proprietary, confidential or trade secret information.
This message is intended solely for the use of the addressee. If you are not the intended recipient
and have received this message in error, please delete this message from your system. Any unauthorized
reading, distribution, copying, or other use of this message or its attachments is strictly prohibited.

Reply all
Reply to author
Forward
0 new messages