I’m writing a custom Ansible lookup plugin that uses open_url to communicate with a web server.
I have to include client_cert and client_key, but I want to keep client_key on my computer encrypted.
Every time I run the playbook, I’m prompted Enter PEM pass phrase: for every lookup that occurs.
I’ve been scouring online, and AI tools trying to find a way to store the pass phrase as a variable, set it in ansible.cfg, or any other method, and can’t seem to find a way.
Do I have to decrypt the private_key to not be prompted?
Is there any other way?
Is there anything I can do in my custom plugin to make it smoother?
You’ll probably want to provide a module option to feed the lookup plugin with the passphrase. That option can be filled by ansible vault protected ansible variable, or an environment variable.
This would require you to code passing the variable into whatever you are doing in your lookup instead of letting something look for stdin during execution which isn’t ideal anyways with how ansible can run in multiple forks.
I’d just set it in the vault.Is there a reason you’re not? If this module is meant to be passed around and you’re looking for an easy way to share the module just state, it can be x variable or x env variable.
I want to provide a module option, but I don’t see any way to pass the module option to the open_url function.
I know the open_url function uses some form of SSL context, but I also don’t see a way to pass the pass phrase to the context.
I feel like there should be a way to do this, but I’m not seeing anything.
Is there just a default var that open_url always reads?
You’d have to do the key decryption in your module and pass the decrypted key to open_url.
The encryption of the key file in that format is for other uses. Ansible provides the ability to protect whole files or just variables at rest with ansible-vault. I’d advocate for storing your key file at rest protected by ansible-vault for use with Ansible. It’s protected just in a way you may not be familiar with.
There simply isn’t an option to provide a passphrase to decrypt a key within that function so we have to use other mechanisms that are available to us to accomplish a similar result.
Ok, so there’s no way to tell the functions related to open_url “this is the passphrase to use for client_key”?
If I wanted to use an encrypted key in the filesystem I need to create a custom function to decrypt the key and store it in a temp file, and then pass that to open_url?
I’m aware of ansible vault and how it works (high-level).
So you’re recommending instead of storing the encrypted key in the filesystem, store the unencrypted key as a variable in Ansible vault and let vault protect it?
Correct, there isn’t a way today to pass a passphrase into open_url.
I’d advocate to just use ansible-vault to encrypt the whole file. I’d have to try it to be certain but I expect ansible to recognize it’s been encrypted at rest with ansible-vault and use any available vault passwords to decrypt it. By encrypting the whole file your “-nodes” or “no des” key file (if using OpenSSL CLI tools) is then protected with AES encryption at rest.
As I start to dive into the thought of using ansible vault, I think I’ve found a potential security area that I’m trying to figure out how best to account:
If I store the file in ansible-vault, I have to generate a tmp file that is unencrypted to use it with open_url.
But if I do that, then I have an unencrypted private key in a tmp directory that is usually readable by all.
It looks like the flow of open_url is open_url → Request.open() → make_context → load_cert_chain()
SSL’s load_cert_chain() has an option for a password, but it’s not included there.
It looks like Request.open() does allow me to include a custom context.