# Working around lookup plugin limitation with environment variables

**URL:** <https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178>\
**Category:** Ansible Project\
**Tags:** aws\
**Created:** [April 10, 2017, 7:40am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178 "2017-04-10T07:40:30Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rob\_White](https://avatars.discourse-cdn.com/v4/letter/r/71c47a/32.png) [@Rob\_White](https://forum.ansible.com/u/Rob_White)\
**Post date:** [April 10, 2017, 7:40am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/1 "2017-04-10T07:40:30Z")

</div>

Hi all,

I’m looking for any suggestions on how to work around the following issue:

I am trying to use a lookup plugin but it is ignoring my environment variables.

The lookup plugin I am trying to use is credstash and the environment variables are being set because I am using AWS STS to assume a role.

It looks a little like this:

`

```auto
---
- name: Get STS token
  hosts: "{{ hosts }}"
  connection: local
  tasks:
    - name: Assume role for passed account
      sts_assume_role:
        region: "{{ aws_region }}"
        role_arn: "arn:aws:iam::{{ aws_account_id }}:role/ansible-is_assumed"
        role_session_name: ansible_assumed_role
      register: assumed_role
      when: use_sts

    - name: Set environment with AWS creds when available
      set_fact:
        my_environment:
          AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
          AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
          AWS_SECURITY_TOKEN: "{{ assumed_role.sts_creds.session_token }}"
      when: assumed_role.skipped is not defined

    - name: Set environment blank when no AWS creds
      set_fact:
        my_environment: {}
      when: assumed_role.skipped is defined

- name: Deploy infrastructure role
  hosts: "{{ hosts }}"
  connection: local
  roles:
    - "{{ role_to_deploy }}"
  environment: "{{ my_environment }}"

```

`

Now in the role\_to\_deploy i have lots of tasks that work brilliantly calling out to AWS using the STS credentials supplied as intended.

Unfortunately, any lookup plugins do not work properly because they do not use the environment variables I have set. They end up calling out to AWS using the default credentials rather than being overridden by the STS creds.

I don’t think this is a bug but it is never the less annoying.

I’m hoping maybe one of the core team can think of a way I can get the lookup plugin to ‘see’ my STS environment variables I have set.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [April 10, 2017, 5:07pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/2 "2017-04-10T17:07:46Z")

</div>

The environment keyword ONLY affects remote task execution (invoked  
inside connection), not the 'local' environment which is what lookups  
run under.

---

<div class="post-metadata">

**Author:** ![Rob\_White](https://avatars.discourse-cdn.com/v4/letter/r/71c47a/32.png) [@Rob\_White](https://forum.ansible.com/u/Rob_White)\
**Post date:** [April 11, 2017, 12:18am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/3 "2017-04-11T00:18:26Z")

</div>

Indeed, hence why it doesn’t work.

Is there any other way to pass an environment variable to a lookup plugin?

The only thing I’ve come up with is a not very elegant:

`lookup('pipe', '(export AWS_ACCESS_KEY_ID=' + assumed_role.sts_creds.access_key + ' && export AWS_SECRET_ACCESS_KEY=' + assumed_role.sts_creds.secret_key + ' && export AWS_SECURITY_TOKEN=' + assumed_role.sts_creds.session_token + ' && credstash -r ' + aws_region + ' -t ' + env + '-credstash get rds_instance_mysql-1_username)')`

This then fails when I am not using STS.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [April 11, 2017, 12:59pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/4 "2017-04-11T12:59:48Z")

</div>

set them in the environment before executing Ansible

AWS\_SECURITY\_TOKEN=xxx ansible-playbook ....

---

<div class="post-metadata">

**Author:** ![Rob\_White](https://avatars.discourse-cdn.com/v4/letter/r/71c47a/32.png) [@Rob\_White](https://forum.ansible.com/u/Rob_White)\
**Post date:** [April 12, 2017, 1:41am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/5 "2017-04-12T01:41:10Z")

</div>

The problem is it is the ansible-playbook that is actually going off to get the STS creds using sts\_assume\_role module so until i run the play, i don’t have the creds.

I guess I could invoke a playbook from within another playbook 😑

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 16, 2020, 10:05pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/6 "2020-07-16T22:05:26Z")

</div>

Hey, have you ever find a solution here ?  
I face the same problem trying to pass my sts credentials in environment for a role, like this :

pre\_tasks :

- name: Assume role  
sts\_assume\_role:  
role\_arn: “arn:aws:iam:::role/myrole”  
role\_session\_name: “mysession”  
region: “{{ my\_region }}”  
register: assumed\_role

roles:

- myrole

environment:  
AWS\_ACCESS\_KEY\_ID: “{{ assumed\_role.sts\_creds.access\_key }}”  
AWS\_SECRET\_ACCESS\_KEY: “{{ assumed\_role.sts\_creds.secret\_key }}”  
AWS\_SECURITY\_TOKEN: “{{ assumed\_role.sts\_creds.session\_token }}”

however it doesn’t work because environment is evaluated before everything else, so my pre-task has not been run yet and the credentials (assumed\_role variable) doesn’t exist .  
not sure how to pass credential as environment in this case ?

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [July 17, 2020, 12:15pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/7 "2020-07-17T12:15:13Z")

</div>

Hello Nico,

I recommended to switch to tasks only in your playbook instead of using pre\_tasks and roles keywords.  
This should solve your problem and in my opinion it also looks more consistent:

tasks:  
&nbsp;&nbsp;- name: Assume role  
&nbsp;&nbsp;&nbsp;&nbsp;sts\_assume\_role:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;role\_arn: "arn:aws:iam:::role/myrole"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;role\_session\_name: "mysession"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;region: "{{ my\_region }}"  
&nbsp;&nbsp;&nbsp;&nbsp;register: assumed\_role  
&nbsp;&nbsp;- name: Import my role  
&nbsp;&nbsp;&nbsp;&nbsp;import\_role:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name: myrole  
&nbsp;&nbsp;&nbsp;&nbsp;environment:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_ACCESS\_KEY\_ID: "{{ assumed\_role.sts\_creds.access\_key }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECRET\_ACCESS\_KEY: "{{ assumed\_role.sts\_creds.secret\_key }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECURITY\_TOKEN: "{{ assumed\_role.sts\_creds.session\_token }}"

Regards  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Racke

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 17, 2020, 6:02pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/8 "2020-07-17T18:02:29Z")

</div>

Thanks Racke,  
sure , so in this case **_environment_** is assigned to the _ **tasks** _ level and should therefore not fail cause it is not loaded before runtime.  
In the case I have multiple roles, I have to repeat the task as many times as I need a role , lots of duplicate _ **environment** _ then .

Can we pass a list or role in _ **import\_role** _ or _ **include\_role** _ ? I couldn’t make this working with “_ **loop** _”

cheers

```auto

- include_role:
        - name: myrole1, when: something | default(None) 
        - name: myrole2, when: somethingElse | default(None)
  environment:
      AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
      AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
      AWS_SECURITY_TOKEN: "{{ assumed_role.sts_creds.session_token }}" 

```

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [July 17, 2020, 6:12pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/9 "2020-07-17T18:12:21Z")

</div>

> Thanks Racke,  
> sure , so in this case \*/environment /\*is assigned to the /\*tasks \*/level and should therefore not fail cause it is not  
> loaded before runtime.  
> In the case I have multiple roles, I have to repeat the task as many times as I need a role , lots of  
> duplicate /\*environment \*/then .
> 
> Can we pass a list or role in /\*import\_role \*/or /\*include\_role \*/? I couldn't make this working with "/\*loop\*/"
> 
> cheers

Hello Nico,

Loop is the wrong approach. But you can certainly set up a variable with your desired environment:

- name: My env  
&nbsp;&nbsp;set\_fact:  
&nbsp;&nbsp;&nbsp;&nbsp;myenv:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_ACCESS\_KEY\_ID: "{{ assumed\_role.sts\_creds.access\_key }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECRET\_ACCESS\_KEY: "{{ assumed\_role.sts\_creds.secret\_key }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECURITY\_TOKEN: "{{ assumed\_role.sts\_creds.session\_token }}"

And in your import\_role/include\_role:

&nbsp;&nbsp;- name: Import my role  
&nbsp;&nbsp;&nbsp;&nbsp;import\_role:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name: myrole  
&nbsp;&nbsp;&nbsp;&nbsp;environment: "{{ myenv }}"

Regards  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Racke

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 23, 2020, 2:59am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/10 "2020-07-23T02:59:29Z")

</div>

Thank you for the proposition, I ve been trying for days to put this in every direction I could but unfortunately 'environment ’  
was never passed to ‘import\_role’ .  
I am not sure how to investigate about import\_role module and why environment is not supported , seems impossible to reuse sts.creds then .  
Any idea is welcome

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [July 23, 2020, 4:27am UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/11 "2020-07-23T04:27:36Z")

</div>

Your setting it in one play and then try to use it in another. That won’t work.

Other question. You run this sts task for all hosts, but is that needed for all of them?

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 24, 2020, 5:44pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/12 "2020-07-24T17:44:05Z")

</div>

not sure if that needs new topic but I see that other AWS modules also fail to pickup variables in Environment as they should .

Example is rds\_instance\_facts

again, I set up the sts credentials in environment block, and then the module doesn’t use them ,why is that ?

`  
Saisissez le code ici…

# playbook.yml

pre\_tasks:  
`

- name: Assume teardown devel stack role  
sts\_assume\_role:  
role\_arn: “arn:aws:iam:::role/role”  
role\_session\_name: “session”  
region: “{{ region }}”  
register: assumed\_role

# no\_log: false

- name: import roles  
block:
- import\_role:  
name: test2  
when: cf\_region is defined  
environment:  
aws\_access\_key: “{{ assumed\_role.sts\_creds.access\_key }}”  
aws\_secret\_key: “{{ assumed\_role.sts\_creds.secret\_key }}”  
security\_token: "{{ assumed\_role.sts\_creds.session\_token }}

# test2.yml

- name: Get rds facts  
rds\_instance\_facts:

# command: facts

db\_instance\_identifier: “{{ cf\_stack\_name }}”  
region: “{{ cf\_region }}”  
register: rds

in the exec I see the temporary keys:

EXEC /bin/sh -c 'aws\_secret\_key=cHAyHECUKdRXeMNELOADIjPKRwdYfJR/BIY8nVMZ aws\_access\_key=ASIA3K27TU7xxxxxxxxxxxx  
security\_token=FwoGZXIvYXdzEOv//////////wEaDBTRsHoNaa4W+L0bkiK+ASTwafNPh9h+q2E6IqgZAR/MjX4eDpo/Vh2zLfFX+D/XHH/B1fCcLUaGp+6AXc0H/wqJG58dt9SQP5Dym1iLq3Xzn3rVwmEc9U+0Q3PcdbczO4qwJS/A2mr1lnZ03HV+PsT0lFbActJJ65VHcNvVCqy4sSvRd+ykeBgkkiM6L35icm8eTr5RJdnTMb2tmcHogNXteaXbaag1AjABC/114coEMspTOCPjexiPtic3io67lQvIJPK9L3gqKsMMn4Ioq7js+AUyLer/WPTStS/PBgsU8WsLrlxd/iuaU4qGgquy4+6vY5H/X7vEaSMyT/8OKo6MVg==

but the module doesn’t care and bail with :  
ClientError: An error occurred (AccessDenied) when calling the DescribeDBInstances operation: User: arn:aws:iam:::user/myuser is not authorized to perform: rds:DescribeDBInstances on resource

I am losing hope in ansible ☹  
What is the point of having a global environment if each and single AWS module requires a set of local credentials ?  
please help me understand the logic here,  
cheers

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [July 24, 2020, 7:41pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/13 "2020-07-24T19:41:56Z")

</div>

> not sure if that needs new topic but I see that other AWS modules also fail to pickup variables in Environment as they  
> should .

You are sure these environment variables are lowercase? Usually they are uppercase, like AWS\_ACCESS\_KEY.

Ansible just passes them along as you see in your output.

Regards  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Racke

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [July 27, 2020, 3:50pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/14 "2020-07-27T15:50:35Z")

</div>

Another option, is to use 'default' filter:

&nbsp;&nbsp;environment:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_ACCESS\_KEY\_ID: "{{ ars.access\_key|default('') }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECRET\_ACCESS\_KEY: "{{ ars.secret\_key|default('') }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AWS\_SECURITY\_TOKEN: "{{ ars.session\_token|default('') }}"  
&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ars: '{{ assumed\_role|default({}).sts\_creds|default({}) }}'

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 28, 2020, 11:19pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/15 "2020-07-28T23:19:44Z")

</div>

same problem, assumed\_role is not defined yet, so ansible failed for Undefined variable, although I couldn’t get the syntax you provided to work for the ars var , is that the good syntax ?  
I got :

`An unhandled exception occurred while templating '{{assumed_role|default({}).sts_creds|default({})}}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: expected token 'end of print statement', got '.'. String: {{assumed_role|default({}).sts_creds|default({})}}"`

---

<div class="post-metadata">

**Author:** ![Nic\_H](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nic\_H](https://forum.ansible.com/u/Nic_H)\
**Post date:** [July 28, 2020, 11:31pm UTC](https://forum.ansible.com/t/working-around-lookup-plugin-limitation-with-environment-variables/24178/16 "2020-07-28T23:31:54Z")

</div>

> > not sure if that needs new topic but I see that other AWS modules also fail to pickup variables in Environment as they  
> > should .
> 
> You are sure these environment variables are lowercase? Usually they are uppercase, like AWS\_ACCESS\_KEY.
> 
> Ansible just passes them along as you see in your output.
> 
> Regards  
> Racke

yes you r right, in uppercase it then works better with the "block / import\_role / environment " structure .  
Thank you
