Forum Discussion

Former Member's avatar
Former Member
4 years ago

Get multiple items from the vault using Ansible loop

So, I am wondering if there is a way to get multiple items from the vault at once?

Here is the issue - I have a playbook with 20 or 30 secrets that are going to be stored inside 1Password. What I really want to avoid is writing the same item_info task 30 times.

Instead, I've made the following:

secrets:
title: Random item
fields:
- var: some_label
definition:
label: Some Label
value: "the value"
section: "Personal Info"
field_type: concealed
- var: dashboard_password
definition:
label: Dashboard Password
generate_value: on_create
generator_recipe:
length: 16
include_symbols: no

It works perfectly for creating items inside 1Password vault, but I also want to be able to retrieve all these values using Ansible loop, something like this:

- name: Get the item
item_info:
item: "{{ vault_title }}"
field: "{{ item.definition.label }}"
vault: Ansible
no_log: true
register: "{{ item.definition.var }}"
loop: "{{ secrets.fields }}"

The problem is that registered var names are not templatable, so the task above is going to fail.

So, is there any other way of doing this?


1Password Version: Not Provided
Extension Version: Not Provided
OS Version: Not Provided

5 Replies

  • Former Member's avatar
    Former Member

    So apparently someone decided to alter the response of the API and make it much simpler to extract all fields from the item.

    Now, instead of doing all that I had to do (described in the comment above), to get to the same result you just need to do this:

    ```
    - name: Get the item
    item_info:
    item: "{{ vault_title }}"
    vault: Ansible
    no_log: true
    register: smtn
    loop: "{{ secrets.fields }}"

    - name: Loop into dictionary
      set_fact:
        password_secrets: "{{ password_secrets | default({}) | combine ({ item.item.label : item.item.value | default('null') }) }}"
      loop: '{{ smtn.results }}'
    

    ```

    That's considerably easier! And I just finished my 1Password role and noticed that it's not working - this is why :) Anyhow, this is much much better!

  • Former Member's avatar
    Former Member

    Absolutely! Here it is: https://github.com/1Password/ansible-onepasswordconnect-collection/issues/38

  • Former Member's avatar
    Former Member

    This is a great idea and I agree this should be supported by the module. We've looked into creating a Lookup Plugin as well, but haven't checked whether that would solve the multiple-lookup issue.

    Could you open an issue in our GitHub repository: https://github.com/1Password/ansible-onepasswordconnect-collection/issues ?

  • Former Member's avatar
    Former Member

    Well after some serious head banging I've actually managed to extract all information I needed.

    Here is the result:

    TASK [Are we there yet?] ***************************************************************************************************************************************************************************************************************************************************************************************************
    ok: [snip] =>
    password_secrets:
    dashboard_password: DrtqaPW7jhUYCKXX
    notesPlain: 'null'
    some_label: the value
    some_label3: the value3
    some_label_2: the value2

    And here is how:
    ```
    - name: Get the item
    item_info:
    item: "{{ vault_title }}"
    vault: Ansible
    no_log: true
    register: smtn
    loop: "{{ secrets.fields }}"

    - name: Set fields
      set_fact:
        fields: "{{ fields | default([]) + [item.op_item.fields] }}"
      loop: '{{ smtn.results }}'
    
    - name: Convert fields to an actual dictionary
      set_fact:
        field_dict: "{{ fields | first | dict2items }}"
    
    - name: Set final items
      set_fact:
        final_items: "{{ final_items | default([]) + [item.value] }}"
      loop: '{{ field_dict }}'
    
    - name: Loop into dictionary
      set_fact:
        password_secrets: "{{ password_secrets | default({}) | combine ({ item.label : item.value | default('null') }) }}"
      loop: '{{ final_items }}'
    
    - name: Are we there yet?
      ansible.builtin.debug:
        var: password_secrets
    

    ```

    Someone might find this useful. Anyhow, I think this should be much much much easier and something available right out of the box.

  • Former Member's avatar
    Former Member

    So, I managed to get this:

    TASK [Print the item] *********************************************************************************************************************************************************************************************
    ok: [snip] =>
    smtn:
    changed: false
    msg: All items completed
    results:
    - ansible_facts:
    discovered_interpreter_python: /usr/bin/python3
    ansible_loop_var: item
    changed: false
    failed: false
    field: the value
    invocation:
    module_args:
    field: Some Label
    hostname: snip
    item: Glupi item
    token: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
    vault: Ansible
    item:
    definition:
    field_type: concealed
    label: Some Label
    section: Personal Info
    value: the value
    var: some_label
    op_item: {}
    - ansible_loop_var: item
    changed: false
    failed: false
    field: DrtqaPW7jhUYCKXX
    invocation:
    module_args:
    field: Dashboard Password
    hostname: snip
    item: Glupi item
    token: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
    vault: Ansible
    item:
    definition:
    generate_value: on_create
    generator_recipe:
    include_symbols: false
    length: 16
    label: Dashboard Password
    var: dashboard_password
    op_item: {}

    out of this:

    - name: Get the item
    item_info:
    item: "{{ vault_title }}"
    field: "{{ item.definition.label }}"
    vault: Ansible
    no_log: true
    register: smtn
    loop: "{{ secrets.fields }}"

    But that's it. I see that there are two ansible_loop_var items in the results but I am just unable to iterate through them.

    Any help would be appreciated.