ansible / ansible

Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from code deployment to network configuration to cloud management, in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com.
https://www.ansible.com/
GNU General Public License v3.0
63.16k stars 23.93k forks source link

RFE: Provide password to foreman inventory plugin via environment variable #52672

Closed AlanCoding closed 5 years ago

AlanCoding commented 5 years ago
SUMMARY

Right now the foreman inventory plugin requires hard-coding your password into the inventory file to use, it would be more secure if another means of specifying via environment variable to added.

ISSUE TYPE
COMPONENT NAME

lib/ansible/plugins/inventory/foreman.py

ANSIBLE VERSION
ansible 2.8.0.dev0
  config file = None
  configured module search path = [u'/Users/alancoding/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/alancoding/Documents/repos/ansible/lib/ansible
  executable location = /Users/alancoding/.virtualenvs/ansible/bin/ansible
  python version = 2.7.11 (default, Oct 17 2016, 14:59:40) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)]
CONFIGURATION

default config

OS / ENVIRONMENT

local, plus cloudforms account

STEPS TO REPRODUCE

Use the foreman inventory plugin, see docs, inventory file looks like:

https://docs.ansible.com/ansible/latest/plugins/inventory/foreman.html

# my.foreman.yml
plugin: foreman
url: http://localhost:2222
user: ansible-tester  # required
password: secure  # required
validate_certs: False

Password is required and there is no alternative means of specifying it.

EXPECTED RESULTS

Most inventory plugins have some alternative means of specifying sensitive fields, take azure_rm for instance, it allows providing password via AZURE_PASSWORD

ACTUAL RESULTS

Mandating that the password is put in the inventory file means that it is forced to be written to disk unencrypted (vault doesn't work in inventory files like this AFAIK).

ansibot commented 5 years ago

Files identified in the description:

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

click here for bot help

bcoca commented 5 years ago

file and/or var can be vaulted, in any case, its easy to add env vars for any option, just add env: section in the docs

bcoca commented 5 years ago

diff --git a/lib/ansible/plugins/inventory/foreman.py b/lib/ansible/plugins/inventory/foreman.py
index db9beef846..5a72f612ca 100644
--- a/lib/ansible/plugins/inventory/foreman.py
+++ b/lib/ansible/plugins/inventory/foreman.py
@@ -31,6 +31,8 @@ DOCUMENTATION = '''
       password:
         description: foreman authentication password
         required: True
+        env:
+            - FOREMAN_PASSWORD
       validate_certs:
         description: verify SSL certificate if using https
         type: boolean```
AlanCoding commented 5 years ago

file and/or var can be vaulted, in any case

Example with aws_ec2...

ansible-vault encrypt_string <my specific access key> --ask-vault-pass

So I produce a file like:

plugin: aws_ec2
regions:
  - us-east-2
aws_access_key_id: <removed>
aws_secret_access_key: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          32313431626666633032306239353165363732653662306564656137313866633939383333323530
          6330366664643730633931623464666533306130643363330a373236666330666335393236656162
          39316232616465333666343738313165666431636435393431303165363837356330316138366539
          3362343361623738320a613138393066336666396566353862316431633732633630383839373866
          3635

Then run

ansible-inventory -i aws_ec2.yaml --list --export --ask-vault-pass -vvvvv

Produces:

ansible-inventory 2.8.0.dev0
  config file = None
  configured module search path = [u'/Users/alancoding/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/alancoding/Documents/repos/ansible/lib/ansible
  executable location = /Users/alancoding/.virtualenvs/ansible/bin/ansible-inventory
  python version = 2.7.11 (default, Oct 17 2016, 14:59:40) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)]
No config file found; using defaults
Vault password: 
setting up inventory plugins
host_list declined parsing /Users/alancoding/Documents/repos/ansible-inventory-file-examples/private/vault/aws_ec2.yaml as it did not pass it's verify_file() method
script declined parsing /Users/alancoding/Documents/repos/ansible-inventory-file-examples/private/vault/aws_ec2.yaml as it did not pass it's verify_file() method
toml declined parsing /Users/alancoding/Documents/repos/ansible-inventory-file-examples/private/vault/aws_ec2.yaml as it did not pass it's verify_file() method
 [WARNING]:  * Failed to parse /Users/alancoding/Documents/repos/ansible-inventory-file-examples/private/vault/aws_ec2.yaml with auto plugin: coercing to Unicode: need string or
buffer, AnsibleVaultEncryptedUnicode found

  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/inventory/manager.py", line 272, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/auto.py", line 55, in parse
    plugin.parse(inventory, loader, path, cache=cache)
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/aws_ec2.py", line 548, in parse
    results = self._query(regions, filters, strict_permissions)
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/aws_ec2.py", line 445, in _query
    return {'aws_ec2': self._get_instances_by_region(regions, filters, strict_permissions)}
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/aws_ec2.py", line 373, in _get_instances_by_region
    for connection, region in self._boto3_conn(regions):
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/aws_ec2.py", line 361, in _boto3_conn
    connection = self._get_connection(credentials, region)
  File "/Users/alancoding/Documents/repos/ansible/lib/ansible/plugins/inventory/aws_ec2.py", line 321, in _get_connection
    connection = boto3.session.Session(profile_name=self.boto_profile).client('ec2', region, **credentials)
  File "/Users/alancoding/.virtualenvs/ansible/lib/python2.7/site-packages/boto3/session.py", line 263, in client
    aws_session_token=aws_session_token, config=config)
  File "/Users/alancoding/.virtualenvs/ansible/lib/python2.7/site-packages/botocore/session.py", line 790, in create_client
    token=aws_session_token)
  File "/Users/alancoding/.virtualenvs/ansible/lib/python2.7/site-packages/botocore/credentials.py", line 248, in __init__
    self._normalize()
  File "/Users/alancoding/.virtualenvs/ansible/lib/python2.7/site-packages/botocore/credentials.py", line 258, in _normalize
    self.secret_key = botocore.compat.ensure_unicode(self.secret_key)
  File "/Users/alancoding/.virtualenvs/ansible/lib/python2.7/site-packages/botocore/compat.py", line 135, in ensure_unicode
    return unicode(s, encoding, errors)

Going about it via

ansible-vault aws_ec2.yaml --ask-vault-pass

does work, yes.

I did not have any expectation that using in-line encrypted values would work in inventory plugins, so I was not considered filing a bug for that.

In our case, we would like to show people the inventory file being used, so whole-file encryption doesn't help with that objective. However, this is only a nice-to-have feature. Likewise, it's nice to not write secrets to the disk, but we can, and will if necessary. So it's not a blocker.

Also, the foreman.py script required passwords in the config file, with no workaround either. So, not a regression either.

AlanCoding commented 5 years ago

Testing with that diff for adding env: and FOREMAN_PASSWORD, it does seem to work.

bcoca commented 5 years ago

Vault encrypted files work across the board, the inline encryption CAN work, but the plugin must be aware of it

AlanCoding commented 5 years ago

Closed with https://github.com/ansible/ansible/pull/52693