Issue 1:
ISSUE TYPE

Bug Report

COMPONENT NAME

modules/cloud/amazon/ec2_vpc_peer.py

ANSIBLE VERSION

ansible --version
ansible 2.4.2.0
config file = /home/snobym/work/aws-k8s-kops/ansible.cfg
configured module search path = [u'/home/snobym/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /home/snobym/.local/lib/python2.7/site-packages/ansible
executable location = /home/snobym/.local/bin/ansible
python version = 2.7.14 (default, Sep 23 2017, 22:06:14) [GCC 7.2.0]

CONFIGURATION

ansible-config dump --only-changed
ANSIBLE_NOCOWS(/home/snobym/work/aws-k8s-kops/ansible.cfg) = True
CACHE_PLUGIN(/home/snobym/work/aws-k8s-kops/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/snobym/work/aws-k8s-kops/ansible.cfg) = .tmp/ansible_fact_cache
CACHE_PLUGIN_TIMEOUT(/home/snobym/work/aws-k8s-kops/ansible.cfg) = 86400
DEFAULT_CALLBACK_PLUGIN_PATH(/home/snobym/work/aws-k8s-kops/ansible.cfg) = [u'/home/snobym/work/aws-k8s-kops/callbacks']
DEFAULT_FORKS(/home/snobym/work/aws-k8s-kops/ansible.cfg) = 20
DEFAULT_HOST_LIST(/home/snobym/work/aws-k8s-kops/ansible.cfg) = [u'/home/snobym/work/aws-k8s-kops/inventory']
HOST_KEY_CHECKING(/home/snobym/work/aws-k8s-kops/ansible.cfg) = False
RETRY_FILES_ENABLED(/home/snobym/work/aws-k8s-kops/ansible.cfg) = False

OS / ENVIRONMENT

Running on Ubuntu 16.04 on an ec2 instance.

SUMMARY

I've used the ec2_vpc_peer module to create a peering connection with tags. Just like in the example in the docs. When I run the next command to locally accept the connection the backtrace shows an exception occurred because the module had no tags defined.

STEPS TO REPRODUCE

# tasks file for vpc-peering
- name: "Get vpc ID of the east-prod.k8s.foo.com VPC"
ec2_vpc_net_facts:
region: "us-east-1"
filters:
"tag:Name": east-prod.k8s.foo.com
register: vpc_data

- set_fact:
K8S_VPC_ID: "{{ vpc_data.vpcs[0].id }}"

#
# Now get the VPC_ID of the Foo Prod VPC
#
- name: "Get vpc ID of the Foo Prod VPC"
ec2_vpc_net_facts:
region: "us-east-1"
filters:
"tag:Name": Foo Prod
register: foo_prod

- set_fact:
FOO_PROD_VPC_ID: "{{ foo_prod.vpcs[0].id }}"

#
# Doing some back error checking to ensure our values are correctly defined
#
- fail: msg="Variable '{{item}}' is not defined"
when: item not in vars
with_items:
- K8S_VPC_ID
- FOO_PROD_VPC_ID

- debug:
msg: "K8S_VPC_ID is {{ K8S_VPC_ID }} "

- debug:
msg: "FOO_PROD_VPC_ID is {{ FOO_PROD_VPC_ID }} "

- name: Create local Account VPC peering connection
ec2_vpc_peer:
region: us-east-1
vpc_id: "{{ K8S_VPC_ID }}"
peer_vpc_id: "{{ FOO_PROD_VPC_ID }}"
state: present
tags:
Name: prod-east-k8s-to-prod-us-east
Project: Kubernetes
register: vpc_peer

- name: Accept local VPC peering request
ec2_vpc_peer:
region: us-east-1
peering_id: "{{ vpc_peer.peering_id }}"
state: accept
register: action_peer

EXPECTED RESULTS

I expected the peering connection to be accepted, after that no changes should happen.

ACTUAL RESULTS

It looks on every run whether the peering connection has been accepted or not the tags are deleted then created again, but since in my accept task I don't list any tags the module throws an exception and gives a back trace because there are no tags to create. To work around this I simply duplicate the tags in the accept call. These are the same tags I used in the create call.

TASK [vpc-peering : Accept local VPC peering request] ******************************************************************************************************************************************
task path: /home/snobym/work/aws-k8s-kops/roles/vpc-peering/tasks/main.yml:53
Using module file /home/snobym/.local/lib/python2.7/site-packages/ansible/modules/cloud/amazon/ec2_vpc_peer.py
<east-prod> ESTABLISH LOCAL CONNECTION FOR USER: snobym
<east-prod> EXEC /bin/sh -c 'echo ~ && sleep 0'
<east-prod> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577 `" && echo ansible-tmp-1518528910.29-192160277860577="` echo /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577 `" ) && sleep 0'
<east-prod> PUT /tmp/tmpZyrTq7 TO /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577/ec2_vpc_peer.py
<east-prod> EXEC /bin/sh -c 'chmod u+x /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577/ /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577/ec2_vpc_peer.py && sleep 0'
<east-prod> EXEC /bin/sh -c '/usr/bin/python /home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577/ec2_vpc_peer.py; rm -rf "/home/snobym/.ansible/tmp/ansible-tmp-1518528910.29-192160277860577/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
File "/tmp/ansible_02oSze/ansible_module_ec2_vpc_peer.py", line 334, in create_tags
client.create_tags(Resources=[pcx_id], Tags=load_tags(module))
File "/home/snobym/.local/lib/python2.7/site-packages/botocore/client.py", line 317, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/snobym/.local/lib/python2.7/site-packages/botocore/client.py", line 615, in _make_api_call
raise error_class(parsed_response, operation_name)

fatal: [east-prod]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"aws_access_key": null,
"aws_secret_key": null,
"ec2_url": null,
"peer_owner_id": null,
"peer_vpc_id": null,
"peering_id": "pcx-bf342cd6",
"profile": null,
"region": "us-east-1",
"security_token": null,
"state": "accept",
"tags": null,
"validate_certs": true,
"vpc_id": null
}
},
"msg": "An error occurred (InvalidParameterValue) when calling the CreateTags operation: Value ( empty ) for parameter tagSet is invalid. You must specify one or more tags to create"
}

The module should probably NOT delete and recreate the tags on the accept call.

Issue 2:
Currently there is no way to pass in variables when using lookup('template', 'mytemplate.j2').

For example. Given the following lookup:

lookup('template', 'mytemplate.j2')

Let's say I want to pass in a var foo which equals bar so that inside the template {{ foo }} outputs {{ bar }}

My scenario is that I'm generating user-data for cloudformation... I have 3 sets of user-data to generate from the same file, where 1 variable changes in that file for each set.