1

I am trying to create multiple files via templates using elements from a dictionary to populate those files.

My goal is to create configuration files for proftpd for each of my uploading groups. Each configuration file contains the various bits of configuration for those users.

Here is the dictionary I am using: (This dictionary structure also includes other elements that are not used by this playbook, but will be used by other playbooks. So I would like to keep this structure if possible to maintain the single source of truth.)

uploaders:
  - name: 'Uploaders from one location'
    initials: 'abc'
    ftps_limit_list: 'LIST PWD xpwd'
    variable_used_by_another_playbook: 'fubar'
  - name: 'Uploaders from a second location'
    initials: 'dfg'
  - name: 'Test Uploader'
    initials: 'TestUploader'
    ftps_upload_directory: '/path/to/TestUploader/uploads'

Here is the conf.d.j2 snippet that I am trying to use:

{% if ftps_upload_directory is defined %}
<Directory {{ ftps_upload_directory }}>
{% else %}
<Directory /path/to/{{ initials|upper }}/uploads>
{% endif %}

<snip>

<Limit LOGIN>
AllowGroup uploader-{{ initials|lower }}
Deny ALL
</Limit>

<snip>

{% if ftps_limit_list is defined %}
<Limit {{ ftps_limit_list }}>
{% else %}
<Limit LIST MLSD MLST NLST SIZE>
{% endif %}
AllowAll
</Limit>

What I expect is 3 configuration files that look like this:

abc.conf (note custom Limit to be allowed)

<Directory /path/to/ABC/uploads>

<snip>

<Limit LOGIN>
AllowGroup uploader-abc
Deny ALL
</Limit>

<snip>

<Limit LIST PWD XPWD>
AllowAll
</Limit>

dfg.conf (note: uses all the defaults)

<Directory /path/to/DFG/uploads>

<snip>

<Limit LOGIN>
AllowGroup uploader-dfg
Deny ALL
</Limit>

<snip>

<Limit LIST MLSD MLST NLST SIZE>
AllowAll
</Limit>

TestUploader.conf (note custom upload directory)

<Directory /path/to/TestUploader/uploads>

<snip>

<Limit LOGIN>
AllowGroup uploader-testuploader }}
Deny ALL
</Limit>

<snip>

<Limit LIST MLSD MLST NLST SIZE>
AllowAll
</Limit>

And my unsuccessful attempt to accomplish this is in this task:

- name: Copy in the configs for various labs
  template:
    src: conf.d.j2
    dest: "/etc/proftpd/conf.d/{{ item.initials }}.conf"
    mode: '0644'
    owner: root
    group: root
  with_dict: "{{ uploaders }}"

What is everyones best advice to creating these configuration files while maintaining a source of truth that can be used for other playbooks? (We are early in our ansible process, so the structure can be changed. My concern is to be as forward thinking for scalability as possible.)

Thanks!

1 Answer 1

1

Well, it turns out I was VERY close.

Two changes needed to be made:

  1. My task needed 'loop' rather than 'with_dict'.
- name: Copy in the configs for various labs
  template:
    src: conf.d.j2
    dest: "/etc/proftpd/conf.d/{{ item.initials }}.conf"
    mode: '0644'
    owner: root
    group: root
  loop: "{{ uploaders }}"
  1. My template needed to access the variable with the 'item.' prefix:
{% if item.ftps_upload_directory is defined %}
<Directory {{ item.ftps_upload_directory }}>
{% else %}
<Directory /path/to/{{ item.initials|upper }}/uploads>
{% endif %}

My playbook works correctly now.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.