Services Blog Français

Quick Ansible tutorial

| by jpic | cli ansible devops

ansible ad hoc command line

The ansible command line allows you to use a single Ansible module without writing a playbook. Useful for one-shot commands, it is also a great way to verify that Ansible can work on a given server and to test different CLI arguments that will work both with the ansible and the ansible-playbook commands.

Use the ansible command line with the ping module to verify that Ansible can work on a target server:

ansible --module-name ping --inventory 1.2.3.4, all

Arguments:

  • --module-name ping: Tell Ansible command line to run the ping Ansible module,
  • --inventory 1.2.3.4,: Tell Ansible command line to not use an inventory file but a single IP,
  • all: Tell Ansible command line to run the module on all hosts of the inventory.
⚠️ Warning:
Do not forget the comma after the ip address in the -i/--inventory command line argument, otherwise Ansible will believe the argument value is the , path to a file!

See more on Ansible Ad Hoc commands documentation

ansible-playbook command line

A playbook is a YAML data structure which contains at least one play, a play defines the context within which you may orchestrate group of tasks using parameterized module call.

- hosts: all
  tasks:
  - ping:

Which you can run with:

ansible-playbook -i 1.2.3.4, play.yaml

See Ansible playbooks introduction for more details.

Modules

Ansible provides an extremely rich module list that you can use, refer to Ansible documentation for the complete list of modules.

Basic YAML script (playbook) example using the file and the shell Ansible modules:

- hosts: all
  tasks:
  - file:
      path: /etc/old_file
      state: absent
  - shell: /some/command some cmd args

CLI equivalent of the first task:

ansible --module-name file --args 'path=/etc/old_file state=absent' -i 1.2.3.4, all

In the freeform argument example with the shell Ansible module, arguments must be passed from the args key of the task:

ansible --module-name shell --args '/some/command some cmd args' -i 1.2.3.4, all

Authentication

Ansible works over various protocols, SSH being the favorite one to pilot Linux servers, which you can configure on the fly with CLI with:

  • --user: SSH user name to use to connect to the server
  • --become: Ask Ansible to become root with sudo
  • --extra-vars: Declare extra runtime variables
  • --extra-vars 'ansible_ssh_pass=...': SSH password to connect with
  • --extra-vars 'ansible_sudo_pass=...': Password to use for sudo on the server
  • --ask-sudo-pass: same as above but interactive
  • --extra-vars 'ansible_ssh_common_args=-oStrictHostKeyChecking=no': Tell ansible to work without checking the SSH server host key

So, suppose we want to run a shell command with sudo after connecting on 1.2.3.4 as localadm with some password non-interactively we can use something like:

ansible --module-name shell --args '/some/command some cmd args' --user localadm --become --extra-vars 'ansible_ssh_pass=SomePassword*' --extra-vars 'ansible_sudo_pass=SomePassword*' --extra-vars 'ansible_ssh_common_args="-oStrictHostKeyChecking=no' -i 1.2.3.4, all

Or:

ansible -m shell -a '/some/command some cmd args' --user localadm --become -e 'ansible_ssh_pass=SomePassword*' -e 'ansible_sudo_pass=SomePassword*' -e 'ansible_ssh_common_args="-oStrictHostKeyChecking=no' -i 1.2.3.4, all

Variables and templating

Ansible uses Jinja2 for templating:

- hosts: all
  vars:
    your_var: /some/command some cmd args
  tasks:
  - file:
      path: /etc/old_file
      state: absent
  # note that we quote the string value here so that Jinja2 doesn't try to
  intercept the curly braces {}
  - shell: "{{ your_var }}"

Read more about Using variables with Ansible and Templating with Ansible

ansible-vault AES256 variable encryption

You can also encrypt variables.

Unless you are working on a test server with a default password, you probably want to have your secret passwords encrypted on the disk rather than written in a playbook or shell history log.

Create a secret variables file with AES256 password encryption:

ansible-vault create secrets.yaml

The above command openned an editor after prompting you for a password, write your secrets in YAML syntax as such:

ansible_ssh_pass: Aoeuidhtns*
ansible_sudo_pass: '{{ ansible_ssh_pass }}'

As you can see, we use Jinja template syntax for parameter expansion, to reuse a variable for example. It is rendered during Ansible runtime and supports the full set of Jinja features. See the Playbooks filters documentation for more details.

Anyway, it will be written on disk after AES256 encryption by the ansible-vault command and look somewhat like this in secrets.yaml:

$ANSIBLE_VAULT;1.1;AES256
30626463636663623531376137373635616539396435613432353434313233653466666234613764
65653435306633376266323932663363663766356333393438343035353436356566396363326536
61326530303736656536636132663064303432336366623166303166653835303332623738373765
3834

Which means you will have to use the ansible-vault edit and other ansible-vault commands to work with the decrypted content.

Now write a playbook play.yaml in clear text which includes your secrets.yaml file as such, equivalent to the above command line:

- hosts: localhost
  user: localadm
  become: true
  vars:
    ansible_ssh_common_args: '-oStrictHostKeyChecking=no'
  vars_files:
  - secrets.yaml
  tasks:
  - shell: /some/command some cmd args

However, Ansible will need the password to decrypt the vaulted variables, which you can pass with:

  • --ask-vault-password for an interactive password prompt
  • --vault-id /path/to/password to store password in a file

See more in Ansible Vault documentation

Roles

An Ansible role is a group of tasks.

Create one with the ansible-galaxy role init test_role

Edit the created test_role/tasks/main.yml file with the following contents

- shell: 'date > {{ path_variable }}'
- file:
    path: '{{ path_variable }}'
    state: absent

Then, include the test_role in a playbook with the roles list:

- hosts: all
  roles:
  - role: test_role
    path_variable: /example_path
  - role: test_role
    path_variable: /other_path_example

This playbook will execute the role tasks twice with different values for the path_variable.

Alternate syntax you might also see, with a vars: intermediary keyword, acheiving the same effect as without it:

- role: test_role
  vars:
    path_variable: /example_path

See Ansible roles documentation for more details.

Ansible Resources

They trust us

Contact

logo