Need help understanding how "cli_options" works


New to ansible and this project so forgive me if this seems like a dumb questions. I’m one of those guys that like to know how things work but I’m getting stuck figuring out how the users role creates users. Specifically this part

 - name: Check whether Ansible can connect as admin_user 
     local_action: command ansible {{ inventory_hostname }} -m ping -u {{ admin_user }} {{ cli_options | default('') }}

From what i can tell cli_options is a function and it’s then filtered through “default(’’)” which I’m guessing just filters the output of cli_option to a string.

My question is where does this cli_options come from and what does it do exactly?

Some context

The SSH user that will succeed for Ansible depends on the context, e.g.:

The remote-user role uses an updated version of the task you posted above to test whether root can connect, making all subsequent connections as the admin_user if root fails. This avoids requiring of Trellis users very much manual management of SSH user names.

Although the remote-user role described above does not create any users, the users role creates the following users on the remote, if they don’t already exist:

  • admin_user to run the server.yml playbook if root cannot connect. This user has full privileges on the server.
  • web_user to run the deploy.yml playbook. This user has privileges limited to managing website files, not the whole server.

The SSH keys docs provide a little more perspective on users.

Breaking down this task

The task you posted above is not a simple place to start understanding Ansible:

  • local_action indicates that the command should be run on the local machine instead of the remote server
  • command indicates that the following will be the command to execute
  • ansible begins an ad hoc command
  • inventory_hostname is an Ansible built-in variable indicating which remote should be accessed in the ad hoc command
  • -m ping indicates the Ansible ping module should be used to test the connection
  • [-u {{ admin_user }}] indicates to attempt the connection as the Trellis-defined variable admin_user. “But wait, you said the task tries to connect as root!” Well, it does now. The version you posted is out-of-date.
  • cli_options is a variable defined by Trellis behind the scenes. See explanation below.
  • | default('') sets the default value of an empty string '' if the cli_options variable is undefined, because without defaults set, Ansible playbooks fail when encountering undefined variables.

The task is complex because it has the unusual local_action thing. It is also unusual to use an ad hoc command. It also includes three different variable types: user-defined (common), magic or built-in (less common), and a Trellis var defined in an Ansible plugin (uncommon).

The cli_options variable

So finally, what is that cli_options variable?

If you run ansible-playbook -h you’ll see the many possible cli options that could affect the SSH connection. For example, suppose someone specified --private-key. The ping test in the task above would only be successful if also specifying this --private-key. So, cli_options is defined as the various cli options the user may have specified that could affect the SSH connection.

Note: the ancestor of cli_options was cli_options_ping, created in roots/trellis#578.

It’s cruel for me to save this gem for the end: I don’t think you’d ever need to think about or use the cli_options variable. :sweat_smile: