Project

General

Profile

Statistics
| Branch: | Revision:

duckcorp-infra / ansible / playbooks / tenants / duckcorp / mail.yml @ 929e449f

History | View | Annotate | Download (5.2 KB)

1
---
2

    
3
- hosts: dnsbl_servers
4
  tasks:
5
    - name: Install DNSBL
6
      import_role:
7
        name: dc-dnsbl
8
  tags: dnsbl
9

    
10
- hosts: mx1_servers
11
  vars:
12
    cert_dir: "/etc/stunnel/certs"
13
    cert_base_name: "duckcorp_stunnel_redis_{{ inventory_hostname }}"
14
    is_master: "{{ redis.master == inventory_hostname }}"
15
    redis_replication_info:
16
      host: localhost
17
      port: "{{ stunnel.redis.tunnel_port }}"
18
  tasks:
19
    - name: Create TLS Certificates Directory
20
      file:
21
        path: "{{ cert_dir }}"
22
        state: directory
23
        owner: root
24
        group: root
25
        mode: 0750
26

    
27
    - name: Install TLS Certificates
28
      copy:
29
        src: "{{ pki.path }}/{{ is_master | ternary('server', 'client') }}/{{ cert_base_name }}.pem"
30
        dest: "{{ cert_dir }}/"
31
        owner: root
32
        group: root
33
        mode: 0740
34

    
35
    - name: "Load Redis master facts"
36
      setup:
37
      delegate_to: "{{ redis.master }}"
38
      delegate_facts: True
39
      when: redis.master not in hostvars or 'ansible_fqdn' not in hostvars[redis.master]
40

    
41
    # :: would bind on both IPv6 and IPv4 and conflict with previous configuration
42
    # see https://serverfault.com/questions/666712/binding-stunnel-on-both-ipv6-and-ipv4#666766
43
    # whereas ::1 only binds IPv6
44
    # so we were forced to split master/slave config
45
    - name: Install Stunnel for Redis Replication (master)
46
      include_role:
47
        name: stunnel
48
      vars:
49
        tunnel_name: redis
50
        services:
51
          # identical as main-db-v6 for slave
52
          main-db:
53
            is_server: "{{ is_master }}"
54
            accept: "{{ is_master | ternary('::', '::1') }}:{{ stunnel.redis.tunnel_port }}"
55
            connect: "{{ is_master | ternary(redis.port, hostvars[redis.master].ansible_fqdn + ':' + stunnel.redis.tunnel_port|string) }}"
56
            tls:
57
              pem_path: "{{ cert_dir }}/{{ cert_base_name }}.pem"
58
              # for some reason filtering on the CN works on the server side but only the SANs work on the client side
59
              allowed_hosts: "{{ is_master | ternary(groups['mx1_servers']|select('ne', redis.master)|map('regex_replace', '^(.*)$', 'TLS Tunnel Redis Node \\1')|list, [hostvars[redis.master].ansible_fqdn]) }}"
60
      when: is_master
61
      tags: redis_stunnel
62

    
63
    - name: Install Stunnel for Redis Replication (slave)
64
      include_role:
65
        name: stunnel
66
      vars:
67
        tunnel_name: redis
68
        services:
69
          main-db-v4:
70
            is_server: "{{ is_master }}"
71
            accept: "{{ is_master | ternary('0.0.0.0', '127.0.0.1') }}:{{ stunnel.redis.tunnel_port }}"
72
            connect: "{{ is_master | ternary(redis.port, hostvars[redis.master].ansible_fqdn + ':' + stunnel.redis.tunnel_port|string) }}"
73
            tls:
74
              pem_path: "{{ cert_dir }}/{{ cert_base_name }}.pem"
75
              # for some reason filtering on the CN works on the server side but only the SANs work on the client side
76
              allowed_hosts: "{{ is_master | ternary(groups['mx1_servers']|select('ne', redis.master)|map('regex_replace', '^(.*)$', 'TLS Tunnel Redis Node \\1')|list, [hostvars[redis.master].ansible_fqdn]) }}"
77
          main-db-v6:
78
            is_server: "{{ is_master }}"
79
            accept: "{{ is_master | ternary('::', '::1') }}:{{ stunnel.redis.tunnel_port }}"
80
            connect: "{{ is_master | ternary(redis.port, hostvars[redis.master].ansible_fqdn + ':' + stunnel.redis.tunnel_port|string) }}"
81
            tls:
82
              pem_path: "{{ cert_dir }}/{{ cert_base_name }}.pem"
83
              # for some reason filtering on the CN works on the server side but only the SANs work on the client side
84
              allowed_hosts: "{{ is_master | ternary(groups['mx1_servers']|select('ne', redis.master)|map('regex_replace', '^(.*)$', 'TLS Tunnel Redis Node \\1')|list, [hostvars[redis.master].ansible_fqdn]) }}"
85
      when: not is_master
86
      tags: redis_stunnel
87

    
88
    - name: "Install Redis Database"
89
      import_role:
90
        name: redis
91
      vars:
92
        memory_max: "{{ redis.memory_max }}"
93
        memory_policy: "{{ redis.memory_policy }}"
94
        password: "{{ redis.pw }}"
95
        replication: "{{ is_master | ternary([], redis_replication_info) }}"
96
      tags: redis_db
97
  tags: redis
98

    
99
- hosts: mx_servers
100
  tasks:
101
    - name: Install MTA
102
      import_role:
103
        name: dc-postfix
104
  tags: mta
105

    
106
- hosts: mx1_servers
107
  tasks:
108
    - name: Create Mail Storage
109
      import_role:
110
        name: lvm_partition
111
      vars:
112
        lv_name: vmail
113
        vg: main
114
        size: 30G
115
        fstype: ext4
116
        path: "{{ mail.storage }}"
117
        opts: "defaults,acl"
118
        passno: 2
119
    - name: Fetch facts for sync partner
120
      setup:
121
      delegate_to: "{{ mail.dovecot.sync_with }}"
122
      delegate_facts: True
123
      when: mail.dovecot.sync_with not in hostvars or 'ansible_fqdn' not in hostvars[mail.dovecot.sync_with]
124
    - name: Install MDA/MAA
125
      import_role:
126
        name: dc-dovecot
127
    # TODO: creation of the `milkypond` namespace and ACLs
128
  tags:
129
    - mda
130
    - maa
131
    - partitionning
132

    
133
- hosts: mx1_servers
134
  tasks:
135
    - name: Install Antispam Checker
136
      import_role:
137
        name: dc-rspamd
138
      tags: antispam_server
139
    - name: Install Antispam Retraining Spooler
140
      import_role:
141
        name: dc-spoolinger
142
      tags: antispam_retrain
143
  tags: antispam
144