When simply using the command line, the main strategy would be to use the cache
git credential helper:
git config --global credential.helper cache
git config --global credential.username {{ gituser }}
git pull {{ repository1 }}
... asks password
... pulls
git pull {{ repository2 }}
... pulls
... etc.
But if I use the ansible git module, prompting does not work (nor is it practical). The only solution I currently see is to use:
- git: repo=https://{{ gituser }}:{{ gitpass }}@{{ repo_url }} dest={{ dest }}
Where I get gituser
and gitpass
using vars_prompt:
, or from ansible's local secure storage. However, this has the unfornutate side effect that it stores the password in {{ dest }}/.git/config
in plain text, which I would like to avoid.
Is there a way to set the password from ansible for the time of the playbook run, but not to store it on the server?
The
ansible
git
module doesn't currently have a way to specify the password be ephemeral, i.e. to ensure it is erased from the.git
directory after the upstream repository has been cloned.You could "hack" this by invoking the
command
module after the invocation of thegit
module to remove the upstream remote from the repository configuration, which will obviously remove any secrets. This does mean the secret is temporarily stored on the host during the pull operation -- this may not be suitable depending upon the threat model you are working under.A better way?
These scenarios are where SSH key authentication comes to the fore, per EEAA's comment. If you can authenticate to your git upstream using SSH, you can use SSH agent forwarding in your Ansible session to pass your SSH agent from the control host through to the target server.
This is a robust method of credential sharing which only survives for the duration of the session, so the long-term risks of secrets being left on the remote host are minimised.
In the end, I went with a solution similar to the hack @CosmicOssifrage mentions. The main difference is that
git remote remove origin
is not enough to remove all secrets, as the password is written to various files in.git/logs/
. So at the end I simply created an include file that calls sed to clean up the mess:This is called like:
What this fails to address is if the git checkout fails for some reason, the next command will not be run, thus leaving the credentials there. The solution would be quite awkward with current ansible failure handling tactics, so I chose to take that risk.