summaryrefslogtreecommitdiffstats
path: root/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml
blob: deb2301d758bf069f84f7ed95221136361111c54 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
---
- name: Install etcd
  package:
    name: "etcd{{ '-' + etcd_version if etcd_version is defined else '' }}"
    state: present
  when: not etcd_is_containerized | bool
  register: result
  until: result is succeeded

- name: Check status of etcd certificates
  stat:
    path: "{{ item }}"
  with_items:
  - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}server.crt"
  - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}peer.crt"
  - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}ca.crt"
  register: g_etcd_server_cert_stat_result
  when: not etcd_certificates_redeploy | default(false) | bool

- set_fact:
    etcd_server_certs_missing: "{{ true if etcd_certificates_redeploy | default(false) | bool
                                   else (False in (g_etcd_server_cert_stat_result.results
                                                   | default({})
                                                   | oo_collect(attribute='stat.exists')
                                                   | list)) }}"

- name: Ensure generated_certs directory present
  file:
    path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}"
    state: directory
    mode: 0700
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Create the server csr
  command: >
    openssl req -new -keyout {{ etcd_cert_prefix }}server.key
    -config {{ etcd_openssl_conf }}
    -out {{ etcd_cert_prefix }}server.csr
    -reqexts {{ etcd_req_ext }} -batch -nodes
    -subj /CN={{ etcd_hostname }}
  args:
    chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}"
    creates: "{{ etcd_generated_certs_dir ~ '/' ~  etcd_cert_subdir ~ '/'
                 ~ etcd_cert_prefix ~ 'server.csr' }}"
  environment:
    SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}"
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

# Certificates must be signed serially in order to avoid competing
# for the serial file.
- name: Sign and create the server crt
  delegated_serial_command:
    command: >
      openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
      -out {{ etcd_cert_prefix }}server.crt
      -in {{ etcd_cert_prefix }}server.csr
      -extensions {{ etcd_ca_exts_server }} -batch
    chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}"
    creates: "{{ etcd_generated_certs_dir ~ '/' ~  etcd_cert_subdir ~ '/'
                 ~ etcd_cert_prefix ~ 'server.crt' }}"
  environment:
    SAN: "IP:{{ etcd_ip }}"
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Create the peer csr
  command: >
    openssl req -new -keyout {{ etcd_cert_prefix }}peer.key
    -config {{ etcd_openssl_conf }}
    -out {{ etcd_cert_prefix }}peer.csr
    -reqexts {{ etcd_req_ext }} -batch -nodes
    -subj /CN={{ etcd_hostname }}
  args:
    chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}"
    creates: "{{ etcd_generated_certs_dir ~ '/' ~  etcd_cert_subdir ~ '/'
                 ~ etcd_cert_prefix ~ 'peer.csr' }}"
  environment:
    SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}"
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

# Certificates must be signed serially in order to avoid competing
# for the serial file.
- name: Sign and create the peer crt
  delegated_serial_command:
    command: >
      openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
      -out {{ etcd_cert_prefix }}peer.crt
      -in {{ etcd_cert_prefix }}peer.csr
      -extensions {{ etcd_ca_exts_peer }} -batch
    chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}"
    creates: "{{ etcd_generated_certs_dir ~ '/' ~  etcd_cert_subdir ~ '/'
                 ~ etcd_cert_prefix ~ 'peer.crt' }}"
  environment:
    SAN: "IP:{{ etcd_ip }}"
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- file:
    src: "{{ etcd_ca_cert }}"
    dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt"
    state: hard
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Create local temp directory for syncing certs
  local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX
  become: no
  register: g_etcd_server_mktemp
  changed_when: False
  when: etcd_server_certs_missing | bool

- name: Create a tarball of the etcd certs
  command: >
    tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz
      -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} .
  args:
    creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz"
    # Disables the following warning:
    # Consider using unarchive module rather than running tar
    warn: no
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Retrieve etcd cert tarball
  fetch:
    src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz"
    dest: "{{ g_etcd_server_mktemp.stdout }}/"
    flat: yes
    fail_on_missing: yes
    validate_checksum: yes
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Ensure certificate directory exists
  file:
    path: "{{ item }}"
    state: directory
  with_items:
  - "{{ etcd_cert_config_dir }}"
  when: etcd_server_certs_missing | bool

- name: Unarchive cert tarball
  unarchive:
    src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz"
    dest: "{{ etcd_cert_config_dir }}"
  when: etcd_server_certs_missing | bool

- name: Create a tarball of the etcd ca certs
  command: >
    tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz
      -C {{ etcd_ca_dir }} .
  args:
    creates: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz"
    warn: no
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Retrieve etcd ca cert tarball
  fetch:
    src: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz"
    dest: "{{ g_etcd_server_mktemp.stdout }}/"
    flat: yes
    fail_on_missing: yes
    validate_checksum: yes
  when: etcd_server_certs_missing | bool
  delegate_to: "{{ etcd_ca_host }}"

- name: Ensure ca directory exists
  file:
    path: "{{ item }}"
    state: directory
  with_items:
  - "{{ etcd_ca_dir }}"
  when: etcd_server_certs_missing | bool

- name: Delete temporary directory
  local_action: file path="{{ g_etcd_server_mktemp.stdout }}" state=absent
  become: no
  changed_when: False
  when: etcd_server_certs_missing | bool

- name: Validate permissions on certificate files
  file:
    path: "{{ item }}"
    mode: 0600
    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
  when: etcd_url_scheme == 'https'
  with_items:
  - "{{ etcd_ca_file }}"
  - "{{ etcd_cert_file }}"
  - "{{ etcd_key_file }}"

- name: Validate permissions on peer certificate files
  file:
    path: "{{ item }}"
    mode: 0600
    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
  when: etcd_peer_url_scheme == 'https'
  with_items:
  - "{{ etcd_peer_ca_file }}"
  - "{{ etcd_peer_cert_file }}"
  - "{{ etcd_peer_key_file }}"

- name: Validate permissions on the config dir
  file:
    path: "{{ etcd_conf_dir }}"
    state: directory
    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"
    mode: 0700