When working with Ansible's file
module to create symbolic links using a list of variables, you might encounter the frustrating error:
fatal: [vmdev] => One or more undefined variables: 'item' is undefined
The error occurs because the with_items
directive isn't properly formatted in modern Ansible versions (2.4+). The correct approach uses loop
instead:
tasks:
- name: Create drush alias symlinks
file:
src: /drupal/drush/{{ item.path }}.aliases.drushrc.php
dest: /home/vagrant/.drush/{{ item.dest }}.aliases.drushrc.php
state: link
loop:
- { path: 'new', dest: 'new' }
- { path: 'vmdev', dest: 'vmdev' }
Here's a full playbook example that demonstrates the correct implementation:
- hosts: all
become: yes
tasks:
- name: Ensure .drush directory exists
file:
path: /home/vagrant/.drush
state: directory
mode: '0755'
owner: vagrant
group: vagrant
- name: Create multiple symlinks for drush aliases
file:
src: "/drupal/drush/{{ item.path }}.aliases.drushrc.php"
dest: "/home/vagrant/.drush/{{ item.dest }}.aliases.drushrc.php"
state: link
force: yes
loop:
- { path: 'new', dest: 'new' }
- { path: 'vmdev', dest: 'vmdev' }
- { path: 'production', dest: 'prod' }
The solution includes several best practices:
- Uses modern
loop
instead of deprecatedwith_items
- Adds directory creation as a prerequisite
- Includes
force: yes
to handle existing files - Sets proper permissions with
mode
,owner
, andgroup
For more complex scenarios where the list comes from a variable:
vars:
drush_aliases:
- { path: 'new', dest: 'new' }
- { path: 'vmdev', dest: 'vmdev' }
tasks:
- name: Create symlinks from variable list
file:
src: "/drupal/drush/{{ item.path }}.aliases.drushrc.php"
dest: "/home/vagrant/.drush/{{ item.dest }}.aliases.drushrc.php"
state: link
loop: "{{ drush_aliases }}"
If you still encounter issues:
- Verify file paths exist with
ls -la /drupal/drush/
- Check Ansible version with
ansible --version
- Run with
-vvv
flag for detailed debugging - Ensure proper permissions on target directories
When working with Ansible's file
module to create symbolic links using a list of variables, you might encounter the frustrating error:
fatal: [vmdev] => One or more undefined variables: 'item' is undefined
This typically occurs when trying to use the with_items
loop incorrectly with the file module.
The proper way to create multiple symlinks using variables in Ansible is:
- name: Create drush alias symlinks
file:
src: "/drupal/drush/{{ item.path }}.aliases.drushrc.php"
dest: "/home/vagrant/.drush/{{ item.dest }}.aliases.drushrc.php"
state: link
loop:
- { path: 'new', dest: 'new' }
- { path: 'vmdev', dest: 'vmdev' }
- Use
loop
instead of deprecatedwith_items
(Ansible 2.5+) - Proper YAML formatting with consistent indentation
- Quoted paths to handle potential spaces
For more complex scenarios where you need additional parameters:
- name: Create multiple symlinks with various parameters
file:
src: "{{ item.src_path }}"
dest: "{{ item.dest_path }}"
owner: "{{ item.owner | default('vagrant') }}"
group: "{{ item.group | default('vagrant') }}"
mode: "{{ item.mode | default('0644') }}"
state: link
loop:
- { src_path: '/drupal/drush/new.aliases.drushrc.php', dest_path: '/home/vagrant/.drush/new.aliases.drushrc.php' }
- { src_path: '/drupal/drush/vmdev.aliases.drushrc.php', dest_path: '/home/vagrant/.drush/vmdev.aliases.drushrc.php', owner: 'root' }
Sometimes you might need to:
- name: Ensure parent directory exists
file:
path: "/home/vagrant/.drush"
state: directory
mode: '0755'
- name: Create symlinks only if source exists
file:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
state: link
loop: "{{ symlink_items }}"
when: item.src is file
If you're still having issues:
- Run with
-vvv
for verbose output - Check variable names are consistent in your loop
- Verify paths exist on the target system
- Consider using
ignore_errors: yes
temporarily to identify which item fails