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

Comments

  • 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.

  • 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.

  • David_agDavid_ag

    Team 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: 1password/ansible-onepasswordconnect-collection ?

  • 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!

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file