Zimbra Distribution Lists with Ansible
Unfortunately there is no Zimbra module for Ansible but with the zmprov
command it’s still possible to do some Ansible magic.
Users
A list of users for the distribution lists.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
users:
### BEHAVIOUR
- name: john
first_name: 'john'
last_name: 'doe'
department: 'it'
- name: jane
first_name: 'jane'
last_name: 'doe'
department: 'it'
- name: janie
first_name: 'janie'
last_name: 'doe'
department: 'hardware'
# this user won't go into the dl
- name: johnny
enabled: false
first_name: 'johnny'
last_name: 'doe'
department: 'hardware'
Zimbra Distribution Lists
Every department (it,hardware) gets a distribution list with the members.
There will be also a all dl where all users are going in.
The selectattr('enabled', 'undefined')
will filter out disabled users.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
zimbra_dl:
# put all users in the "all" dl
- name: all
description: 'all employees'
members:
- "{{ users | selectattr('enabled', 'undefined') | map(attribute='name') | list }}"
# it
- name: it
description: 'it department'
members:
- "{{ users | selectattr('enabled', 'undefined') | selectattr('department', 'equalto', 'it') | map(attribute='name') | list }}"
mail_alias:
- 'root@example.com'
# hardware
- name: it
description: 'it department'
members:
- "{{ users | selectattr('enabled', 'undefined') | selectattr('department', 'equalto', 'hardware') | map(attribute='name') | list }}"
Ansible task
This looks a little bit messy but not all zmprov
commands are consistent with the output format and their parameters.
Tasks are doing following:
- Get all Distribution Lists
- Create if not present
- Get config of the lists
- Configure initial settings
- Add members
- An optional array of mail aliases
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
---
- block:
### DISTRIBUTION LISTS (non-dynamic)
- name: get all distribution lists
command: "./zmprov gadl"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
register: dl_result
changed_when: false
- name: create distribution lists
command: "./zmprov cdl {{ item.name }}@{{ item.domain | default('example.com') }}"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
with_items: "{{ zimbra_dl | default([]) | flatten }}"
when: "'{{ item.name }}@{{ item.domain | default('example.com') }}' not in dl_result.stdout_lines"
# optional to make the output less verbose
loop_control:
label: "{{ item.name }}"
- name: get distribution lists config
command: "./zmprov gdl {{ item.name }}@{{ item.domain | default('example.com') }}"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
with_items: "{{ zimbra_dl | default([]) }}"
register: dl_config_result
changed_when: false
loop_control:
label: "{{ item.name }}"
- name: configure distribution lists
command: >
./zmprov mdl "{{ item.item.name }}"@"{{ item.item.domain | default('example.com') }}"
displayName "{{ item.item.description }}"
zimbraDistributionListSubscriptionPolicy "{{ item.item.subscription_policy | default('reject') | upper }}"
zimbraDistributionListUnsubscriptionPolicy "{{ item.item.unsubscription_policy | default('reject') | upper }}"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
with_items: "{{ dl_config_result.results }}"
when: item.item.description not in item.stdout
loop_control:
label: "{{ item.item.name }}"
- name: configure distribution list members
command: "./zmprov adlm {{ item.item.name }}@{{ item.item.domain | default('example.com') }} {{ item.item.members | flatten | join('@example.com ') ~ '@' ~ 'example.com' }}"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
with_items: "{{ dl_config_result.results }}"
when: item.item.members | flatten | map('regex_replace', '$', '@example.com') | list | sort | join('\n') not in item.stdout
loop_control:
label: "{{ item.item.name }}"
### ALIAS
- name: configue distribution lists alias
command: "./zmprov adla {{ item.0.item.name }}@{{ item.0.item.domain | default('example.com') }} {{ item.1 }}"
args:
chdir: "{{ zimbra_data_dir }}/bin/"
with_subelements:
- "{{ dl_config_result.results }}"
- item.mail_alias
- flags:
skip_missing: true
when:
- item.1 is defined
- item.1 not in item.0.stdout
loop_control:
label: "{{ item.0.item.name }}"
become: true
become_user: "{{ zimbra_user }}"
Tested with:
- Ansible 2.5.7
- Zimbra 8.7.11
This post is licensed under CC BY 4.0 by the author.