Skip to content

Repository files navigation

ansible

General

  • Ansible is agentless; this means no agent neeeds to be installed on the target hosts; ssh access is just enough
  • Ansible will be run on a control node, which executes the remote tasks.
  • Target hosts are also called managed nodes
  • Plugins can be used to expand the capabilities of ansible.
  • Ansible content can be distributed and shared through Ansible Galaxy. Its like a marketplace.

Basic concepts

Inventory

  • A inventory is a list of managed nodes/hosts
  • All hosts should be added to the inventory.ini file (hostname or ip address).
  • The hosts can be grouped; the group name is inside brackets []
  • The inventory can be ether a .ini or a .yaml file
  • Its also possible to declare variables inside of the inventory file
  • Its possible to define ranges with [01:50]. It's also possible to skip some numbers with a stride [01:50:2] so every odd number gets used.
  • Alphabetical ranges are also possible
  • It's possible to configure ansible to escalate privileges after sshing into a host (so it has root privileges)

Verify inventory

ansible-inventory -i inventory.ini --list 

Source

Run default automation

ansible test -m ping -i inventory.yaml

Important parameters

Parameter Meaning
-u Defines the user to use for ssh into the servers
-i Specifies the inventory file to use
--check A sort of dry run; hosts configuration don't gets altered

Playbooks

  • A playbook is an automation blueprint

  • It consists of plays, tasks & modules

  • They have a hierarchy:

    • Playbook (List of plays)
      • Play (Ordered list of tasks)
        • Task (Reference to module for executing a task)
          • Module (The code that gets run)
  • A playbook is defined in a playbook.yaml-file

  • A playbook can be run with the ansible-playbook command

ansible-playbook -i inventory.yaml playbook.yaml
  • A play is a ordered list of tasks with the definition on how to run them (variables, etc.)
  • Each play consists of at minium the nodes to target and the tasks to execute
  • So this is a play
- name: Ping specified hosts
  hosts: test
  tasks:
    - name: Ping
      ansible.builtin.ping:
  • A task is an action inside of a play, which will be executed by a module

  • A module is simply the binary/code that gets run by a task

  • Most ansible modules check before execution if the desired state is already met, if this is the case, it won't do anything.

  • When you wan't to try a playbook without apply the changes to the system, you can pass the --check flag.

  • So ansible will only do a "dry run" of the playbook without altering the system configuration.

  • This is great for testing new playbooks before running in production.

  • With ansible-lint it's possible to check a playbook and get feedback about it.

  • Just run ansible-lint followed by the playbooks name

ansible-lint playbook.yaml

Playbooks intro

Templating

  • Its possible to use jinja2 templates to create dynamic expressions with data like ip address, hostname or environmental information
  • Templates get calculated on the control node and then will be sent, to the hosts. The hosts don't notice anything from the templating process.

Source

  • Jinja2 supports inline conditionals
"{{ 'wheel' if ansible_os_family == 'RedHat' else 'sudo' }}"

python - Jinja2 shorthand conditional - Stack Overflow

Filters

  • Filters are used to transform something into something for example json data to yaml data or generating a hash out of a string.
  • Those filter transformations are aswell (same as with templating) executed on the control node.
  • With filters its also possible to defined variables as mandatory or providing default values

Example for a default value

{{ some_variable | default(5) }}
  • Its also possible to set a default value if a boolean is false/true
  • By default ansible requires values for custom set variables. To decalre a variable as optional omit needs to be set as default value
{{ item.mode | default(omit) }}

To define a value as mandator, use mandatory

{{ variable | mandatory }}

Its also possible to define a hint/custom error message, if a required value in undefined

galaxy_api_key: "{{ undef(hint='You must specify your Galaxy API key') }}"
  • A overview of the possibilites is provided on the corresponding ansible docs page.

Source

Tests

  • It's possible to define tests/conditions for each tasks, which need to be fulfilled, so the task gets run
  • This can be also used for checking if some var is truthy

Example:

- debug:
    msg: "Truthy"
  when: value is truthy
  vars:
    value: "some string"
  • Maybe you want to run a task only on certain linux distributions/os families. Then you can use something like the following:
when: ansible_os_family == 'Debian'

Docs Conditionals

Fact gathering / Ansible Facts

  • When a playbook is run, ansible firstly gathers some information about the hosts, its running on
  • Those facts than can be accessed as variables with ansible_ prefix
  • This enables the possibility to only run some tasks on certain operating systems
  • Fact gathering can be disabled per play with gather_facts: false

Docs Guide to Ansible Facts and Fact Gathering Best way to run a playbook with different OS’s? : r/ansible

Debug module

  • For debug and developement purposes the debug module can be handy
  • It prints a speicifed message as console output
  • Its also useful to combine this with conditions via the when: directive
    - name: Print os family
      debug:
        msg: "{{ ansible_os_family }}"

Docs

Variables

Docs

Variable Prompts

  • Variables prompts enable you to ask the user before running the playbook to input some variables/values for the current execution
  • Those prompt variables can be defined with a list named vars_prompt, instead of the default vars
  vars_prompt:
    - name: api_key
      prompt: Enter the API key
  • This can be used for supplying sensitive information at runtime (like passwords) which weren't stored in Ansible Vault.

Source

Handy modules

Ad-hoc commands

  • Ad-hoc commands are an alternative way for running ansible commands
  • They are ideal for simple "one command" tasks which were rarely done (like rebooting some servers)
  • By default ansible uses the ansible.builtin.command module for ad-hoc commands
  • For example if you wan't to reboot a group of hosts, run:
ansible test -i inventory.yaml -a "/sbin/reboot"
  • With -m you can tell ansible to use another module
ansible test -m ansible.builtin.copy -a "src=/etc/hosts dest=/tmp/hosts"
  • So for quick command execution ad-hoc commands are ideal.
  • But for more complex stuff you should prefer the use of regular yaml playbooks

Ansible Galaxy

Show installed collections:

ansible-galaxy collection list

Ansible Vault

  • Ansible Vault is a tool to manage sensitive information within Ansible, so they don't need to be stored in plaintext
  • It's is possible to use one password for encrypting all secrets or use one password per secret
  • Each password has his own vault with an vault id. The vault id can be used to differentiate the passwords and where a secret is stored.
  • The --vault-id has to be passed to ansible like follows: --vault-id label@source
  • Ansible Vault can be used to encrypt variables and files
  • The encrypted content includes !vault to signalize that Ansible has to decrypt the content inside
  • The easiest way to use Ansible Vault is having an encrypted file which stores sensitive variables and then is encrypted via Ansible Vault.
  • Using encrypted variables inside a playbook don't differs from using a plaintext variable, so it doens't interrupt you from doing your work.

Encrypt variable (in-file-usage)

  • To encrypt a string on the fly, use the encrypt_string method
ansible-vault encrypt_string
  • You will be prompted to input your vault password and afterwards the plaintext content of the secret

  • Notice that you end the input with twice typing Ctrl + D and not with Enter!

  • Using Enter counts as linebreak inside your secret

  • Afterwards the encrypted string is shown in the console

  • From there you can copy and use it inside your playbooks

  • For decrypting to work right, you have to define them as variables

  vars:
    my_secret: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          ENCRYPTED-VALUE
  • To access the secret you have to pass the parameter --ask-vault-pass when running a playbook
  • Whilst runtime you then will be asked for your encryption key
  • Ansible Vault then will ensure the values get decrypted right

Creating/managing secrets (file-level)

  • Firstly create a file which contains sensitive information
my_secret: this-is-a-very-secret-information
  • Encrypt a file
ansible-vault encrypt <FILE>

Example:

ansible-vault encrypt vars.yaml
  • When you want to adjust/edit your secrets, you have two ways to accomplish this:

Decrypting the entire file and encrypting again afterwards

ansible-vault decrypt vars.yaml
  • Don't forget to encrypt again after editing the file

Opening the file inisde an text editor like vi or emacs

ansible-vault edit vars.yaml

Referencing a secret in a playbook

  • Referencing a vault item inside a playbook is done as with any other non-encrypted variable
    - name: Get secret
      debug:
        msg: "{{ my_secret }}"
  • While running the playbook you than have to pass the secrets file with -e
ansible-playbook -i inventory.yaml -e @vars.yaml --ask-vault-pass playbook.yaml
  • Alternatively to interactive passing the vault password (encryption key) to Ansible, you can use a password file, which contains the vault password
ansible-playbook -i inventory.yaml -e @vars.yaml --vault-password-file /path/to/password.file playbook.yaml 
  • Notice that this file should be locked down/protected, so that not everyone can access it.
  • The file shouldn't store the plaintext password on your disk, for obvious reasons
  • The --vault-password-file parameter can be combined/tied together with other secret management tools or the CLI of a password manager for providing the password on the fly

Docs Basic summary Practial usage

About

Collection of my ansible playbooks and notes

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages