Use Towers role‑based access control as much as possible to delegate the
minimum level of privilege to those only required to run automation at their
level. At the same time, follow the practice of least privilege without
interfering with their day‑to‑day jobs.
Ansible Tower uses teams that have a similar concept of
groups to assign permissions, and you can assign permissions
to groups rather than individuals.
Ansible Tower supports connecting to external account sources
such as LDAP and SAML. This will eliminate a source of error
when working with permissions.
I've always found that the time‑consuming nature of maintaining users
in large organizations is certainly error prone and could potentially
be a security risk due to those errors.
You should practice least privilege and minimize access
to system administrative accounts.
The system administrator is a really powerful user that can access,
edit, and disrupt any system application. Always keep the number of
accounts with root access to as small a group as possible, and also to
have a detailed audit trail on this account.
Also, if the automation credentials are stored in Tower,
it can be further secured.
You can lock down access further as services such as
OpenSSH can be configured only to allow credentials on
connections from specific addresses.
Finally,
separation of duties. Different pieces of automation may need
to access a system at different levels.
For example,
you may have a low‑level system automation that applies patches to keep a
system at a baseline, or even just to perform security baseline check‑in. Then
there will be a higher‑level piece of automation that deploys complex
applications and more complex automation workflows.
So here you can use different keys or credentials for each piece of automation,
minimizing the effect of any one key vulnerability, while allowing
easy baseline auditing that needs to be done regularly by a less
experienced user. For task execution, Ansible uses batches
controlled by parameters called forks.
The default value is five,
which means Ansible executes a task on the first five hosts,
waits for the task to complete, and then takes the next batch of five hosts.
So the default of five is pretty conservative. Consider setting the forks
in a job template to larger values to increase the parallelism of
execution runs for large environments, and when the control host and
network infrastructure can support the load.
So gathering facts is an implicit task and may not be needed, if, for example,
you're not using any of those gathered facts in variables later in playbooks.
So in Ansible Tower, we have an Ansible Fact Cache plugin that can
store and retrieve facts on a per‑host basis.
This behavior is configured on a per‑job template basis.
There is also a global timeout setting that the plugin enforces
per host that could be specified in seconds.
So using fact caching saves a significant amount of time running fact
gathering over a large group of hosts. Let's say you have a playbook in
a job that runs against 1000 hosts, and then you have increased the
number of forks. With fact caching, the first run caches these facts for
jobs you run regularly,
and the next run will pull them from the fact database. This would save a
ton of time running jobs against large inventories,
including smart inventories.