Using a list variable for efs target key

Hello,
Long time listener first time poster here.

AWS Availability Zones are highly dynamic. The Ansible EFS module has a targets key that seems static.

Has anyone been able to push a list variable into this key to get a EFS to deploy in a more dynamic nature?

ANSIBLE VERSION

$ ansible --version
ansible 2.3.1.0
config file = /Users/user/repos/ansible-ops/ansible.cfg
configured module search path = [u’./library/']
python version = 2.7.10 (default, Feb 7 2017, 00:08:15) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]

ANSIBLE CODE

  • name: Populating targets list
    set_fact:
    targets: “{{ targets | default() }} + {{ [ { ‘subnet_id’: efs_target_item, ‘security_groups’: efs_item.security_groups } ] }}”
    with_items:

  • “{{ efs_item.subnet }}”
    loop_control:
    loop_var: efs_target_item

  • debug: msg=“{{ targets}}”

  • name: Creating EFS Target
    efs:
    aws_access_key: “{{ aws_access_key }}”
    aws_secret_key: “{{ aws_secret_key }}”
    security_token: “{{ security_token }}”
    state: present
    name: “{{ efs_item.name }}”
    region: “{{ region }}”
    tags:
    Name: “{{ efs_item.name }}”
    Site: “{{ site }}”
    targets: [ “{{ targets }}” ]

ansible OUTPUT

TASK [debug] ****************************************************************************************************************************
task path: /Users/user/repos/ansible-ops/playbooks/roles/aws-efs/tasks/create.yaml:33
ok: [localhost] => {
“msg”: [
{
“security_groups”: “sg-abcd1234”,
“subnet_id”: “subnet-abcd1234”
},
{
“security_groups”: “sg-abcd1234”,
“subnet_id”: “subnet-abcd1234”
},
{
“security_groups”: “sg-abcd1234”,
“subnet_id”: “subnet-abcd1234”
}
]
}

TASK [Create EFS Target] ****************************************************************************************************************
task path: /Users/user/repos/ansible-ops/playbooks/roles/aws-efs/tasks/create.yaml:35
Using module file /Users/user/virtualenvs/ansible/lib/python2.7/site-packages/ansible/modules/cloud/amazon/efs.py
ESTABLISH LOCAL CONNECTION FOR USER: user
EXEC /bin/sh -c ‘echo ~ && sleep 0’
EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792” && echo ansible-tmp-1509464005.83-40924843971792=“echo /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792” ) && sleep 0’
PUT /var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/tmpsl6C1w TO /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792/efs.py
EXEC /bin/sh -c ‘chmod u+x /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792/ /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792/efs.py && sleep 0’
EXEC /bin/sh -c ‘python /Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792/efs.py; rm -rf “/Users/user/.ansible/tmp/ansible-tmp-1509464005.83-40924843971792/” > /dev/null 2>&1 && sleep 0’
The full traceback is:
Traceback (most recent call last):
File “/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_1RA7ko/ansible_module_efs.py”, line 631, in
main()
File “/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_1RA7ko/ansible_module_efs.py”, line 599, in main
targets = [dict((target_translations[key], value) for (key, value) in x.items()) for x in module.params.get(‘targets’)]
AttributeError: ‘list’ object has no attribute ‘items’

fatal: [localhost]: FAILED! => {
“changed”: false,
“failed”: true,
“module_stderr”: “Traceback (most recent call last):\n File "/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_1RA7ko/ansible_module_efs.py", line 631, in \n main()\n File "/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_1RA7ko/ansible_module_efs.py", line 599, in main\n targets = [dict((target_translations[key], value) for (key, value) in x.items()) for x in module.params.get(‘targets’)]\nAttributeError: ‘list’ object has no attribute ‘items’\n”,
“module_stdout”: “”,
“msg”: “MODULE FAILURE”,
“rc”: 0
}

Thanks,
/Chris C

I solved this problem. Targets security_groups is a dictionary!

ansible DEBUG OUTPUT

fatal: [localhost]: FAILED! => {
“changed”: false,
“failed”: true,
“module_stderr”: “Traceback (most recent call last):\n File "/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_GOX2SY/ansible_module_efs.py", line 631, in \n main()\n File "/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_GOX2SY/ansible_module_efs.py", line 614, in main\n changed = connection.converge_file_system(name=name, tags=tags, targets=targets) or changed\n File "/var/folders/z_/kvbxc4110t189p1kg1hky4nm0000gn/T/ansible_GOX2SY/ansible_module_efs.py", line 427, in converge_file_system\n **targets[sid]\n File "/Users/ccallega/virtualenvs/ansible/lib/python2.7/site-packages/botocore/client.py", line 312, in _api_call\n return self._make_api_call(operation_name, kwargs)\n File "/Users/ccallega/virtualenvs/ansible/lib/python2.7/site-packages/botocore/client.py", line 575, in _make_api_call\n api_params, operation_model, context=request_context)\n File "/Users/ccallega/virtualenvs/ansible/lib/python2.7/site-packages/botocore/client.py", line 630, in _convert_to_request_dict\n api_params, operation_model)\n File "/Users/ccallega/virtualenvs/ansible/lib/python2.7/site-packages/botocore/validate.py", line 291, in serialize_to_request\n raise ParamValidationError(report=report.generate_report())\nbotocore.exceptions.ParamValidationError: Parameter validation failed:\nInvalid type for parameter SecurityGroups, value: sg-abcd1234, type: <type ‘str’>, valid types: <type ‘list’>, <type ‘tuple’>\n”,
“module_stdout”: “”,
“msg”: “MODULE FAILURE”,
“rc”: 0

Here is the working code…

ANSIBLE CODE

  • name: Populating targets list
    set_fact:
    targets: “{{ targets | default() }} + {{ [ { ‘subnet_id’: efs_target_item, ‘security_groups’: [ efs_item.security_groups ] } ] }}”
    with_items:

  • “{{ efs_item.subnet }}”
    loop_control:
    loop_var: efs_target_item

  • debug: msg=“{{ targets}}”

  • name: Creating EFS target
    efs:
    aws_access_key: “{{ aws_access_key }}”
    aws_secret_key: “{{ aws_secret_key }}”
    security_token: “{{ security_token }}”
    state: present
    name: “{{ efs_item.name }}”
    region: “{{ region }}”
    tags:
    Name: “{{ efs_item.name }}”
    Site: “{{ site }}”
    targets: “{{ targets }}”

Thanks,
/Chris C