Skip to content

Latest commit

 

History

History
661 lines (546 loc) · 18.4 KB

EN.md

File metadata and controls

661 lines (546 loc) · 18.4 KB

Ansible RefCard

English version

RefCard for Ansible usage.

Written by Germain LEFEBVRE on December 2018 for Ansible v2.7 usage.

Update by Nicolas Mercier on April 2022 for Ansible v2.12 usage.

Table of Contents

  1. Context
  2. Upgrade your Ansible version
  3. Ansible Definitions
  4. Ansible Configuration
  5. Ansible AdHoc Commands
  6. Ansible Inventories
  7. Ansible Tasks
  8. Ansible Playbooks
  9. Ansible Variables
  10. Ansible Plays
  11. Ansible Roles
  12. Import de Playbooks, Tasks et Roles
  13. Ansible Options
  14. Ansible Modules
  15. Ansible Vault
  16. Ansible Galaxy
  17. Extension par utilisation

Context

This is the list of the packages version used to make this RefCard.

Operating System distribution and version:

cat /etc/redhat-release
Rocky Linux release 8.5 (Green Obsidian)

Python version:

python --version
Python 3.8.8

Ansible version:

ansible --version
ansible [core 2.12.1]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.8 (default, Nov  9 2021, 13:31:34) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
  jinja version = 3.0.3
  libyaml = True

Upgrade your Ansible version

Ansible give their Roadmap for v2.12 : https://docs.ansible.com/ansible/devel/roadmap/ROADMAP_2_12.html

Ansible provides porting guides to help you keeping up-to-date: Ansible Porting Guides

Ansible Definitions

Ansible Facts

The Facts are variables used by Ansible to persist data through hosts and executions. There are native facts are stored on local server (disk or in-memory) and user facts defined by Human actions. It is important to get that facts are stored by group of actions OR by host.

Ansible Hosts

The Hosts are just servers that the Ansible Server can reach trhough its preferred protocol.

Ansible Inventories

The Inventories are list of Hosts defined by FQDN and tidied in groups. Groups can be composed with hosts or group of hosts. Hosts can be aliased to make the list customisable.

Ansible Tasks

The Tasks are the actions launched on remote Hosts. Tasks are written in YAML langage in a descriptive structure way making the read and write uniform through any tasks in the world.

Ansible Variables

The Variables are the way for Ansible to pass custom values in tasks (and more over).

Ansible Playbooks

The Playbooks are the gathering of tasks and hosts. So a Playbook defines a list of tasks to perform on remote servers.

Ansible Roles

The Roles are the tidy way to write playbooks. It permits to store a group of actions with the same purpose and to call them in playbooks in a single line.

Ansible Handlers

Ansible Handlers are action triggers called from tasks and run at the end of a play. A Handler is a tasks defined by its name and called with its name.

Ansible Modules

Modules are scripts written in Python and making uniform actions possible in giving common inputs for users and generating outputs regarding the command played in the module.

Ansible Configuration

Configuration can be made and used in a file which will be searched for in the following order:

  • ansible.cfg (in the current directory)
  • ~/.ansible.cfg (in the home directory)
  • /etc/ansible/ansible.cfg

Ansible AdHoc Commands

AdHoc commands are commands launched on the fly with writting any complex structured files.

ansible localhost -m ping
ansible localhost -m setup
ansible localhost -m debug -a 'myVar'
ansible localhost -m shell -a 'uptime'
ansible all -i inventories/servers -m ping

Ansible Inventories

Ansible Inventories make possible to gather servers in a single file to run commands on all these hosts. Inventories are usually organized by environments (a file by env) to let the group_vars operate on tasks and roles.

Inventory definition:

server.domain.fr
server[01-09].domain.fr

rhel01 rhel01.domain.fr
deb01 deb01.domain.fr
arch01 arch01.domain.fr
win01 win01.domain.fr

[redhat]
rhel01

[debian]
deb01

[linux:children]
redhat
debian

[linux]
arch01

[windows]
win01

Ansible Tasks

A task is a YAML structure able to perform actions through Ansible.

Task definition :

- name: The task name to make things clearly
  become: yes
  become_method: sudo
  become_user: root
  check_mode: yes
  diff: no
  remote_user: ansible
  ignore_errors: True
  import_tasks: more_handlers
  include_tasks: other-tasks.yml
  notify: restart apache
  register: my_register
  changed_when: False
  failed_when: False
  vars:
    - myvar: toto
    myfiles:
      -  default.conf
  loop:
    - item1
    - ["item2", "item3"]
    - { name: "item4", description: "Desc Item 4" }
  when:
    - my_register is defined
    - ansible_distribution == "CentOS"
    - ansible_distribution_major_version == "7" 
  block:
    - name: Task to run in block
      ...
  rescue:
    - name: Task when block failed
  always:
    - name: Task always run before/after block

Ansible Playbooks

A playbook is used to apply tasks to inventory servers. It is a repeatable, reusable and simple multi-machine deployment and configuration management system.

Playbooks can:

  • declare the configurations

  • orchestrate the steps of any manual process ordered, on several sets of machines, in a defined order

  • launch tasks synchronously or asynchronously

Install package on RHEL servers

- hosts: [redhat]
  become: true
  tasks
  - yum:
      name: httpd
      state: installed

Run roles on Docker servers but Master

- hosts: docker,!docker-master
  become: true
  roles:
  - docker
  - kubernetes

Ansible Variables

Variable Definition

A Ansible variable is defined in group_vars, host_vars, role vars, CLI vars and is called in Jinja Templating way : {{ my_variable }}. You can call variables everywhere in Ansible (tasks, variables, template, ...)

Variable Typology

You can have 3 types of variables:

  • String
  • List
  • Dictionary

A variable is defined by a couple Key/Value where Key doesn't have any space and Value is a structure as defined above.

my_string: "value"
my_list: ["bob", "alice"]
my_dict:
    item1: value1
    item2: value2

Variable precedence

You can set Ansible variables in multiple places like group_vars, playbooks, roles, etc... but they are evaluated according to a precedence. Here is the order of precedence from least to greatest:

command line values
role defaults
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
inventory group_vars/*
playbook group_vars/*
inventory file or script host vars
inventory host_vars/*
playbook host_vars/*
host facts / cached set_facts
play vars
play vars_prompt
play vars_files
role vars (defined in role/vars/main.yml)
block vars (only for tasks in block)
task vars (only for the task)
include_vars
set_facts / registered vars
role (and include_role) params
include params
extra vars (always win precedence)

Ansible Plays

A sufficient list of attributes for Ansible Play when running a playbook:

- hosts: webservers
  accelerate: no
  accelerate_port: 5099
  ansible_connection: local
  any_errors_fatal: True
  become: yes
  become_method: su
  become_user: postgress
  become_flags: True
  debugger: on_failed
  gather_facts: no
  max_fail_percentage: 30
  order: sorted
  remote_user: root
  serial: 5
  strategy: debug
  vars:
    http_port: 80
  vars_files:
    - "vars.yml"
  vars_prompt:
    - name: "my_password2"
      prompt: "Enter password2"
      default: "secret"
      private: yes
      encrypt: "md5_crypt"
      confirm: yes
      salt: 1234
      salt_size: 8
  tags: 
    - stuff
  pre_tasks:
    - <task>
  roles:
    - common
    - common
      vars:
        port: 5000
      when: "bar == 'Baz'"
      tags : [one, two]
    - common
    - { role: common, port: 5000, when: "bar == 'Baz'", tags :[one, two] }
  tasks:
    - include: tasks.yaml
    - include: tasks.yaml
      when: day == 'Thursday'
      vars:
        foo: aaa 
        baz:
          - z
          - y
    - { include: tasks.yaml, foo: zzz, baz: [a,b]}
    - <task>
  post_tasks:
    - <task>

Ansible Roles

Structure of a role

Role directories strucutre:

roles/
└── my-role
    ├── defaults
    │   └── main.yml
    ├── files
    |   └── file
    ├── handlers
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    |   └── template.j2
    └── vars
        └── main.yml

These are what files refer to:

  • my-role/defaults/main.yml defines default variables for the role,
  • my-role/files/file file (without vars) to be copied,
  • my-role/handlers/main.yml defnies the handlers tasks,
  • my-role/tasks/main.yml is the main taskfile run thorugh the role,
  • my-role/templates/template.yml.j2 template (with vars) to be copied,
  • my-role/vars/main.yml defines the vars to override,

Role with simple task

- command: cat /etc/hosts

Role with file to copy

File at roles/example/files/my-file.sh and task at roles/example/tasks/main.yml.

- copy:
    src: my-file.sh
    dest: /tmp/my-file.sh

Role with template to generate

Template at roles/example/templates/my-template.sh.j2

#!/bin/bash
echo "{{ timezone }}"

Task at roles/example/tasks/main.yml

- template:
    src: my-template.sh.j2
    dest: /tmp/my-template.sh

Role with trigger to handler

Handler at roles/example/handlers/main.yml.

- name: Restart Apache
  systemd:
    name: httpd
    state: restart

Task at roles/example/tasks/main.yml.

- copy:
    src: httpd.conf
    dest: /etc/httpd/conf/httpd.conf
  notify: Restart Apache

Will run the handler Restart Apache if task copy state has changed.

Role with default variables

Default variables at roles/example/defaults/main.yml

apache_version: '2.4.2'

Task at roles/example/tasks/main.yml

- yum:
    name: httpd-{{ apache_version }}
    state: present

Including and importing playbooks, tasks and roles

Include playbook

Only import_playbook works for including a whole playbook in another one.

- import_playbook: install_apache.yml

Include tasks

Both import_task and include_task work.

- hosts: [redhat]
  tasks:
  - import_tasks: roles/example/tasks/main.yml
  - include_tasks: roles/example/tasks/main.yml

Include tasks filtering by tag

Only the import_tasks call allows to include tasks and filter them using Tags. Important: The include_tasks calls need to include the tags to be propagated, otherwise the tasks will not run.

Include a whole role

Both import_role and include_role can be used to call tasks from a role. This will include the whole role example.

- hosts: [redhat]
  tasks:
  - import_role:
      name: example

Include a taskfile from a role

Permit to load all variables inherant to the role. This will include the task install.ymlfrom the role example.

- hosts: [redhat]
  tasks:
  - include_role:
      name: example
      tasks_from: install

Include tasks but filter on tag in ansible-playbook command

Only import_role works for including a whole role in a playbook using tags on commands.

- hosts: [redhat]
  tasks:
  - import_role:
      name: example

Ansible Options

Ansible offre des possibilités plus avancées qui aident à la vérification, au débuggage et poussent sur le plan non destructif des exécutions.

Filter with Inventory

Option --limit or -l filters playbook runtime by server (host or alias), inventory groups and understand the exclusions.

ansible-playbook -i hosts.yml playbook.yml --limit 'linux,!debian'

Filter by Tag

Option --tag or -t filters playbook tasks on tags set through attribut tags: on Plays and Tasks. Exclusion is possible on Tag filter.

ansible-playbook -i host.yml playbook.yml --tags 'config,service,!reload'

Run in Dry-Run

Option --check runs playbook without applying any modification on server and reveals the state for every Task (ok, changed, failed). Dry-Run mode make verifications easy.

ansible-playbook -i host.yml playbook.yml --check

Dry-Run mode is not plenty compatible with shell module because no state is returned on running shell scripts or commands.

Mode Differences

Option --diff show differences between Ansible and Server sides and is closely linked to files (copy, template modules). Differences mode is a good way to see changes on servers.

ansible-playbook -i host.yml playbook.yml --diff

Ansible Modules

Location

Store your modules on :

  • Local side (current dir) : Create your Ansibel Module directly in your ansible rundir in a directory library,
  • Server side (all users) : Define the path with the attribute library in /etc/ansible/ansible.cfg.
library        = /usr/share/my_modules/

Instanciate your Module Class

class MyAnsibleModule(AnsibleModule):
    def __init__(self, *args, **kwargs):
        self._output = []
        self._facts = dict()
        super(MyAnsibleModule, self).__init__(*args, **kwargs)

    def process(self):
        [...]

Run your Class

if __name__ == '__main__':
  MyAnsibleModule().process()

Define your attributes

Define your module arguments.

MyAnsibleModule(
    argument_spec=dict(
        url=dict(type='str',
                 required=True),
        type=dict(type='str',
                  required=True,
                  choices=['indice', 'document']),
        state=dict(type='str',
                   choices=['present','absent'],
                   default='present')
    )
).process()

Call your module argument on processing.

def process(self):
    try:
        changed = False

        # Retrieve value for attribute 'url'
        param_url = self.params['url']

        self.exit_json(changed=changed, ansible_facts={}, output=self._output)
    except Exception as e:
        self.fail_json(msg=(e.message, self._output))

Use the Check Mode

Enable the check mode.

def main():
    MyAnsibleModule(
        supports_check_mode=True,
        [...]
    ).process()

Use the check mode in processing. Process to your action after checking check_mode statement.

def process(self):
    # Stop if check_mode is true before doing any action
    if self.check_mode:
        return True
    # Keep doing actions if check_mode is false

Ansible Vault

Vault Configuration

Ansible Vault Password configuration can be done in several ways:

  • Attribute vault_password_file in file ansible.cfg,
  • Env variable ANSIBLE_VAULT_PASSWORD_FILE,
  • Option --vault-password-file or --vault-id with password file in ansible command,
  • Option --ask-vault-pass with prompt in ansible command.

Vault File

You can secure whole files with vault in encrypting them.

ansible-vault create foo.yml
ansible-vault encrypt foo.yml

View and decrypt to clear file.

ansible-vault view foo.yml
ansible-vault encrypt foo.yml

Vault Variables

You can also only encrypt value in variables files.

ansible-vault encrypt_string --name 'mykey' 'mysecret'

Ansible with Vault

If you have provided a vault password in configuration file then you will keep using ansible as usual.

If not you will need to provide vault options to your ansible commands.

ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
ansible-playbook --vault-id dev@dfile-dev-password site.yml
ansible-playbook --vault-id prod@prompt site.yml

You can also provide multiple vault resolvers to roll on multiple environments. Example for Dev with password file and Prod with prompt.

ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml

Ansible Galaxy

Ansible Galaxy is a free site to search, download, rate and review all kinds of community-developed Ansible roles and can be a great way to start your automation projects. It can also be used to create the "skeleton" of a role.

ansible-galaxy init my_name_role

Extension by use

Ansible is first and foremost a deployment tool for standardizing server-side actions and centralizing the configuration of deployed applications.

Verifications

Ansible can, however, be used for a whole other use. The implementation of Dry-Run mode makes it possible to check the status of servers without making any changes. It becomes easy to use it as a verification tool in order to control any changes made on the servers.

Idempotency

Idempotence is the faculty of an action not to apply change when it is not necessary. The repeatability of the action must not be destructive (state changed) and must go back to its good configuration (state ok).

A playbook is idempotent when it no longer causes a changed state when passing through. Idempotence is said to be perfect when, at a time t, the actions are changing on the first launch and are no longer so on all the following ones.

Patterns and regular expressions

An Ansible template can refer to a single host, an IP address, an inventory group, a set of groups, or all hosts in your inventory. Patterns are very flexible: you can exclude or require subsets of hosts, use wildcards or regular expressions, etc. Ansible runs on all inventory hosts included in the template. We can also combine the different Models.

- limitation to one host
  . ansible -m [module] -a "[module options]" --limit "host1"
- limitation to multiple hosts or groups
  . ansible -m [module] -a "[module options]" --limit "host1,host2" or "group1,group2"
- Exclusion of a group
  . ansible -m [module] -a "[module options]" --limit "allgroup,!group2"