|
6 | 6 | kind: Namespace |
7 | 7 | state: present |
8 | 8 |
|
| 9 | +# Setup CNPG s3 secret |
| 10 | + |
9 | 11 | - name: CNPG s3 CA (secret) |
10 | 12 | when: > |
11 | 13 | dsc.global.backup.cnpg.enabled and |
|
34 | 36 | data: |
35 | 37 | ca.pem: "{{ cnpg_s3_ca_pem }}" |
36 | 38 |
|
| 39 | +# Setup CNPG backup |
| 40 | + |
37 | 41 | - name: Set cnpg backup secret |
| 42 | + when: dsc.global.backup.cnpg.enabled |
38 | 43 | kubernetes.core.k8s: |
39 | 44 | name: "{{ dsc.global.backup.s3.credentials.name }}" |
40 | 45 | namespace: "{{ dsc.keycloak.namespace }}" |
|
44 | 49 | data: |
45 | 50 | accessKeyId: "{{ dsc.global.backup.s3.credentials.accessKeyId.value | b64encode }}" |
46 | 51 | secretAccessKey: "{{ dsc.global.backup.s3.credentials.secretAccessKey.value | b64encode }}" |
47 | | - when: dsc.global.backup.cnpg.enabled |
48 | 52 |
|
49 | 53 | - name: Remove cnpg scheduled backup |
50 | 54 | kubernetes.core.k8s: |
|
55 | 59 | state: absent |
56 | 60 | when: not dsc.global.backup.cnpg.enabled |
57 | 61 |
|
58 | | -- name: Create PostgreSQL cluster and keycloak database |
| 62 | +# Create CNPG cluster and Keycloak database |
| 63 | + |
| 64 | +- name: Create PostgreSQL cluster and Keycloak database |
59 | 65 | kubernetes.core.k8s: |
60 | 66 | template: "{{ item }}" |
61 | 67 | with_items: |
|
95 | 101 | retries: 30 |
96 | 102 | delay: 5 |
97 | 103 |
|
| 104 | +# Set Keycloak admin password |
| 105 | + |
98 | 106 | - name: Get Keycloak admin password secret |
99 | 107 | kubernetes.core.k8s_info: |
100 | 108 | namespace: "{{ dsc.keycloak.namespace }}" |
|
116 | 124 | namespace: "{{ dsc.keycloak.namespace }}" |
117 | 125 | type: Opaque |
118 | 126 |
|
119 | | -- name: Check Keycloak helm release |
120 | | - kubernetes.core.helm_info: |
121 | | - name: keycloak |
122 | | - namespace: "{{ dsc.keycloak.namespace }}" |
123 | | - register: kc_helm_release |
124 | | - |
125 | | -- name: Reset Keycloak admin password |
126 | | - when: > |
127 | | - kc_helm_release.status is defined and |
128 | | - kc_adm_pass_secret.resources | length == 0 |
129 | | - block: |
130 | | - - name: Get Keycloak primary BDD pod |
131 | | - kubernetes.core.k8s_info: |
132 | | - kind: Pod |
133 | | - label_selectors: |
134 | | - - "cnpg.io/cluster=pg-cluster-keycloak" |
135 | | - - "cnpg.io/instanceRole=primary" |
136 | | - register: kc_bdd_pod |
137 | | - |
138 | | - - name: Get Keycloak admin ID from database |
139 | | - kubernetes.core.k8s_exec: |
140 | | - pod: "{{ kc_bdd_pod.resources[0].metadata.name }}" |
141 | | - namespace: "{{ dsc.keycloak.namespace }}" |
142 | | - command: > |
143 | | - psql -U postgres -d keycloak --csv -c "\x" -c "select id from user_entity where username = 'admin';" |
144 | | - register: kc_admin_id |
145 | | - |
146 | | - - name: Set kc_admin_id fact |
147 | | - ansible.builtin.set_fact: |
148 | | - kc_admin_id: "{{ kc_admin_id.stdout | regex_search('^id.*', multiline=True) | regex_search('id,(.+)', '\\1') | first }}" |
149 | | - |
150 | | - - name: Delete Keycloak admin in database |
151 | | - kubernetes.core.k8s_exec: |
152 | | - pod: "{{ kc_bdd_pod.resources[0].metadata.name }}" |
153 | | - namespace: "{{ dsc.keycloak.namespace }}" |
154 | | - command: > |
155 | | - psql -U postgres -d keycloak -c "delete from credential where user_id = '"{{ kc_admin_id }}"';" |
156 | | - -c "delete from user_role_mapping where user_id = '"{{ kc_admin_id }}"';" |
157 | | - -c "delete from user_entity where id = '"{{ kc_admin_id }}"';" |
158 | | - -c "delete from user_required_action where user_id = '"{{ kc_admin_id }}"';" |
159 | | -
|
160 | | - - name: Restart Keycloak pods to reset admin password |
161 | | - kubernetes.core.k8s: |
162 | | - kind: Pod |
163 | | - namespace: "{{ dsc.keycloak.namespace }}" |
164 | | - label_selectors: |
165 | | - - "app.kubernetes.io/component=keycloak" |
166 | | - - "app.kubernetes.io/instance=keycloak" |
167 | | - state: absent |
168 | | - |
169 | | - - name: Wait Keycloak URL |
170 | | - ansible.builtin.uri: |
171 | | - url: https://{{ keycloak_domain }} |
172 | | - validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
173 | | - method: GET |
174 | | - status_code: [200, 202] |
175 | | - return_content: false |
176 | | - register: kc_response |
177 | | - until: kc_response is not failed |
178 | | - retries: 30 |
179 | | - delay: 5 |
| 127 | +# Deploy Keycloak |
180 | 128 |
|
181 | 129 | - name: Add bitnami helm repo |
182 | 130 | kubernetes.core.helm_repository: |
|
216 | 164 | retries: 30 |
217 | 165 | delay: 5 |
218 | 166 |
|
| 167 | +# Set admin facts and check access to Keycloak API |
| 168 | + |
219 | 169 | - name: Get Keycloak admin password |
220 | 170 | kubernetes.core.k8s_info: |
221 | 171 | namespace: "{{ dsc.keycloak.namespace }}" |
222 | 172 | kind: Secret |
223 | 173 | name: keycloak |
224 | 174 | register: kc_adm_pass |
225 | 175 |
|
226 | | -- name: Set Keycloak admin name fact |
| 176 | +- name: Set Keycloak admin facts |
227 | 177 | ansible.builtin.set_fact: |
228 | 178 | keycloak_admin_password: "{{ kc_adm_pass.resources[0].data['admin-password'] | b64decode }}" |
229 | 179 | keycloak_admin: admin |
230 | 180 |
|
| 181 | +- name: Get Keycloak API token |
| 182 | + ansible.builtin.uri: |
| 183 | + url: https://{{ keycloak_domain }}/realms/master/protocol/openid-connect/token |
| 184 | + method: POST |
| 185 | + status_code: [200, 202] |
| 186 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 187 | + return_content: true |
| 188 | + body: username={{ keycloak_admin }}&password={{ keycloak_admin_password }}&grant_type=password&client_id=admin-cli |
| 189 | + register: kc_token |
| 190 | + ignore_errors: true |
| 191 | + |
| 192 | +- name: Reset Keycloak admin fact and API token |
| 193 | + when: kc_token is failed |
| 194 | + block: |
| 195 | + - name: Reset Keycloak admin fact |
| 196 | + ansible.builtin.set_fact: |
| 197 | + keycloak_admin: dsoadmin |
| 198 | + |
| 199 | + - name: Get Keycloak API token |
| 200 | + ansible.builtin.uri: |
| 201 | + url: https://{{ keycloak_domain }}/realms/master/protocol/openid-connect/token |
| 202 | + method: POST |
| 203 | + status_code: [200, 202] |
| 204 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 205 | + return_content: true |
| 206 | + body: username={{ keycloak_admin }}&password={{ keycloak_admin_password }}&grant_type=password&client_id=admin-cli |
| 207 | + register: kc_token |
| 208 | + |
| 209 | +- name: Set kc_access_token fact |
| 210 | + ansible.builtin.set_fact: |
| 211 | + kc_access_token: "{{ kc_token.json.access_token }}" |
| 212 | + |
| 213 | +# Create permanent Keycloak admin and update DSO Console inventory |
| 214 | + |
| 215 | +- name: Get keycloak master realm users from API |
| 216 | + ansible.builtin.uri: |
| 217 | + url: https://{{ keycloak_domain }}/admin/realms/master/users |
| 218 | + method: GET |
| 219 | + status_code: [200, 202] |
| 220 | + return_content: true |
| 221 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 222 | + body_format: json |
| 223 | + headers: |
| 224 | + Authorization: bearer {{ kc_access_token }} |
| 225 | + register: kc_master_users |
| 226 | + |
| 227 | +- name: Set permanent_admin_present fact |
| 228 | + ansible.builtin.set_fact: |
| 229 | + permanent_admin_present: false |
| 230 | + |
| 231 | +- name: Update admin_present fact |
| 232 | + when: kc_master_users.json | selectattr('username', 'equalto', 'dsoadmin') |
| 233 | + ansible.builtin.set_fact: |
| 234 | + permanent_admin_present: true |
| 235 | + |
| 236 | +- name: Create permanent admin group and user into master realm |
| 237 | + when: not permanent_admin_present |
| 238 | + block: |
| 239 | + - name: Create admin group |
| 240 | + community.general.keycloak_group: |
| 241 | + auth_client_id: admin-cli |
| 242 | + auth_keycloak_url: https://{{ keycloak_domain }} |
| 243 | + auth_realm: master |
| 244 | + auth_username: "{{ keycloak_admin }}" |
| 245 | + auth_password: "{{ keycloak_admin_password }}" |
| 246 | + name: admin |
| 247 | + realm: master |
| 248 | + state: present |
| 249 | + |
| 250 | + - name: Map admin realm role from admin group |
| 251 | + community.general.keycloak_realm_rolemapping: |
| 252 | + realm: master |
| 253 | + auth_client_id: admin-cli |
| 254 | + auth_keycloak_url: https://{{ keycloak_domain }} |
| 255 | + auth_realm: master |
| 256 | + auth_username: "{{ keycloak_admin }}" |
| 257 | + auth_password: "{{ keycloak_admin_password }}" |
| 258 | + state: present |
| 259 | + group_name: admin |
| 260 | + roles: |
| 261 | + - name: admin |
| 262 | + |
| 263 | + - name: Create master realm permanent admin user |
| 264 | + community.general.keycloak_user: |
| 265 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 266 | + auth_client_id: admin-cli |
| 267 | + auth_keycloak_url: https://{{ keycloak_domain }} |
| 268 | + auth_realm: master |
| 269 | + auth_username: "{{ keycloak_admin }}" |
| 270 | + auth_password: "{{ keycloak_admin_password }}" |
| 271 | + state: present |
| 272 | + realm: master |
| 273 | + credentials: |
| 274 | + - temporary: false |
| 275 | + type: password |
| 276 | + value: "{{ keycloak_admin_password }}" |
| 277 | + username: dsoadmin |
| 278 | + first_name: Admin |
| 279 | + last_name: Admin |
| 280 | + email: admin@example.com |
| 281 | + enabled: true |
| 282 | + email_verified: true |
| 283 | + groups: |
| 284 | + - name: admin |
| 285 | + state: present |
| 286 | + |
231 | 287 | - name: Update console inventory |
232 | 288 | kubernetes.core.k8s: |
233 | 289 | kind: Secret |
|
237 | 293 | definition: |
238 | 294 | data: |
239 | 295 | KEYCLOAK_ADMIN_PASSWORD: "{{ keycloak_admin_password | b64encode }}" |
240 | | - KEYCLOAK_ADMIN: "{{ keycloak_admin | b64encode }}" |
| 296 | + KEYCLOAK_ADMIN: "{{ 'dsoadmin' | b64encode }}" |
| 297 | + |
| 298 | +# Remove Keycloak temporary admin |
| 299 | + |
| 300 | +- name: Set temporary_admin_present fact |
| 301 | + ansible.builtin.set_fact: |
| 302 | + temporary_admin_present: false |
| 303 | + |
| 304 | +- name: Update temporary_admin_present fact |
| 305 | + when: kc_master_users.json | selectattr('username', 'equalto', 'admin') |
| 306 | + ansible.builtin.set_fact: |
| 307 | + temporary_admin_present: true |
| 308 | + |
| 309 | +- name: Remove temporary admin from master realm |
| 310 | + when: temporary_admin_present |
| 311 | + community.general.keycloak_user: |
| 312 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 313 | + auth_client_id: admin-cli |
| 314 | + auth_keycloak_url: https://{{ keycloak_domain }} |
| 315 | + auth_realm: master |
| 316 | + auth_username: "{{ keycloak_admin }}" |
| 317 | + auth_password: "{{ keycloak_admin_password }}" |
| 318 | + state: absent |
| 319 | + realm: master |
| 320 | + username: admin |
| 321 | + |
| 322 | +# Ensure we will use permanent admin for subsequent tasks |
| 323 | + |
| 324 | +- name: Get Keycloak API token |
| 325 | + ansible.builtin.uri: |
| 326 | + url: https://{{ keycloak_domain }}/realms/master/protocol/openid-connect/token |
| 327 | + method: POST |
| 328 | + status_code: [200, 202] |
| 329 | + validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
| 330 | + return_content: true |
| 331 | + body: username={{ keycloak_admin }}&password={{ keycloak_admin_password }}&grant_type=password&client_id=admin-cli |
| 332 | + register: kc_token |
| 333 | + ignore_errors: true |
| 334 | + |
| 335 | +- name: Reset Keycloak admin fact |
| 336 | + when: kc_token is failed |
| 337 | + ansible.builtin.set_fact: |
| 338 | + keycloak_admin: dsoadmin |
241 | 339 |
|
242 | 340 | - name: Get Keycloak API token |
243 | 341 | ansible.builtin.uri: |
|
253 | 351 | ansible.builtin.set_fact: |
254 | 352 | kc_access_token: "{{ kc_token.json.access_token }}" |
255 | 353 |
|
| 354 | +# Create and setup dso realm |
| 355 | + |
256 | 356 | - name: Create dso realm |
257 | 357 | community.general.keycloak_realm: |
258 | 358 | validate_certs: "{{ dsc.exposedCA.type == 'none' }}" |
|
433 | 533 | realm: dso |
434 | 534 | otp_policy_algorithm: SHA256 |
435 | 535 |
|
| 536 | +# Patch some metrics resources |
| 537 | + |
436 | 538 | - name: Patch serviceMonitors |
437 | 539 | when: > |
438 | 540 | dsc.global.metrics.enabled and |
|
0 commit comments