Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions admin-tools/get-credentials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
block:
- name: Get Keycloak DSO user credentials
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
kind: Secret
name: dso-admin-user-secret
register: keycloak_user_creds
Expand All @@ -128,15 +128,15 @@
kubernetes.core.k8s_info:
kind: Secret
name: keycloak
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
register: keycloak_admin_creds
tags:
- keycloak

- name: Display Keycloak credentials
ansible.builtin.debug:
msg:
- "URL : https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }} "
- "URL : https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }} "
- "Admin username: dsoadmin "
- "Admin password: {{ keycloak_admin_creds.resources[0].data['admin-password'] | b64decode }} "
tags:
Expand Down
2 changes: 1 addition & 1 deletion admin-tools/get-versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
- name: Retrieve Keycloak infos
kubernetes.core.helm_info:
name: keycloak
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
register: keycloak_infos

- name: Display Keycloak version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
- name: Reset Keycloak admin password
hosts: localhost
gather_facts: false
vars:
post_conf_job: true
argo_infra_ns_check:
failed: true
tasks:
- name: "Déclaration du clone GitOps local"
ansible.builtin.set_fact:
gitops_local_repo: "{{ lookup('ansible.builtin.env', 'GITOPS_REPO_PATH') }}"
- name: Set Keycloak password reset flag
ansible.builtin.set_fact:
keycloak_reset_password: true
Expand Down Expand Up @@ -33,18 +40,6 @@
- "Rappel : le présent playbook lancé seul, sans extra vars, utilisera la configuration dsc par défaut (conf-dso)."
- "Il réinitialisera donc le mot de passe de l'administrateur Keycloak du namespace associé."

- name: Get Keycloak pods
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloak.namespace }}"
kind: Pod
label_selectors:
- app.kubernetes.io/name=keycloak
register: kc_pods

- name: Set kc_pod fact
ansible.builtin.set_fact:
kc_pod: "{{ kc_pods.resources[0].metadata.name }}"

- name: Set tmp_adm_pass fact
ansible.builtin.set_fact:
tmp_adm_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}"
Expand All @@ -53,23 +48,97 @@
ansible.builtin.set_fact:
kc_adm_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}"

- name: Create temporary admin user
kubernetes.core.k8s_exec:
pod: "{{ kc_pod }}"
namespace: "{{ dsc.keycloak.namespace }}"
command: >
bash -c "JAVA_OPTS_APPEND='-Djgroups.dns.query=keycloak-headless.{{ dsc.keycloak.namespace }}.svc.cluster.local -Djgroups.bind.port=7900';
export PASS_VAR='{{ tmp_adm_pass }}';
kc.sh bootstrap-admin user --username tmpadm --password:env PASS_VAR"
register: tmp_adm
- name: Bootstrap temporary admin via isolated pod
block:
- name: Get keycloak StatefulSet spec
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloakx.namespace }}"
kind: StatefulSet
name: keycloak
register: kc_statefulset

- name: Set kc_container_spec fact
ansible.builtin.set_fact:
kc_container_spec: "{{ kc_statefulset.resources[0].spec.template.spec.containers | selectattr('name', 'equalto', 'keycloak') | first }}"
kc_pod_security_context: "{{ kc_statefulset.resources[0].spec.template.spec.securityContext | default({}) }}"
kc_service_account: "{{ kc_statefulset.resources[0].spec.template.spec.serviceAccountName | default(omit) }}"

- name: Set bootstrap pod name and temp admin username facts
ansible.builtin.set_fact:
bootstrap_pod_name: "keycloakx-bootstrap-admin-{{ now(fmt='%Y%m%d%H%M%S') }}"
tmp_admin_username: "tmpadm-{{ now(fmt='%Y%m%d%H%M%S') }}"

- name: Create isolated bootstrap-admin pod
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: "{{ bootstrap_pod_name }}"
namespace: "{{ dsc.keycloakx.namespace }}"
labels:
app.kubernetes.io/name: keycloakx-bootstrap-admin
spec:
restartPolicy: Never
serviceAccountName: "{{ kc_service_account | default(omit) }}"
securityContext: "{{ kc_pod_security_context }}"
containers:
- name: bootstrap-admin
image: "{{ kc_container_spec.image }}"
securityContext: "{{ kc_container_spec.securityContext | default({}) }}"
command:
- /opt/keycloak/bin/kc.sh
args:
- bootstrap-admin
- user
- --username
- "{{ tmp_admin_username }}"
- --password:env
- PASS_VAR
- --no-prompt
env: "{{ bootstrap_env }}"
vars:
base_env: "{{ (kc_container_spec.env | default([])) | rejectattr('name', 'equalto', 'KC_CACHE') | list }}"
bootstrap_env: "{{ base_env + [{'name': 'KC_CACHE', 'value': 'local'}, {'name': 'PASS_VAR', 'value': tmp_adm_pass}] }}"

- name: Wait for bootstrap-admin pod to finish
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloakx.namespace }}"
kind: Pod
name: "{{ bootstrap_pod_name }}"
register: bootstrap_pod_status
until: bootstrap_pod_status.resources[0].status.phase in ['Succeeded', 'Failed']
retries: 50
delay: 5

- name: Get bootstrap-admin pod logs
kubernetes.core.k8s_log:
namespace: "{{ dsc.keycloakx.namespace }}"
name: "{{ bootstrap_pod_name }}"
register: bootstrap_pod_logs

- name: Fail if bootstrap-admin pod did not succeed
ansible.builtin.fail:
msg: "{{ bootstrap_pod_logs.log_lines | default([bootstrap_pod_logs.log | default('no logs')]) }}"
when: bootstrap_pod_status.resources[0].status.phase != 'Succeeded'
always:
- name: Delete bootstrap-admin pod
kubernetes.core.k8s:
state: absent
namespace: "{{ dsc.keycloakx.namespace }}"
kind: Pod
name: "{{ bootstrap_pod_name }}"
when: bootstrap_pod_name is defined
ignore_errors: true

- name: Update dsoadmin user
community.general.keycloak_user:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
auth_client_id: admin-cli
auth_keycloak_url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}
auth_keycloak_url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}
auth_realm: master
auth_username: tmpadm
auth_username: "{{ tmp_admin_username }}"
auth_password: "{{ tmp_adm_pass }}"
state: present
realm: master
Expand All @@ -91,12 +160,12 @@
- name: Update keycloak secret
kubernetes.core.k8s:
kind: Secret
name: keycloak
namespace: "{{ dsc.keycloak.namespace }}"
name: keycloakx-admin-secret
namespace: "{{ dsc.keycloakx.namespace }}"
state: patched
definition:
data:
admin-password: "{{ kc_adm_pass | b64encode }}"
KEYCLOAK_ADMIN_PASSWORD: "{{ kc_adm_pass | b64encode }}"

- name: Update console inventory
when: not dsc.global.gitOps.deploymentEnabled
Expand All @@ -113,16 +182,25 @@
community.general.keycloak_user:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
auth_client_id: admin-cli
auth_keycloak_url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}
auth_keycloak_url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}
auth_realm: master
auth_username: dsoadmin
auth_password: "{{ kc_adm_pass }}"
state: absent
realm: master
username: tmpadm
username: "{{ tmp_admin_username }}"
# NB: a leftover "tmpadm" (or "tmpadm-<timestamp>" from an earlier
# interrupted run of this playbook) is not cleaned up here - each run
# now uses a unique temp username, so nothing depends on removing old
# ones, and their passwords were random and never recorded anywhere.
# Remove them by hand from the master realm's user list if you want
# the account list tidy.

- name: Update new password in infra-vault
when: dsc.global.gitOps.deploymentEnabled
# No `when: dsc.global.gitOps.deploymentEnabled` guard here: the
# keycloakx-admin-secret Secret is AVP-rendered from this same Vault
# path on every ArgoCD sync, so skipping the write would let the next
# sync silently revert this reset.
block:
- name: Load variables for the vault-secrets post-install role
ansible.builtin.include_vars:
Expand All @@ -131,6 +209,8 @@
- name: Post-install vault-secrets run
ansible.builtin.import_role:
name: "gitops/vault-secrets"
vars:
post_vault_update: true

- name: Get DSO Console server deployment
kubernetes.core.k8s_info:
Expand Down Expand Up @@ -164,8 +244,8 @@
ansible.builtin.debug:
msg:
- "Réinitialisation du mot de passe administrateur de l'instance Keycloak suivante effectuée :"
- " URL : https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}"
- " Namespace : {{ dsc.keycloak.namespace }}"
- " URL : https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}"
- " Namespace : {{ dsc.keycloakx.namespace }}"
- ""
- "Nouveaux identifiants :"
- " Utilisateur : dsoadmin "
Expand Down
18 changes: 9 additions & 9 deletions admin-tools/keycloak-user-unlock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@

- name: Get Keycloak pods
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
kind: Pod
label_selectors:
- app.kubernetes.io/name=keycloak
- app.kubernetes.io/name=keycloakx
register: kc_pods

- name: Set kc_pod fact
Expand All @@ -75,16 +75,16 @@
- name: Create temporary admin user
kubernetes.core.k8s_exec:
pod: "{{ kc_pod }}"
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
command: >
bash -c "JAVA_OPTS_APPEND='-Djgroups.dns.query=keycloak-headless.{{ dsc.keycloak.namespace }}.svc.cluster.local -Djgroups.bind.port=7900';
bash -c "JAVA_OPTS_APPEND='-Djgroups.dns.query=keycloak-headless.{{ dsc.keycloakx.namespace }}.svc.cluster.local -Djgroups.bind.port=7900';
export PASS_VAR='{{ tmp_admin_pass }}';
kc.sh bootstrap-admin user --username {{ tmp_admin }} --password:env PASS_VAR"
/opt/keycloak/bin/kc.sh bootstrap-admin user --username {{ tmp_admin }} --password:env PASS_VAR"
register: tmp_adm

- name: Get Keycloak API token
ansible.builtin.uri:
url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}/realms/master/protocol/openid-connect/token
url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}/realms/master/protocol/openid-connect/token
method: POST
status_code: [200, 202]
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
Expand All @@ -99,7 +99,7 @@

- name: Retrieve users from API
ansible.builtin.uri:
url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}/admin/realms/master/users
url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}/admin/realms/master/users
method: GET
status_code: [200, 204]
return_content: true
Expand All @@ -118,7 +118,7 @@

- name: Unlock user
ansible.builtin.uri:
url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}/admin/realms/master/attack-detection/brute-force/users/{{ user_id }}
url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}/admin/realms/master/attack-detection/brute-force/users/{{ user_id }}
method: DELETE
status_code: [200, 204]
return_content: true
Expand All @@ -131,7 +131,7 @@
community.general.keycloak_user:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
auth_client_id: admin-cli
auth_keycloak_url: https://{{ dsc.keycloak.subDomain }}{{ dsc.global.rootDomain }}
auth_keycloak_url: https://{{ dsc.keycloakx.subDomain }}{{ dsc.global.rootDomain }}
auth_realm: master
auth_username: "{{ tmp_admin }}"
auth_password: "{{ tmp_admin_pass }}"
Expand Down
4 changes: 2 additions & 2 deletions admin-tools/pgrestore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

vars:
pgdump_cnpg_clusters:
- name: "{{ dsc.keycloak.subDomain }}"
namespace: "{{ dsc.keycloak.namespace }}"
- name: "{{ dsc.keycloakx.subDomain }}"
namespace: "{{ dsc.keycloakx.namespace }}"
db: keycloak
- name: "{{ dsc.sonarqube.subDomain }}"
namespace: "{{ dsc.sonarqube.namespace }}"
Expand Down
2 changes: 1 addition & 1 deletion post-install/awx-oidc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
- name: Get awx client secret
kubernetes.core.k8s_info:
kind: Secret
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
name: keycloak-client-secret-awx-client
register: awx_secret
failed_when: awx_secret.resources | length == 0
Expand Down
6 changes: 3 additions & 3 deletions post-install/keycloak.yaml → post-install/keycloakx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
envs:
- name: "{{ dsc_name }}"
apps:
- argocd_app: keycloak
- argocd_app: keycloakx
vault_values:
global:
userTmpPassword: "itDoesNotMatterWhatWeWriteHere"
Expand All @@ -33,7 +33,7 @@

- name: Import keycloak role
ansible.builtin.import_role:
name: gitops/post-install/keycloak
name: gitops/post-install/keycloakx

- name: Update vault-secrets for oidc
block:
Expand All @@ -49,7 +49,7 @@
- argocd_app: gitlab
vault_values:
oidcProvider: "{{ gitlab_oidc_provider | b64encode | default('') }}"
- argocd_app: keycloak
- argocd_app: keycloakx
vault_values:
client:
argo:
Expand Down
10 changes: 5 additions & 5 deletions roles/admin-tools/keycloak-enforce-mfa/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
- name: Get Keycloak admin password
kubernetes.core.k8s_info:
namespace: "{{ dsc.keycloak.namespace }}"
namespace: "{{ dsc.keycloakx.namespace }}"
kind: Secret
name: keycloak
register: kc_adm_pass
Expand All @@ -13,7 +13,7 @@

- name: Get Keycloak API token
ansible.builtin.uri:
url: "{{ keycloak_auth_url }}/realms/{{ dsc.keycloak.managementRealm }}/protocol/openid-connect/token"
url: "{{ keycloak_auth_url }}/realms/{{ dsc.keycloakx.managementRealm }}/protocol/openid-connect/token"
method: POST
status_code: [200, 202]
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
Expand All @@ -29,7 +29,7 @@

- name: Get Keycloak API token
ansible.builtin.uri:
url: "{{ keycloak_auth_url }}/realms/{{ dsc.keycloak.managementRealm }}/protocol/openid-connect/token"
url: "{{ keycloak_auth_url }}/realms/{{ dsc.keycloakx.managementRealm }}/protocol/openid-connect/token"
method: POST
status_code: [200, 202]
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
Expand All @@ -50,7 +50,7 @@
page_size: 100
first_index: "{{ item }}"
ansible.builtin.uri:
url: "{{ keycloak_auth_url }}/admin/realms/{{ dsc.keycloak.applicationRealm }}/users?first={{ first_index }}&max={{ page_size }}"
url: "{{ keycloak_auth_url }}/admin/realms/{{ dsc.keycloakx.applicationRealm }}/users?first={{ first_index }}&max={{ page_size }}"
method: GET
headers:
Authorization: "Bearer {{ kc_access_token }}"
Expand All @@ -67,7 +67,7 @@

- name: Force CONFIGURE_TOTP for all users except admin
ansible.builtin.uri:
url: "{{ keycloak_auth_url }}/admin/realms/{{ dsc.keycloak.applicationRealm }}/users/{{ item.id }}"
url: "{{ keycloak_auth_url }}/admin/realms/{{ dsc.keycloakx.applicationRealm }}/users/{{ item.id }}"
method: PUT
status_code: [200, 204]
body_format: json
Expand Down
Loading