User’s guide
Introduction
Ansible role: config_light
Requirements: ansible.posix , community.general
The role installs packages, creates and configures files and services. The handlers are created from user provided data. The control-flow will be determined by the user provided configuration data. Some attributes of the dictionaries determine which Ansible module will be used. This data-driven programming paradigm provides a flexible, and robust framework to apply basic Ansible modules. In the code, each Ansible module is used only once. This makes the implementation, upgrading, and testing of the modules simple and easy.
The user of this role is expected to master at least the following Ansible topics:
The supported OS (FreeBSD and Ubuntu) can use the role to install and configure arbitrary applications. Other Linux distributions, that support the used Ansible modules, should work with minimal changes. BSD*, Debian, and Red Hat ansible_os_family should work out of the box.
There are four imported tasks in the first part of the role to setup handlers, assemble, and check the configuration data:
tasks description tags enabled (default)
___________________________________________________________________________
setup create handlers cl_setup, always cl_setup=true
vars assemble configuration data cl_vars, always always
sanity check sanity cl_sanity, always cl_sanity=true
debug help debugging data cl_debug cl_debug=false
Then, there are four imported tasks to manage the infrastructure:
tasks description tags enabled (default)
___________________________________________________________________________
packages install packages cl_packages cl_install=true
states modify states of files cl_states always
files configure files cl_files always
services configure services cl_services always
packages: The Ansible modules
package
,apt
,yum
, andsnap
are used to install Linux packages. In FreeBSD, modulespkgng
andportinstall
are used to install FreeBSD packages and ports.states: The Ansible module
mount
is used to mount and unmount paths, and to configure fstab. The modulefile
is used to modify states of files.files: The Ansible modules
template
,copy
,replace
,patch
,lineinfile
,blockinfile
, andini_file
are used to configure files.services: The Ansible Module
service
is used to configure both Linux and BSD services.
See also
The directory contrib comprises examples on how to install and configure various applications and how to create handlers and templates. Some of them are commented Examples.
Hint
Feel free to share your feedback and report issues. The contributions to the project are welcome.
Installation
The most convenient way how to install an Ansible role is to use
Ansible Galaxy CLI ansible-galaxy
. The utility comes with the
standard Ansible package and provides the user with a simple interface
to the Ansible Galaxy’s services. For example, take a look at the
current status of the role
shell> ansible-galaxy role info vbotka.config_light
and install it
shell> ansible-galaxy role install vbotka.config_light
Install the collections community.general and ansible.posix if necessary
shell> ansible-galaxy collection install ansible.posix
shell> ansible-galaxy collection install community.general
Install yamllint
to use the default validation of the created
handlers and assembled data. See the variables cl_assemble_validate
and cl_handlers_validate in defaults/main.yml. Optionally, install
and configure ansible-lint.
Note
By default sanity checking of yamllint is disabled (cl_sanity_yamllint: false)
Hint
To install specific versions from various sources see Ansible Galaxy
Take a look at other roles
shell> ansible-galaxy search --author=vbotka
Playbook
Below is a simple playbook that calls this role (11) at a single host srv.example.com (2)
1shell> cat pb.yml
2- hosts: srv.example.com
3 gather_facts: true
4 connection: ssh
5 remote_user: admin
6 become: true
7 become_user: root
8 become_method: sudo
9
10 roles:
11 - vbotka.config_light
Note
gather_facts: true
(3) must be set to gather facts needed to evaluate OS-specific options of the role. For example, the variable ansible_os_family is needed to select the Ansible module to install packages.For details see Connection Plugins (4-5)
and Understanding Privilege Escalation (6-8)
Debug
To see additional information enable debug output in the configuration
cl_debug: true
, or set the extra variable in the command:
shell> ansible-playbook pb.yml -e cl_debug=true
Note
The debug output of this role is optimized for the yaml
callback plugin. Set this plugin, for example, in the
environment shell> export ANSIBLE_STDOUT_CALLBACK=yaml
.
Variables
The Default variables control the options of the role.
The most important are the variables that control the collection of
the configuration data. In each project, customize the files with the
configuration data stored in the directory cl_dird
See also
See vars.yml annotated source code
Note
The names of the dictionaries in the configuration files
cl_dird/*.d/*
are not used by the role and can be any arbitrary
strings that are valid names of Ansible variables. The names must
be unique in the particular section (files.d, packages.d, …).
Default variables
Default variables are stored in the directory defaults
.
Most of the variables are self-explaining. There are five very
important variables cl_handlers
, cl_packages
, cl_states
,
cl_services
, and cl_files
(26-30). These dictionaries, which
comprise the configuration data of handlers, packages, services, and
files, will be explained in details. By default, these dictionaries
are empty.
Best practice is to provide the data either in host_vars and
group_vars or as a files in the directories cl_handlersd_dir
,
cl_packagesd_dir
, cl_statesd_dir
, cl_servicesd_dir
, and
cl_filesd_dir
(37-41). Both methods can be applied at the same
time. The variables will be assembled and combined by the tasks
vars_handlers.yml
, vars_packages.yml
, vars_states.yml
,
vars_services.yml
, and vars_files.yml
. The assembled
dictionaries, customized for each host in the play, will be stored in
the host-specific files cl_packagesd
, cl_statesd
,
cl_servicesd
, and cl_filesd
(60-63). The variable
cl_handlers
is not host-specific because the handlers will be
created at the controller (localhost) only. Assembled dictionary
cl_handlers
will be stored in the file cl_handlersd
(59). Take
a look at the assembled data in the directory cl_dira
(58).
By default, the base of the directories is role_path
(36). The
user is expected to put the configuration data to a more suitable
directory, for example, to playbook_dir
directory.
1---
2# defaults for config_light
3
4cl_setup: true # Import tasks/setup.yml
5cl_install: true # Install packages or ports
6cl_debug: false # Print debug output
7cl_backup: false # Backup files
8cl_copyfile_delete: false # Delete dest then copy samples and defaults
9cl_template_delete: false # Delete dest then create from templates
10
11# Sanity
12cl_sanity: true # Import tasks/sanity.yml
13cl_sanity_quiet: true # Module assert, parameter quiet
14cl_sanity_collections: false # Test required collections
15cl_sanity_modules_pkg: true # Test modules in cl_packages are supported
16cl_sanity_yamllint: false # Test yamllint is installed
17
18# Supported
19cl_supported_linux_family: [Debian, RedHat]
20cl_supported_modules_pkg: [apt, package, pkgng, snap, yum]
21
22# Required collections
23cl_collections: [ansible.posix, community.general]
24
25# Combine assembled data with these variables
26cl_handlers: {}
27cl_packages: {}
28cl_services: {}
29cl_files: {}
30cl_states: {}
31
32# Assemble data from these directories
33# cl_dird_owner: root # no default
34# cl_dird_group: adm # no default
35cl_dird_dmode: '0775' # default very permissive, restrict if necessary
36cl_dird: "{{ role_path }}/files"
37cl_handlersd_dir: "{{ cl_dird }}/handlers.d"
38cl_packagesd_dir: "{{ cl_dird }}/packages.d"
39cl_servicesd_dir: "{{ cl_dird }}/services.d"
40cl_filesd_dir: "{{ cl_dird }}/files.d"
41cl_statesd_dir: "{{ cl_dird }}/states.d"
42
43# Lint
44cl_yamllint: yamllint
45cl_yamllint_rules:
46 extends: default
47 rules:
48 line-length:
49 level: warning
50cl_assemble_validate: "{{ cl_yamllint }} -d '{{ cl_yamllint_rules|to_json }}' %s"
51cl_handlers_validate: "{{ cl_yamllint }} -d '{{ cl_yamllint_rules|to_json }}' %s"
52
53# Assemble inventory_hostname data into these files
54# cl_dira_owner: root # no default
55# cl_dira_group: adm # no default
56cl_dira_dmode: '0775' # default very permissive, restrict if necessary
57cl_dira_fmode: '0664' # default very permissive, restrict if necessary
58cl_dira: "{{ cl_dird }}/assemble"
59cl_handlersd: "{{ cl_dira }}/handlersd" # localhost; not inventory_hostname specific
60cl_packagesd: "{{ cl_dira }}/packagesd.{{ inventory_hostname }}"
61cl_servicesd: "{{ cl_dira }}/servicesd.{{ inventory_hostname }}"
62cl_filesd: "{{ cl_dira }}/filesd.{{ inventory_hostname }}"
63cl_statesd: "{{ cl_dira }}/statesd.{{ inventory_hostname }}"
64cl_assemble_regexp: '^(.*)[^~]$' # Any string but terminated by ~
65# Delete packagesd, servicesd, filesd, and statesd before assembling
66cl_all_delete: false # Delete packagesd, servicesd, filesd, and statesd
67cl_packagesd_delete: false # Delete packagesd
68cl_servicesd_delete: false # Delete servicesd
69cl_filesd_delete: false # Delete filesd
70cl_statesd_delete: false # Delete statesd
71
72# Role handlers directory
73# cl_handlers_dir_owner: admin # no default
74# cl_handlers_dir_group: admin # no default
75# cl_handlers_dir_dmode: '0775' # no default
76# cl_handlers_main_mode: '0644' # no default
77cl_handlers_delete_all: false
78cl_handlers_delete: false
79cl_handlers_create: true
80cl_handlers_dir_become: false
81
82# Snap
83cl_snap_paths:
84 - /usr/local/sbin
85 - /usr/local/bin
86 - /usr/sbin
87 - /usr/bin
88 - /sbin
89 - /bin
90# - /snap/bin
91cl_snap_patterns:
92 - snap
93
94# States
95cl_states_unmount: [absent, unmounted]
96cl_states_mount: [present, mounted, remounted]
97cl_states_file: [absent, directory, file, hard, link, touch]
98
99# Files
100cl_files_collections:
101 copy: ansible.builtin
102 template: ansible.builtin
103 markers: ansible.builtin
104 create-backup: ansible.builtin
105 patch: ansible.posix
106 lineinfile: ansible.builtin
107 blockinfile: ansible.builtin
108 inifile: ansible.builtin
109 ucl: vbotka.freebsd
110 delete-backup: ansible.builtin
111cl_files_order: "{{ cl_files_collections|dict2items|
112 selectattr('value', 'in', ['ansible.builtin'] + cl_collections)|
113 map(attribute='key') }}"
114
115# OS common
116install_retries: 10
117install_delay: 5
118
119# FreeBSD
120freebsd_install_method: packages
121# freebsd_install_method: ports
122freebsd_use_packages: true
123cl_services_freebsd_rcconf_auto: false
124
125# EOF
126...
Warning
The defaults of the variables cl_dird_dmode (35), cl_dira_dmode (56) and cl_dira_fmode (57) to access the configuration data and the assembled dictionaries are very permissive. Restrict the permissions if these dictionaries might comprise classified data.
Configuration data
The configuration data describe the creation of handlers, installation of the packages or ports, and management of files and services. See the below sections on how to create the data for the Ansible modules that serve your use-case best. Review hints in the Examples.
Handlers
Synopsis
The dictionary cl_handlers comprises data to create handlers. The structure of the dictionary depends on the template that is used to create the files with the handlers. For example, the structure below can be used together with the template handlers-auto1.yml.j2.
Parameters
Parameter |
Type |
Comments |
---|---|---|
template |
string |
Template filename |
handlers |
list |
List of handlers dictionaries |
|
string |
Name of the handler |
|
string |
Ansible module in handler |
|
list |
Ansible module parameters |
|
list |
List of conditions |
Examples
FreeBSD handlers for Postfix
[contrib/postfix/conf-light/handlers.d/postfix-freebsd.yml]
1postfix_freebsd:
2 template: handlers-auto1.yml.j2
3 handlers:
4
5 - handler: enable and start postfix
6 module: service
7 params:
8 - 'name: postfix'
9 - 'state: started'
10 - 'enabled: true'
11
12 - handler: disable and stop postfix
13 module: service
14 params:
15 - 'name: postfix'
16 - 'state: stopped'
17 - 'enabled: false'
18
19 - handler: reload postfix
20 module: service
21 params:
22 - 'name: postfix'
23 - 'state: reloaded'
24 conditions:
25 - '- cl_service_postfix_enable|bool'
26
27 - handler: restart postfix
28 module: service
29 params:
30 - 'name: postfix'
31 - 'state: restarted'
32 conditions:
33 - '- cl_service_postfix_enable|bool'
34
35 - handler: postfix check
36 module: command
37 params:
38 - 'cmd: /usr/local/sbin/postfix check'
39
40 - handler: newaliases
41 module: command
42 params:
43 - 'cmd: /usr/bin/newaliases'
44
45# - handler: 'postmap smtp sasl passwords'
46# module: command
47# params:
48# - 'cmd: /usr/local/sbin/postmap {{ postfix_main_cf_smtp_sasl_password_maps }}'
49
50# - handler: 'postmap virtual aliases'
51# module: command
52# params:
53# - cmd: /usr/local/sbin/postmap {{ postfix_virtual }}'
Create the handlers
shell> ansible-playbook pb.yml -t cl_vars -e cl_setup=true
Take a look at the file with the handlers
shell> cat roles/vbotka.config_light/handlers/handlers-auto-postfix_freebsd.yml
1---
2# Ansible managed
3# Automatically generated file with handlers.
4
5- name: postfix_freebsd enable and start postfix
6 service:
7 name: postfix
8 state: started
9 enabled: true
10
11- name: postfix_freebsd disable and stop postfix
12 service:
13 name: postfix
14 state: stopped
15 enabled: false
16
17- name: postfix_freebsd reload postfix
18 service:
19 name: postfix
20 state: reloaded
21 when:
22 - cl_service_postfix_enable|bool
23
24- name: postfix_freebsd restart postfix
25 service:
26 name: postfix
27 state: restarted
28 when:
29 - cl_service_postfix_enable|bool
30
31- name: postfix_freebsd postfix check
32 command:
33 cmd: /usr/local/sbin/postfix check
34
35- name: postfix_freebsd newaliases
36 command:
37 cmd: /usr/bin/newaliases
38
39# EOF
The file is imported into the handlers/main.ym
shell> grep handlers-auto-postfix_freebsd.yml roles/vbotka.config_light/handlers/main.yml
- import_tasks: handlers-auto-postfix_freebsd.yml
See also
the template handlers-auto1.yml.j2
Note
The template handlers-auto1.yml.j2 is available in the role’s
directory templates
. The user is expected to create new
templates when needed. Feel free to change the structure of the
data and to create new templates that might fit the purpose
better. Feel free to contribute new templates and configuration
examples to the project.
Packages
Synopsis
The dictionary cl_packages comprises managed packages (Linux or BSD) or BSD ports.
FreeBSD
By default packages will be installed. If you want to install ports set
freebsd_install_method: ports
snap
By default snap packages won’t be installed or uninstalled if snap binary can’t be found in
cl_snap_paths
. If you want the role to fail when snap is missing set
cl_snap_missing_fatal: true
The variables cl_snap_missing_fatal, cl_snap_paths, cl_snap_patterns are declared in
defaults/main.yml
.
Parameters
Parameter |
Type |
Comments |
---|---|---|
name |
list |
List of packages or BSD ports |
module |
string |
Ansible module to manage packages.
choices: package, apt, yum, snap, pkgng
(default=package)
|
state |
string |
State of packages or BSD ports
(default=present)
|
. |
. |
<TBD: see tasks/packages.yml> |
Examples
FreeBSD install Postfix package or port
[contrib/postfix/conf-light/packages.d/postfix.yml]
1postfix:
2 module: pkgng
3 name:
4 - mail/postfix
Armbian package for Simple SMTP
[contrib/ssmtp/conf-light/packages.d/ssmtp.yml]
1ssmtp:
2 module: pkgng
3 name:
4 - mail/ssmtp
Ubuntu delete snap packages
[contrib/ubuntu-snap-disable/conf-light/packages.d/snap-deinstall.yml]
1snap_deinstall_list1:
2 module: snap
3 state: absent
4 name:
5 - chromium
6 - core
7 - core18
8 - gnome-3-28-1804
9 - gtk-common-themes
10 - simplenote
11 - tusk
12# - snapd
13#
14# msg: Ooops! Snap installation failed while executing 'sh -c "/usr/bin/snap remove chromium core
15# core18 gnome-3-28-1804 gtk-common-themes simplenote snapd tusk"', please examine logs and error
16# output for more details.
17# rc: 1
18# stderr: |-
19# error: cannot remove "chromium", "core", "core18", "gnome-3-28-1804",
20# "gtk-common-themes", "simplenote", "snapd", "tusk": snap "snapd" is not
21# removable: remove all other snaps first
Ubuntu purge snapd package
[contrib/ubuntu-snap-disable/conf-light/packages.d/snapd.yml]
1snap_deinstall_list2:
2 module: apt
3 state: absent
4 purge: true
5 name:
6 - snapd
See also
States
Synopsis
The dictionary cl_states comprises the states of the managed files. If mounted, the path is
unmounted when state is in the list cl_states_unmount
(default=absent)
cl_states_unmount: [absent, unmounted]
Then, the module file is applied if state is in the list cl_states_file
(default=file)
cl_states_file: [absent, directory, file, hard, link, touch]
In the end, the path is mounted if state is in the list cl_states_mount
(default=absent)
cl_states_mount: [present, mounted, remounted]
The variables cl_states_unmount, cl_states_mount, cl_states_file are declared in
defaults/main.yml
. Details of the parameters are described in the modules mount
and
file
.
Parameters
Parameter |
Type |
Comments |
---|---|---|
path |
string |
Path to file |
state |
string |
State of the file |
owner |
string |
Owner of the file |
group |
string |
Group of the file |
mode |
string |
Mode of the file |
… |
… |
<TBD: see tasks/states.yml> |
Examples
Ownership and permissions of the document root for Lighttpd
[contrib/lighttpd/conf-light/states.d/lighttpd-server-document-root.yml]
1lighttpd_server_document_root:
2 state: directory
3 path: "{{ cl_lighttpd_server_document_root }}"
4 owner: "{{ cl_lighttpd_server_username }}"
5 group: "{{ cl_lighttpd_server_groupname }}"
6 mode: '0750'
Delete snap directories
[contrib/ubuntu-snap-disable/conf-light/states.d/snap.yml]
1snap_root:
2 path: /snap
3 state: absent
4snap_var:
5 path: /var/snap
6 state: absent
7snap_lib_var:
8 path: /var/lib/snapd
9 state: absent
See also
See
shell> ansible-doc -t module mount
See
shell> ansible-doc -t module file
Services
Synopsis
The dictionary cl_services comprises managed services.
Parameters
Parameter |
Type |
Comments |
---|---|---|
name |
string |
Name of the service |
state |
string |
State of the service default: started |
enabled |
boolean |
Start on boot default: true |
Examples
FreeBSD services for Postfix and Sendmail
[contrib/postfix/conf-light/service.d/postfix.yml]
1postfix:
2 name: postfix
3 state: "{{ cl_service_postfix_state }}"
4 enabled: "{{ cl_service_postfix_enable }}"
[contrib/postfix/conf-light/service.d/sendmail.yml]
1sendmail:
2 name: sendmail
3 state: "{{ cl_service_sendmail_state }}"
4 enabled: "{{ cl_service_sendmail_enable }}"
See also
Files
The variable cl_files is a dictionary of the files that shall be managed by this role. It’s optional which Ansible module will be used to manage a file. More options can be applied at the same file. For example, it is possible to create a file by the Ansible module template and modify it by the module lineinfile later. Several options, listed in the default order, are available
copy: If the attribute copyfile is defined in the dictionary
template: If the attribute template is defined in the dictionary
create blockinfile markers: If the attribute markers is defined in the dictionary
patch: If the attribute patch is defined in the dictionary
lineinfile: If the attribute dict or lines is defined in the dictionary
blockinfile: If the attribute blocks is defined in the dictionary
ini_file: If the attribute ini is defined in the dictionary
The variable cl_files_order
controls the order of the execution. Multiple options, when present
in the dictionary of a file definition, will be applied in this order. In addition to the options,
listed above, there are create-backup
and delete-backup
tasks to backup files that was
changed if enabled by cl_backup
(default: false). By default, the backup files are created after
copy, template, and markers. Fit the order of the execution to your needs.
copy
Copy files.
Parameters for copyfile
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
copyfile |
dict |
copyfile parameters (see tasks/files-copy.yml) |
|
path |
string |
Path of the source file |
|
remote_src |
string |
Source file from remote |
|
force |
boolean |
If no, transfer if dest does not exist |
|
… |
… |
<TBD> |
|
owner |
string |
Owner of the file |
|
group |
string |
Group of the file |
|
mode |
string |
Mode of the file |
|
attributes |
string |
Attributes of the file |
|
validate |
string |
Command to validate file |
|
handlers |
list |
List of handlers |
Example of copyfile
Create the description of the file (2) and declare the variable for the dictionary (7)
[contrib/lighttpd_nagios/conf-light/files.d/lighttpd-modulesconf.yml]
1lighttpd-modulesconf:
2 path: /usr/local/etc/lighttpd/modules.conf
3 create: true
4 owner: root
5 group: wheel
6 mode: '0644'
7 copyfile: "{{ cl_lighttpd_modulesconf_copy }}"
8 markers: "{{ cl_lighttpd_modulesconf_markers }}"
9 lines: "{{ cl_lighttpd_modulesconf_lines }}"
10 blocks: "{{ cl_lighttpd_modulesconf_blocks }}"
11 handlers:
12 - configtest lighttpd
13 - reload lighttpd
Create the dictionary cl_lighttpd_modulesconf_copy
(69)
[contrib/lighttpd_nagios/cl-lighttpd.yml]
68# /usr/local/etc/lighttpd/modules.conf
69cl_lighttpd_modulesconf_copy:
70 path: /usr/local/etc/lighttpd/modules.conf.sample
71 remote_src: true
72 force: false
Then, the command
shell> ansible-playbook config-light.yml -t cl_files_copy
will copy sample file modules.conf.sample
to modules.conf
if
the destination does not exist.
See also
See files-copy.yml at GitHub
See files-copy.yml annotated source code
template
Create files from templates.
Parameters for template
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
template |
dict |
Template parameters (see files-templates.yml) |
|
path |
string |
Path of the source file |
|
force |
boolean |
If no, transfer if dest does not exist |
|
… |
… |
<TBD> |
|
owner |
string |
Owner of the file |
|
group |
string |
Group of the file |
|
mode |
string |
Mode of the file |
|
attributes |
string |
Attributes of the file |
|
validate |
string |
Command to validate file |
|
handlers |
list |
List of handlers |
Example of template
File /etc/mail/mailer.conf
for postfix
[contrib/postfix/conf-light/files.d/mailer-conf.yml]
1mailerconf:
2 path: /etc/mail/mailer.conf
3 template:
4 path: mailer.conf.j2
5 force: true
6 owner: root
7 group: wheel
8 mode: '0644'
See also
See files-template.yml how the files are modified or created by the Ansible module
template
See files-template.yml annotated source code
Note
There are couple of templates ready to be used in the directory
templates
. The user is expected to create new templates when
needed. Feel free to contribute new templates to the project.
blockinfile markers
Create markers for Ansible module blockinfile. Mark existing blocks that you want to configure.
Parameters for blockinfile markers
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
markers |
list |
List of dictionaries (see fn/mark-block.yml) |
|
regex1 |
string |
Regex of block’s beginning |
|
replace1 |
string |
Block’s beginning |
|
regex2 |
string |
Regex of block’s ending |
|
replace2 |
string |
Block’s ending |
Example of blockinfile markers
For example, in file /usr/local/etc/lighttpd/modules.conf
, create blockinfile markers in the
following block
1##
2
3server.modules = (
4 "mod_access",
5 # "mod_alias",
6 # "mod_auth",
7 # "mod_authn_file",
8 # "mod_evasive",
9 # "mod_setenv",
10 # "mod_usertrack",
11 # "mod_redirect",
12 # "mod_rewrite",
13 )
14
15##
Create the description of the file (2) and declare the variable for the list of the markers (8)
[contrib/lighttpd_nagios/conf-light/files.d/lighttpd-modulesconf.yml]
1lighttpd-modulesconf:
2 path: /usr/local/etc/lighttpd/modules.conf
3 create: true
4 owner: root
5 group: wheel
6 mode: '0644'
7 copyfile: "{{ cl_lighttpd_modulesconf_copy }}"
8 markers: "{{ cl_lighttpd_modulesconf_markers }}"
9 lines: "{{ cl_lighttpd_modulesconf_lines }}"
10 blocks: "{{ cl_lighttpd_modulesconf_blocks }}"
11 handlers:
12 - configtest lighttpd
13 - reload lighttpd
Create the list of the dictionaries cl_lighttpd_modulesconf_markers
(73)
[contrib/lighttpd_nagios/cl-lighttpd.yml]
68# /usr/local/etc/lighttpd/modules.conf
69cl_lighttpd_modulesconf_copy:
70 path: /usr/local/etc/lighttpd/modules.conf.sample
71 remote_src: true
72 force: false
73cl_lighttpd_modulesconf_markers:
74 - marker: server.modules
75 regex1: 'server.modules\s*=\s*\('
76 replace1: 'server.modules = ('
77 regex2: '\)'
78 replace2: ')'
Then, the command
shell> ansible-playbook config-light.yml -t cl_files_copy,cl_files_markers
will copy sample file modules.conf.sample
to modules.conf
and
will create blockinfile markers
1##
2
3# BEGIN ANSIBLE MANAGED BLOCK server.modules
4server.modules = (
5 "mod_access",
6# "mod_alias",
7# "mod_auth",
8# "mod_authn_file",
9# "mod_evasive",
10# "mod_setenv",
11# "mod_usertrack",
12# "mod_redirect",
13# "mod_rewrite",
14
15)
16# END ANSIBLE MANAGED BLOCK server.modules
17
18##
See also
patch
Patch files.
Parameters for patch
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file to be patched |
|
patch |
dict |
Parameters of patch module (see files-patch.yml) |
|
src |
string |
Path of the patch file |
|
basedir |
path |
Apply patch in this dir |
|
… |
… |
<TBD> |
|
handlers |
list |
List of handlers |
Example of patch
File /etc/network.subr
for /etc/rc.d/wpa_cli
[contrib/freebsd-custom-image-wpacli/conf-light/files.d/network_subr.yml]
1network_subr:
2 path: "{{ bsd_cimage_mount_path }}/etc/network.subr"
3 patch:
4 src: "{{ playbook_dir }}/files/network.subr.patch"
5 basedir: "{{ bsd_cimage_mount_path }}/etc"
See also
See files-patch.yml annotated source code
See details about the example in the role vbotka.freebsd_wpa_cli
lineinfile
Create or configure lines in a file.
Parameters for lineinfile
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
lines |
list |
lineinfile params. Either dict or lines is required. |
|
regexp |
string |
Regular expression |
|
line |
string |
Line |
|
backrefs |
|||
state |
|||
firstmatch |
|||
insertafter |
|||
insertbefore |
|||
… |
… |
<TBD> |
|
assignment |
string |
Assignment of key and value in dict |
|
dict |
list |
lineinfile params. Either dict or lines is required. (see files-lineinfile.yml) |
|
key |
string |
Key value for regexp |
|
value |
string |
Value for line |
|
firstmatch |
|||
insertafter |
|||
insertbefore |
|||
… |
… |
<TBD> |
|
owner |
string |
Owner of the file |
|
group |
string |
Group of the file |
|
mode |
string |
Mode of the file |
|
attributes |
string |
Attributes of the file |
|
other |
string |
Attributes of module file |
|
create |
boolean |
Create file |
|
validate |
string |
Command to validate file |
|
handlers |
list |
List of handlers |
Example of lineinfile with lines
File /usr/local/etc/dma/dma.conf
for DragonFly Mail Agent
[contrib/dma/conf-light/files.d/dma-dmaconf.yml]
1dma_dmaconf:
2 path: /usr/local/etc/dma/dma.conf
3 create: true
4 owner: root
5 group: mail
6 mode: '0644'
7 lines: "{{ cl_dma_dmaconf_lines }}"
[contrib/dma/host_vars/srv.example.com/config-light-dma.yml]
20cl_dma_dmaconf_lines:
21 - {regexp: '^SMARTHOST\s*(.*)$', line: 'SMARTHOST {{ cl_dma_smarthost }}'}
22 - {regexp: '^PORT\s*(.*)$', line: 'PORT {{ cl_dma_port }}'}
23 - {regexp: '^AUTHPATH\s*(.*)$', line: 'AUTHPATH {{ cl_dma_authpath }}'}
24 - {regexp: '^ALIASES\s*(.*)$', line: 'ALIASES {{ cl_dma_aliasespath }}'}
25 - {regexp: '^SECURETRANSFER\s*(.*)$', line: 'SECURETRANSFER'}
26 - {regexp: '^STARTTLS\s*(.*)$', line: 'STARTTLS'}
27 - {regexp: '^MASQUERADE\s*(.*)$', line: 'MASQUERADE {{ cl_dma_masquerade }}'}
Example of lineinfile with dict
File /usr/local/etc/lighttpd/lighttpd.conf
for lighttpd
[contrib/lighttpd/conf-light/files.d/lighttpd-lighttpdconf.yml]
1lighttpd-lighttpdconf:
2 path: /usr/local/etc/lighttpd/lighttpd.conf
3 create: true
4 owner: root
5 group: wheel
6 mode: '0644'
7 assignment: ' = '
8 dict: "{{ cl_lighttpd_lighttpdconf_dict }}"
9 handlers:
10 - reload lighttpd
[contrib/lighttpd/host_vars/srv.example.com/cl-lighttpd.yml]
10cl_lighttpd_lighttpdconf_dict:
11 - {key: server.port, value: '"{{ cl_lighttpd_server_port }}"'}
12 - {key: server.use-ipv6, value: '"{{ cl_lighttpd_server_useipv6 }}"'}
13 - {key: server.username, value: '"{{ cl_lighttpd_server_username }}"'}
14 - {key: server.groupname, value: '"{{ cl_lighttpd_server_groupname }}"'}
15 - {key: server.document-root, value: '"{{ cl_lighttpd_server_document_root }}"'}
See also
See files-lineinfile.yml at GitHub how the files are modified or created by the Ansible module
lineinfile
See files-lineinfile.yml annotated source code
blockinfile
Create or configure blocks in files.
Parameters for blockinfile
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
blocks |
list |
List of dictionaries (see files-blockinfile.yml) |
|
marker |
string |
Label of the marker |
|
block |
string |
Text between markers |
|
… |
… |
<TBD> |
|
owner |
string |
Owner of the file |
|
group |
string |
Group of the file |
|
mode |
string |
Mode of the file |
|
create |
boolean |
Create if does not exist |
|
validate |
string |
Command to validate file |
|
handlers |
list |
List of handlers |
Example of blockinfileinfile
Create the description of the file (2) and declare the list of the blocks (10)
[contrib/lighttpd_nagios/conf-light/files.d/lighttpd-modulesconf.yml]
1lighttpd-modulesconf:
2 path: /usr/local/etc/lighttpd/modules.conf
3 create: true
4 owner: root
5 group: wheel
6 mode: '0644'
7 copyfile: "{{ cl_lighttpd_modulesconf_copy }}"
8 markers: "{{ cl_lighttpd_modulesconf_markers }}"
9 lines: "{{ cl_lighttpd_modulesconf_lines }}"
10 blocks: "{{ cl_lighttpd_modulesconf_blocks }}"
11 handlers:
12 - configtest lighttpd
13 - reload lighttpd
Create the list of the blocks cl_lighttpd_modulesconf_blocks
(89)
[contrib/lighttpd_nagios/cl-lighttpd.yml]
84cl_lighttpd_modulesconf_server_modules:
85 - mod_access
86 - mod_alias
87 - mod_auth
88 - mod_setenv
89cl_lighttpd_modulesconf_blocks:
90 - marker: server.modules
91 block: |
92 server.modules = (
93 {% for module in cl_lighttpd_modulesconf_server_modules %}
94 "{{ module }}",
95 {% endfor %}
96 )
Then, the command
shell> ansible-playbook config-light.yml -t cl_files_blockinfile
will create this block in modules.conf
1##
2
3# BEGIN ANSIBLE MANAGED BLOCK server.modules
4server.modules = (
5 "mod_access",
6 "mod_alias",
7 "mod_auth",
8 "mod_setenv",
9)
10# END ANSIBLE MANAGED BLOCK server.modules
11
12##
See also
See files-blockinfile.yml annotated source code
ini_file
Create or configure ini entries in a file.
Parameters for ini_file
Parameter |
Type |
Comments |
|
---|---|---|---|
path |
string |
Path to file |
|
ini |
list |
ini_file parameters list of dictionaries (see files-inifile.yml) |
|
section |
string |
Section name in INI file |
|
option |
string |
Name of the option |
|
value |
string |
Value of the option |
|
state |
string |
If absent the option or section will be removed |
|
allow_no_value |
boolean |
Allow option without value |
|
no_extra_spaces |
boolean |
Do not insert spaces |
|
… |
… |
<TBD> |
|
owner |
string |
Owner of the file |
|
group |
string |
Group of the file |
|
mode |
string |
Mode of the file |
|
attributes |
string |
Attributes of the file |
|
create |
boolean |
Create file |
|
handlers |
list |
List of handlers |
Example of ini_file
<TODO: No example yet>
See also
See files-inifile.yml annotated source code
community.general ini_file.py
Note
Quoting Multiple options with the same name exist #273 “There is no “The INI format”, there are many different interpretations out there what valid INI formats should be …”
Best practice
Check syntax
Check syntax of the playbook
shell> ansible-playbook pb.yml --syntax-check
Validation
Install yamllint
to use the default validation of the created
handlers and assembled data. See the variables cl_assemble_validate
and cl_handlers_validate in defaults/main.yml. Optionally, use
other linter, for example, ansible-lint and change the
variables. You can disable the validation by clearing the variables
cl_assemble_validate: ''
cl_handlers_validate: ''
Setup
Assemble data, create handlers, check sanity, and display
variables. When you take a look at tasks/main.yml
you’ll see that
the first three groups of the tasks (setup, vars, and sanity) are
tagged always
. As a result, when you apply the tag cl_debug all
three groups of the tasks will be executed before cl_debug
shell> ansible-playbook pb.yml -t cl_debug -e cl_setup=true -e cl_sanity=true -e cl_debug=true
Manage packages
Dry-run the management of packages
shell> ansible-playbook pb.yml -t cl_packages -e cl_install=true -CD
Manage packages
shell> ansible-playbook pb.yml -t cl_packages -e cl_install=true
Then disable the installation cl_install=false
to speedup the playbook.
Manage states of files
Dry-run the management of files’ states
shell> ansible-playbook pb.yml -t cl_states -CD
Set the states (existence and attributes) of the files
shell> ansible-playbook pb.yml -t cl_states
Manage configuration files
Dry-run the configuration of files
shell> ansible-playbook pb.yml -t cl_files -CD
Create and modify files
shell> ansible-playbook pb.yml -t cl_files
Manage services
Dry-run the configuration of services
shell> ansible-playbook pb.yml -t cl_services -CD
Configure services
shell> ansible-playbook pb.yml -t cl_services
Hint
If you know what you are doing skip the above selection of particular tags and run the complete role at once
shell> ansible-playbook pb.yml -e cl_setup=true -e cl_install=true
Idempotency
The role and the configuration data in the examples are idempotent. When the application is installed and configured there should be no changes reported by ansible-playbook when running the playbook repeatedly. Disable setup, sanity, debug, and install to speedup the execution when running the playbook periodically to audit the configuration
shell> ansible-playbook pb.yml -e cl_setup=false \
-e cl_sanity=false \
-e cl_debug=false \
-e cl_install=false