Contents
- 1 Basic
- 1.1 Define environment variables
- 1.2 Save the output in a variable
- 1.3 Read configs from a yml file
- 1.4 Not mark the task as changed
- 1.5 Perform an action based on the host name
- 1.6 Iterate over a loop
- 1.7 Trigger a handler when a task is performed
- 1.8 Separate pre-condition, main tasks and post-conditions
- 1.9 Wait for tasks to complete on other hosts
- 1.10 Load tasks from another file
- 1.11 Run as a privileged user
- 1.12 Run the same scripts on different ports or by different users
- 1.13 Configure max time to connect to a host
- 1.14 Conditionals
- 1.15 Multi-line debug
- 2 Common tasks
- 3 Service management
- 4 Application management
- 5 User management
Basic
Define environment variables
hosts: REPLACE_HOST_ALIAS environment: REPLACE_VAR_NAME_1: "REPLACE_VAR_VALUE_1" REPLACE_VAR_NAME_2: "{{ ansible_env.PATH }}:REPLACE_RELATIVE_PATH" sample_value_map: - {name: "name 1", description:"description 1", field1: "...", ...} - {name: "name 2", description:"description 2", field1: "...", ...} ...
Save the output in a variable
- name: REPLACE_TASK_NAME register: variable_name
Read configs from a yml file
- name: Load the configuration file include_vars: file: "{{ configuration_file }}" name: my_vars ... - name: REPLACE_TASK_NAME # Replace action using the var e.g. my_vars[x].z
Not mark the task as changed
For read-only commands that are not changing anything on the host. E.g. check if services are up after an upgrade
- name: REPLACE_TASK_NAME changed_when: False
Perform an action based on the host name
- name: REPLACE_TASK_NAME when: REPLACE_CONDITION # Example: "'host_prefix' in inventory_hostname
Iterate over a loop
- name: REPLACE_TASK_NAME # Replace action using{{ item }}" with_items: [item_A,item_B...]
Alternatively:
- name: REPLACE_TASK_NAME # Replace action using{{ item }}" with_items: - item_A - item_B ...
Trigger a handler when a task is performed
E.g. to restart a service after updating some config files
tasks: - name: Write the apache config file ... notify: - REPLACE_HANDLER_NAME
handlers: - name: REPLACE_HANDLER_NAME ...
Separate pre-condition, main tasks and post-conditions
pre_tasks: ... tasks: ... post_tasks: ...
Wait for tasks to complete on other hosts
tasks: - name: Phase 1 block: - name: task phase 1 - name: Phase 2 block: - name: task phase 2 ...
Load tasks from another file
To simplify complex scripts without using roles:
- name: REPLACE_TASK_NAME include_tasks: file: REPLACE_RELATIVE_PATH
Run as a privileged user
become: yes become_method: su become_user: REPLACE_USER
Run the same scripts on different ports or by different users
[REPLACE_HOST_ALIAS] REPLACE_DNS_1 ansible_port=REPLACE_PORT_1 ansible_user=REPLACE_USERNAME_1 REPLACE_DNS_2 ansible_port=REPLACE_PORT_2 ansible_user=REPLACE_USERNAME_2 ...
Configure max time to connect to a host
Add this parameter to the SSH connection:
-o ServerAliveInterval=NumberOfSeconds
Conditionals
For example if we have different paths on modern and legacy hosts:
"{% if var_name == 'xxx' %}'value 1'{% else %}'value 2'{% endif %}"
Multi-line debug
- name: REPLACE_TASK_NAME debug: msg: - "Debug line 1" - "Debug line 2" ...
Common tasks
Check if a file exists
- name: REPLACE_TASK_NAME stat: path: "{{ PATH_VARIABLE_NAME }}" check_mode: no register: file_stat failed_when: not file_stat.stat.exists
Check if a file’s content matches the expected content
- name: REPLACE_TASK_NAME src: PATH_FILE_EXPECTED_CONTENT dest: PATH_FILE_IN_HOST backup: yes
Create a folder
- name: Create a folder file: path: REPLACE_PATH state: directory
Upload a file
- name: Copy a file to a folder
copy:
src: REPLACE_LOCAL_PATH
dest: REPLACE_DESTINATION_PATH
Delete a file
- name: Delete a file file
path: REPLACE_FILE_PATH
state: absent
Uncompress a file
- name: Uncompress a file unarchive: src: REPLACE_FILE_PATH dest: REPLACE_DESTINATION_FOLDER remote_src: yes # so it looks for it on the host
Set a symbolic link
- name: REPLACE_TASK_NAME file: src: "REPLACE_TARGET_PATH" dest: "REPLACE_LINK_PATH" state: link force: true
Check an endpoint is working and returning the expected content
- name: REPLACE_TASK_NAME url: "REPLACE_ENDPOINT" return_content: yes register: response until: 'REPLACE_EXPECTED_CONTENT_IN_RESPONSE in response.content' retries: REPLACE_MAX_NUMBER_RETRIES delay: REPLACE_DELAY_TIME
Download a repository from Git
- name: REPLACE_TASK_NAME git: repo: REPLACE_CLONE_URL dest: REPLACE_DESTINATION_PATH clone: yes update: yes
Service management
Check a service is started and enabled on boot
- name: REPLACE_TASK_NAME service: name: REPLACE_SERVICE_NAME state: started enabled: yes
Restart a service
- name: REPLACE_TASK_NAME service: name: REPLACE_SERVICE_NAME state: restarted
Application management
Check if some applications have been installed with yum
- name: REPLACE_TASK_NAME name: REPLACE_APP_NAMES_SEPARATED_COMMAS state: present
Check if we are using the latest version of an app installed with yum
- name: REPLACE_TASK_NAME ansible.builtin.yum: name: REPLACE_APP_NAME state: latest
Check if an application has been installed with pip
- name: REPLACE_TASK_NAME name: REPLACE_APP_NAME state: present
User management
Create a list of user groups
- name: REPLACE_TASK_NAME group: name: "{{ item }}" loop: - REPLACE_GROUP_NAME_1 - REPLACE_GROUP_NAME_2 - ...
Create a list of users
- name: REPLACE_TASK_NAME user: name: "{{ item.name }}" group: "{{ item.group }}" groups: "{{ item.groups }}" uid: "{{ item.uid }}" state: "{{ item.state }}" loop: - { name: 'REPLACE', group: 'REPLACE', groups: 'REPLACE', uid: 'REPLACE', state: 'present' } - ...
To update a list of users and delete one, simply replace “present” by absent