programmatically create sudo rules for running ansible-playbook - ansible

How could I create a list for all possible commands an ansible-playbook is using so that I could create a sudoers file?
For testing the playbooks, temporally I create an entry in the /etc/sudoers.d:
tempuser ALL=(ALL:ALL) NOPASSWD:ALL
But is there a plugin or way to get like the list of commands so that I could later create a list like
tempuser ALL= NOPASSWD: /bin/systemctl start mariadb.service
...
Any ideas?

If you intend to use privilege escalation with ansible then privilege escalation must be general
You cannot limit privilege escalation permissions to certain commands. Ansible does not always use a specific command to do something but runs modules (code) from a temporary file name which changes every time. If you have ‘/sbin/service’ or ‘/bin/chmod’ as the allowed commands this will fail with ansible as those paths won’t match with the temporary file that Ansible creates to run the module. If you have security rules that constrain your sudo/pbrun/doas environment to running specific command paths only, use Ansible from a special account that does not have this constraint, or use Red Hat Ansible Tower to manage indirect access to SSH credentials.
As demonstrated in the above documentation quote, this is a well known limitation of the tool. If this is a problem in your environment, either look at the above proposed workarounds in documentation quote, or don't use ansible at all.

Related

Ansible hide ansible_password

I am familiar with the solution of ansible-vault feature.
Our passwords are stored as a call to an external lookup (to be specific - Cyberark password).
However, a regular user can still with simple debug command to see them
ansible -m debug -a var=ansible_password <some host>
I am familiar with ansible feature known as "no_log". When you set this attribute on a task, or on a specific variable (in Ansible argument spec) - the output is hidden, even with high verbosity
Is there a way to set this attribute on ansible_password variable? so no one can print it?
The only other solution we came up with is to use vault, but all the cyberarcpassword lookup came up in order to "cut of" the vault feature...
You can set the password to expire or change in Cyberark after each call or execution. Why to worry about user seeing Cyberark's password? It may be useless after Ansible using it.

Ansible custom escalation

I'm trying to use ansible to automate a bunch of task that are done on multiple machines in one go.
My team does not manage the users and groups of the system, so a minimal or no setup in this front is highly appreciated.
Currently we are allowed to edit/create files with vi. Via a terminal we abuse this privilege by issuing sudo vi -c sh which will drop us in a sh shell as root. sudo will not work with any other executable.
I've consumed myself trying to abuse this in ansible but I'm figuring this is not possible out of the box.
Any idea how I could achieve this with minimal change/setup on the hosts?

"sudo ansible-playbook" command fails even with --user option

I've a user foo which is able to do passwordless ssh to A(self) and B. The playbook requires sudo access inside which I'm escalating with become and the below command is working fine.
ansible-playbook -i ../inventory.ini --user=foo --become --become-user=root echo_playbook.yml
But the above command is part of a shell script which doesn't have permission for foo. So when I use sudo to trigger that shell script, ansible is saying host unreachable. So I tried the ansible command with sudo as shown below and same. It showed host is unreachable.
sudo ansible-playbook -i ../inventory.ini --user=foo --become --become-user=root echo_playbook.yml
I agree that sudo is escalating the ansible-playbook to root. But I'm also providing the --user to tell ansible that "foo" user needs to be used for ssh.
Basically to access the playbook I need sudo. To connect to other servers I need foo user. To execute the actions inside the playbook (commands in playbook) I need sudo again (which I am using become for).
Am I doing anything wrong? Can anybody tell me the exact command for the ansible-playbook for the above scenario where ansible-playbook needs to run as sudo ansible-playbook?
I'm not entirely clear on exactly where you're stuck. I don't think you're confused between the remote user and the local user. If the playbook works as foo, and from what you describe, I can only guess that ~foo/.ssh/id_rsa or another automatically provided key authenticates foo. But you can generate a key for any user and allow it access to the remote foo if you'd prefer. Or, you can run the playbook as another user. It's up to you. The only thing that won't work is relying on the environment or configuration of particular users and then not providing it.
the above command is part of a shell script which doesn't have permission for foo.
What I'm hearing is that:
a user foo can successfully run ansible job
a script runs (under root?) that cannot run the ansible job
If you're happy with how ansible works for the foo user, you can switch to the foo user to run the ansible:
sudo -u foo ansible-playbook ...
If the script runs as root, sudo will always succeed. Otherwise, you can configure sudo to allow one user to access another for one command or more.

How to pass ansible vault password as an extra var?

I have the ability to encrypt variables using another mechanism(Azure pipeline secret feature), so I would like to save an ansible-vault password there(in Azure pipeline) and pass it to playbook execution as an extra var.
May I know if it can be done so?
An example of what/how I'm expecting is
ansible-playbook --extra-vars "vault-password=${pipelinevariable}"
Vault password cannot be passed as an extra var. There are several ways to provide it which are all covered in the documentation:
Providing vault password section in the general vault documentation.
Using vault in playbooks
Very basically your options are:
providing it interactively passing the --ask-vault-pass option
reading it from a file (static or executable) by either:
providing the --vault-password-file /path/to/vault option on the command line
setting the ANSIBLE_VAULT_PASSWORD_FILE environment variable (e.g. export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/vault).
There is much more to learn in the above doc, especially how to use several vault passwords with ids, how to use a client script to retrieve the password from a key store...
Although this doesn't use extra vars, I believe it fulfills what you were trying to do:
Optional/one-time only: ask for the password and set it as an environment variable:
read -s ansible_vault_pass && export ansible_vault_pass
Now use that variable in your ansible command:
ansible-playbook your-playbook.yml --vault-password-file <(cat <<<"$ansible_vault_pass")
Credits for, and explanation of the <(cat <<<"") technique are in this other StackOverflow answer: Forcing cURL to get a password from the environment.
May I know if it can be done so?
Not familiar with Ansible Vault, but you have at least two directions based on the documents shared by Zeitounator.
1.Use a CMD task first to create a vault-password-file with plain-text content. (Not sure if the vault-password-file can be created in this way, it might not work.)
(echo $(SecretVariableName)>xxx.txt)
Then you may use the newly created xxx.txt file as input of ansible-playbook --vault-password-file /path/to/my/xxx.txt xxx.yml.
2.Create a corresponding vault-password-file before running the pipeline, add it to version control. (Same source repo of your current pipeline)
Then you can use ansible-playbook --vault-password-file easily when the vault-password-file is available. Also you can store the password file in private github repo, fetch the repo via git clone https://{userName}:{userPassword}#github.com/xxx/{RepoName}.git, copy the needed password file to the directory where you run the ansible-playbook commands via Copy Files task. This direction should work no matter if direction 1 is supported.

Could i use ansible playbook(tgz,zip format ) like helm charts?

I want to use ansible to manage multi service deployment, each service have many roles. Now I want to package one service as a tgz or zip file(same as helm charts), and use one file to override variables when use ansible execute(like helm install xx.tgz --values values.yml)
I am new to ansible, and have checked ansible-playbook -h, but no find some related information
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
Runs Ansible playbooks, executing the defined tasks on the targeted hosts.
Options:
--ask-vault-pass ask for vault password
-C, --check don't make any changes; instead, try to predict some
of the changes that may occur
-D, --diff when changing (small) files and templates, show the
differences in those files; works great with --check
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with #
--flush-cache clear the fact cache for every host in inventory
--force-handlers run handlers even if a task fails
-f FORKS, --forks=FORKS
specify number of parallel processes to use
(default=5)
-h, --help show this help message and exit
-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
specify inventory host path or comma separated host
list. --inventory-file is deprecated
-l SUBSET, --limit=SUBSET
further limit selected hosts to an additional pattern
--list-hosts outputs a list of matching hosts; does not execute
anything else
--list-tags list all available tags
--list-tasks list all tasks that would be executed
-M MODULE_PATH, --module-path=MODULE_PATH
prepend colon-separated path(s) to module library (def
ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
gins/modules)
--skip-tags=SKIP_TAGS
only run plays and tasks whose tags do not match these
values
--start-at-task=START_AT_TASK
start the playbook at the task matching this name
--step one-step-at-a-time: confirm each task before running
--syntax-check perform a syntax check on the playbook, but do not
execute it
-t TAGS, --tags=TAGS only run plays and tasks tagged with these values
--vault-id=VAULT_IDS the vault identity to use
--vault-password-file=VAULT_PASSWORD_FILES
vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--version show program's version number, config file location,
configured module search path, module location,
executable location and exit
Connection Options:
control as whom and how to connect to hosts
-k, --ask-pass ask for connection password
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
use this file to authenticate the connection
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=None)
-c CONNECTION, --connection=CONNECTION
connection type to use (default=smart)
-T TIMEOUT, --timeout=TIMEOUT
override the connection timeout in seconds
(default=10)
--ssh-common-args=SSH_COMMON_ARGS
specify common arguments to pass to sftp/scp/ssh (e.g.
ProxyCommand)
--sftp-extra-args=SFTP_EXTRA_ARGS
specify extra arguments to pass to sftp only (e.g. -f,
-l)
--scp-extra-args=SCP_EXTRA_ARGS
specify extra arguments to pass to scp only (e.g. -l)
--ssh-extra-args=SSH_EXTRA_ARGS
specify extra arguments to pass to ssh only (e.g. -R)
Privilege Escalation Options:
control how and which user you become as on target hosts
-b, --become run operations with become (does not imply password
prompting)
--become-method=BECOME_METHOD
privilege escalation method to use (default=sudo), use
`ansible-doc -t become -l` to list valid choices.
--become-user=BECOME_USER
run operations as this user (default=root)
-K, --ask-become-pass
ask for privilege escalation password
version:ansible 2.8.0
You can't package playbooks as zip or tgz files. One option would be to use ansible-pull. It checks a repository out and runs a specified playbook: https://docs.ansible.com/ansible/latest/cli/ansible-pull.html

Resources