ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
823 stars 1.52k forks source link

ansible_become_password via 1Password lookup causes significant slowdown of playbook execution #8113

Closed jamesdh closed 6 months ago

jamesdh commented 7 months ago

Summary

I was working on some playbooks intended for running locally over the weekend and got tired of constantly typing in my password, so I added the following:

- hosts: localhost
  vars:
    ansible_become_password: "{{ lookup('community.general.onepassword', 'Personal MacBook', field='password') }}"
  roles:
    ...

I gave a run, and immediately noticed that the playbooks were executing at about 1/10th of their normal speed, with a noticeable ~1 second pause between every task. It's almost as if it's evaluating the field lookup for every task.

Issue Type

Bug Report

Component Name

onepassword

Ansible Version

2.16.4

Community.general Version

community.general 8.4.0  

Configuration

CALLBACKS_ENABLED(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = ['ansible.posix.profile_tasks']
CONFIG_FILE() = /Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg
DEFAULT_HOST_LIST(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = ['/Users/jamesdh/Projects/jamesdh/dotfiles/hosts']
DEFAULT_LOOKUP_PLUGIN_PATH(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = ['/Users/jamesdh/Projects/jamesdh/dotfiles/lookup_plugins']
DEFAULT_MODULE_PATH(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = ['/Users/jamesdh/Projects/jamesdh/dotfiles/library']
DEFAULT_STDOUT_CALLBACK(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = yaml
DEFAULT_VAULT_PASSWORD_FILE(/Users/jamesdh/Projects/jamesdh/dotfiles/ansible.cfg) = /Users/jamesdh/.ansible/dotfiles_vaultpass
EDITOR(env: EDITOR) = vim

OS / Environment

macOS 14.4, Python 3.12.2

Steps to Reproduce

Expected Results

Playbooks execute at the same speed as if the user used --ask-become-pass and manually entered it.

Actual Results

Playbooks execute many times slower

Code of Conduct

ansibullbot commented 7 months ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

felixfontein commented 7 months ago

Variables are lazily evaluated. This means that this lookup is called every single time ansible_become_password is used.

Better use set_fact as a first task (or pre-task) to obtain the password once and store the (evaluated) result in a variable.

jamesdh commented 7 months ago

Thanks @felixfontein, I suspected it was something like that but have been away from ansible long enough I really had no idea.

kitforbes commented 6 months ago

I achieved this with a playbook like this:

---
- hosts: remote_host
  become: true
  become_method: ansible.builtin.sudo
  become_user: root
  gather_facts: false

  pre_tasks:
  - name: Get facts from 1Password
    set_fact:
      ansible_become_pass: "{{ lookup('community.general.onepassword', 'remote_host', field='become_password', vault='infra') }}"
      ansible_host: "{{ lookup('community.general.onepassword', 'remote_host', field='hostname', vault='infra') }}"
      ansible_port: "{{ lookup('community.general.onepassword', 'remote_host', field='port', vault='infra') }}"
      ansible_user: "{{ lookup('community.general.onepassword', 'remote_host', field='user', vault='infra') }}"
  - name: Gather facts
    ansible.builtin.gather_facts:

Thanks for the guidance!

felixfontein commented 6 months ago

You might want to add run_once: true to the set_fact task to speed this up even a bit further :)

jamesdh commented 6 months ago

Closing this since @kitforbes and @felixfontein's answers provide a working solution. Thank you!