Creating symlinks with ansible using variables

Viewed 2156

I'm doing a playbook to create symlinks of nodejs, npm and gulp because I need to use a specific version and to install it all I'm just unzipping folders to /opt/ where all this is going to stay.

The task with items I'm using for creating the links are:

- name: Create NPM symlink
  file:
    src: '{{ item.src_dir }}/{{ item.src_name }}'
    dest: '{{ item.dest_dir }}/{{ item.dest_name }}'
    owner: "{{ ansible_ssh_user }}"
    group: "{{ ansible_ssh_user }}"
    state: link
  with_items:
    - { src_dir: "{{ npm_real_dir }}", src_name: "{{ npm_real_name }}" }
    - { dest_dir: "{{ nodenpm_link_dir }}", dest_name: "{{ npm_link_name }}" }

all the variables used in the items "zone" are declared in the host file as such: npm_real_dir=/opt/nodejs/node-v6.11.2-linux-x64/lib/node_modules/npm/bin

npm_real_name=npm-cli.js

nodenpm_link_dir=/opt/nodejs/node-v6.11.2-linux-x64/bin

npm_link_name=npm

ansible_ssh_user=vagrant

And I'm getting the error:

FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'dest_dir'

Which I'm not understanding since all the variables used in the task are declared and correct. I made a similar task without items:

- name: Create symbolic link for npm
  file:
    src: '{{ npm_real_dir }}/{{ npm_real_name }}'
    path: '{{ nodenpm_link_dir }}/{{ npm_link_name }}'
    owner: "{{ ansible_ssh_user }}"
    group: "{{ ansible_ssh_user }}"
    state: link

And its working, however the structure is the same as before, just without the items.

At this point I just want to know if its a known bug, if there is any issue in using items to create links, or if I did a stupid mistake and gain knowledge about it

Thanks in advance

1 Answers

The issue is that you're passing two different objects to the with_items property. The first object has two properties (src_dir and src_name), while the second object has two different properties (dest_dir and dest_name).

It looks like you want to combine them into a single object like this:

- name: Create NPM symlink
  file:
    src: '{{ item.src_dir }}/{{ item.src_name }}'
    dest: '{{ item.dest_dir }}/{{ item.dest_name }}'
    owner: "{{ ansible_ssh_user }}"
    group: "{{ ansible_ssh_user }}"
    state: link
  with_items:
    - { src_dir: "{{ npm_real_dir }}", src_name: "{{ npm_real_name }}", dest_dir: "{{ nodenpm_link_dir }}", dest_name: "{{ npm_link_name }}" }

That should work better and get rid of the error, but in this case you don't really need the with_items, since it's only one item that you're dealing with. You can add more objects for other tools, e.g. gulp in the same manner, e.g. like this:

- name: Create symlinks
  file:
    src: '{{ item.src_dir }}/{{ item.src_name }}'
    dest: '{{ item.dest_dir }}/{{ item.dest_name }}'
    owner: "{{ ansible_ssh_user }}"
    group: "{{ ansible_ssh_user }}"
    state: link
  with_items:
    - { src_dir: "{{ npm_real_dir }}", src_name: "{{ npm_real_name }}", dest_dir: "{{ nodenpm_link_dir }}", dest_name: "{{ npm_link_name }}" }
    - { src_dir: "{{ gulp_real_dir }}", src_name: "{{ gulp_real_name }}", dest_dir: "{{ gulp_link_dir }}", dest_name: "{{ gulp_link_name }}" }
Related