mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-19 11:36:39 +00:00
Compare commits
7 Commits
feature/ke
...
ab48cf522f
| Author | SHA1 | Date | |
|---|---|---|---|
| ab48cf522f | |||
| 41c12bdc12 | |||
| aae463b602 | |||
| bb50551533 | |||
| 098099b41e | |||
| 0a7d767252 | |||
| d88599f76c |
@@ -50,3 +50,9 @@ credentials:
|
|||||||
recaptcha:
|
recaptcha:
|
||||||
website_key: "" # Required if you enabled recaptcha:
|
website_key: "" # Required if you enabled recaptcha:
|
||||||
secret_key: "" # Required if you enabled recaptcha:
|
secret_key: "" # Required if you enabled recaptcha:
|
||||||
|
|
||||||
|
accounts:
|
||||||
|
bootstrap:
|
||||||
|
username: "administrator"
|
||||||
|
system:
|
||||||
|
username: "{{ SOFTWARE_NAME | replace('.', '_') | lower }}"
|
||||||
78
roles/web-app-keycloak/tasks/05_login.yml
Normal file
78
roles/web-app-keycloak/tasks/05_login.yml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
- name: Ensure permanent Keycloak admin exists and can log in (container env only)
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Try login with permanent admin (uses container ENV)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
register: kc_login_perm
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
|
||||||
|
- name: Login with bootstrap admin (uses container ENV)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KC_BOOTSTRAP_ADMIN_USERNAME" \
|
||||||
|
--password "$KC_BOOTSTRAP_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
register: kc_login_bootstrap
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Ensure permanent admin user exists (create if missing)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
# Try to create; if it already exists, Keycloak returns 409
|
||||||
|
{{ KEYCLOAK_KCADM }} create users -r master \
|
||||||
|
-s "username=$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
-s "enabled=true"
|
||||||
|
'
|
||||||
|
register: kc_create_perm_admin
|
||||||
|
failed_when: >
|
||||||
|
not (
|
||||||
|
kc_create_perm_admin.rc == 0 or
|
||||||
|
(kc_create_perm_admin.stderr is defined and
|
||||||
|
('User exists with same username' in kc_create_perm_admin.stderr))
|
||||||
|
)
|
||||||
|
changed_when: kc_create_perm_admin.rc == 0
|
||||||
|
|
||||||
|
- name: Set permanent admin password (by username, no ID needed)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} set-password -r master \
|
||||||
|
--username "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--new-password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Grant realm-admin role to permanent admin (by username)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} add-roles -r master \
|
||||||
|
--uusername "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--cclientid realm-management \
|
||||||
|
--rolename realm-admin
|
||||||
|
'
|
||||||
|
register: kc_grant_admin
|
||||||
|
changed_when: (kc_grant_admin.stderr is defined and kc_grant_admin.stderr | length > 0) or
|
||||||
|
(kc_grant_admin.stdout is defined and kc_grant_admin.stdout | length > 0)
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Verify login with permanent admin (after creation)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
changed_when: false
|
||||||
@@ -13,82 +13,18 @@
|
|||||||
include_tasks: 04_dependencies.yml
|
include_tasks: 04_dependencies.yml
|
||||||
when: KEYCLOAK_LOAD_DEPENDENCIES | bool
|
when: KEYCLOAK_LOAD_DEPENDENCIES | bool
|
||||||
|
|
||||||
- name: "Wait until '{{ KEYCLOAK_CONTAINER }}' container is healthy"
|
- name: "Load Login routines for '{{ application_id }}'"
|
||||||
community.docker.docker_container_info:
|
include_tasks: 05_login.yml
|
||||||
name: "{{ KEYCLOAK_CONTAINER }}"
|
|
||||||
register: kc_info
|
|
||||||
retries: 60
|
|
||||||
delay: 5
|
|
||||||
until: >
|
|
||||||
kc_info is succeeded and
|
|
||||||
(kc_info.container | default({})) != {} and
|
|
||||||
(kc_info.container.State | default({})) != {} and
|
|
||||||
(kc_info.container.State.Health | default({})) != {} and
|
|
||||||
(kc_info.container.State.Health.Status | default('')) == 'healthy'
|
|
||||||
|
|
||||||
- name: kcadm login (master)
|
- name: "Load Client Update routines for '{{ application_id }}'"
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
include_tasks: update/01_client.yml
|
||||||
shell: >
|
|
||||||
{{ KEYCLOAK_EXEC_KCADM }} config credentials
|
|
||||||
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }}
|
|
||||||
--realm master
|
|
||||||
--user {{ KEYCLOAK_MASTER_API_USER_NAME }}
|
|
||||||
--password {{ KEYCLOAK_MASTER_API_USER_PASSWORD }}
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: "Update Client settings"
|
- name: "Load Mail Update routines for '{{ application_id }}'"
|
||||||
vars:
|
include_tasks: update/02_mail.yml
|
||||||
kc_object_kind: "client"
|
|
||||||
kc_lookup_value: "{{ KEYCLOAK_CLIENT_ID }}"
|
|
||||||
kc_desired: >-
|
|
||||||
{{
|
|
||||||
KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| list | first
|
|
||||||
}}
|
|
||||||
kc_force_attrs:
|
|
||||||
publicClient: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='publicClient')
|
|
||||||
| first)
|
|
||||||
}}
|
|
||||||
serviceAccountsEnabled: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='serviceAccountsEnabled')
|
|
||||||
| first )
|
|
||||||
}}
|
|
||||||
frontchannelLogout: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='frontchannelLogout')
|
|
||||||
| first)
|
|
||||||
}}
|
|
||||||
attributes: >-
|
|
||||||
{{
|
|
||||||
( (KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| list | first | default({}) ).attributes | default({}) )
|
|
||||||
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True)
|
|
||||||
}}
|
|
||||||
include_tasks: _update.yml
|
|
||||||
|
|
||||||
- name: "Update REALM mail settings from realm dictionary (SPOT)"
|
- name: "Load RBAC Update routines for '{{ application_id }}'"
|
||||||
include_tasks: _update.yml
|
include_tasks: update/03_rbac_client_scope.yml
|
||||||
vars:
|
|
||||||
kc_object_kind: "realm"
|
|
||||||
kc_lookup_field: "id"
|
|
||||||
kc_lookup_value: "{{ KEYCLOAK_REALM }}"
|
|
||||||
kc_desired:
|
|
||||||
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
|
||||||
kc_merge_path: "smtpServer"
|
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
||||||
|
|
||||||
- include_tasks: 05_rbac_client_scope.yml
|
- name: "Load LDAP Update routines for '{{ application_id }}'"
|
||||||
|
include_tasks: update/04_ldap.yml
|
||||||
- include_tasks: 06_ldap.yml
|
|
||||||
when: KEYCLOAK_LDAP_ENABLED | bool
|
when: KEYCLOAK_LDAP_ENABLED | bool
|
||||||
|
|||||||
40
roles/web-app-keycloak/tasks/update/01_client.yml
Normal file
40
roles/web-app-keycloak/tasks/update/01_client.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
- name: "Update Client settings"
|
||||||
|
vars:
|
||||||
|
kc_object_kind: "client"
|
||||||
|
kc_lookup_value: "{{ KEYCLOAK_CLIENT_ID }}"
|
||||||
|
kc_desired: >-
|
||||||
|
{{
|
||||||
|
KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| list | first
|
||||||
|
}}
|
||||||
|
kc_force_attrs:
|
||||||
|
publicClient: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='publicClient')
|
||||||
|
| first)
|
||||||
|
}}
|
||||||
|
serviceAccountsEnabled: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='serviceAccountsEnabled')
|
||||||
|
| first )
|
||||||
|
}}
|
||||||
|
frontchannelLogout: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='frontchannelLogout')
|
||||||
|
| first)
|
||||||
|
}}
|
||||||
|
attributes: >-
|
||||||
|
{{
|
||||||
|
( (KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| list | first | default({}) ).attributes | default({}) )
|
||||||
|
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True)
|
||||||
|
}}
|
||||||
|
include_tasks: _update.yml
|
||||||
10
roles/web-app-keycloak/tasks/update/02_mail.yml
Normal file
10
roles/web-app-keycloak/tasks/update/02_mail.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
- name: "Update REALM mail settings from realm dictionary (SPOT)"
|
||||||
|
include_tasks: _update.yml
|
||||||
|
vars:
|
||||||
|
kc_object_kind: "realm"
|
||||||
|
kc_lookup_field: "id"
|
||||||
|
kc_lookup_value: "{{ KEYCLOAK_REALM }}"
|
||||||
|
kc_desired:
|
||||||
|
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
||||||
|
kc_merge_path: "smtpServer"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# --- Ensure RBAC client scope exists (idempotent) ---
|
|
||||||
- name: Ensure RBAC client scope exists
|
- name: Ensure RBAC client scope exists
|
||||||
shell: |
|
shell: |
|
||||||
cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f -
|
cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f -
|
||||||
@@ -16,7 +15,6 @@
|
|||||||
('already exists' not in (create_rbac_scope.stderr | lower))
|
('already exists' not in (create_rbac_scope.stderr | lower))
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
|
|
||||||
# --- Get the scope id we will attach to the client ---
|
|
||||||
- name: Get all client scopes
|
- name: Get all client scopes
|
||||||
shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json"
|
shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json"
|
||||||
register: all_scopes
|
register: all_scopes
|
||||||
@@ -10,19 +10,21 @@ KC_HTTP_ENABLED= true
|
|||||||
KC_HEALTH_ENABLED= {{ KEYCLOAK_HEALTH_ENABLED | lower }}
|
KC_HEALTH_ENABLED= {{ KEYCLOAK_HEALTH_ENABLED | lower }}
|
||||||
KC_METRICS_ENABLED= true
|
KC_METRICS_ENABLED= true
|
||||||
|
|
||||||
# Administrator
|
|
||||||
KEYCLOAK_ADMIN= "{{ KEYCLOAK_ADMIN }}"
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
KC_DB= {{ database_type }}
|
KC_DB= {{ database_type }}
|
||||||
KC_DB_URL= {{ database_url_jdbc }}
|
KC_DB_URL= {{ database_url_jdbc }}
|
||||||
KC_DB_USERNAME= {{ database_username }}
|
KC_DB_USERNAME= {{ database_username }}
|
||||||
KC_DB_PASSWORD= {{ database_password }}
|
KC_DB_PASSWORD= {{ database_password }}
|
||||||
|
|
||||||
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
|
# Credentials
|
||||||
KC_BOOTSTRAP_ADMIN_USERNAME= "{{ KEYCLOAK_ADMIN }}"
|
|
||||||
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
## Bootstrap
|
||||||
|
KC_BOOTSTRAP_ADMIN_USERNAME="{{ KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME }}"
|
||||||
|
KC_BOOTSTRAP_ADMIN_PASSWORD="{{ KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD }}"
|
||||||
|
|
||||||
|
## Permanent
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_USERNAME="{{ KEYCLOAK_PERMANENT_ADMIN_USERNAME }}"
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_PASSWORD="{{ KEYCLOAK_PERMANENT_ADMIN_PASSWORD }}"
|
||||||
|
|
||||||
# Enable detailed logs
|
# Enable detailed logs
|
||||||
{% if MODE_DEBUG | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
users:
|
|
||||||
administrator:
|
|
||||||
username: "administrator"
|
|
||||||
@@ -29,14 +29,22 @@ KEYCLOAK_REALM_IMPORT_FILE_SRC: "import/realm.json.j2"
|
|||||||
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ [KEYCLOAK_REALM_IMPORT_DIR_HOST,'realm.json'] | path_join }}"
|
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ [KEYCLOAK_REALM_IMPORT_DIR_HOST,'realm.json'] | path_join }}"
|
||||||
|
|
||||||
## Credentials
|
## Credentials
|
||||||
KEYCLOAK_ADMIN: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
### Bootstrap
|
||||||
|
KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME: "{{ applications | get_app_conf(application_id, 'accounts.bootstrap.username') }}"
|
||||||
|
KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
||||||
|
|
||||||
|
### Permanent
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_USERNAME: "{{ applications | get_app_conf(application_id, 'accounts.system.username') }}"
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
KEYCLOAK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
KEYCLOAK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}"
|
||||||
KEYCLOAK_EXEC_KCADM: "docker exec -i {{ KEYCLOAK_CONTAINER }} /opt/keycloak/bin/kcadm.sh" # Init script for keycloak
|
KEYCLOAK_EXEC_CONTAINER: "docker exec -i {{ KEYCLOAK_CONTAINER }}"
|
||||||
KEYCLOAK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
KEYCLOAK_KCADM: "/opt/keycloak/bin/kcadm.sh"
|
||||||
KEYCLOAK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
KEYCLOAK_EXEC_KCADM: "{{ KEYCLOAK_EXEC_CONTAINER }} {{ KEYCLOAK_KCADM }}"
|
||||||
|
KEYCLOAK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}"
|
||||||
|
KEYCLOAK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}"
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
KEYCLOAK_SERVER_HOST: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
KEYCLOAK_SERVER_HOST: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
||||||
@@ -69,11 +77,6 @@ KEYCLOAK_LDAP_USER_OBJECT_CLASSES: >
|
|||||||
) | join(', ')
|
) | join(', ')
|
||||||
}}
|
}}
|
||||||
|
|
||||||
## API
|
|
||||||
KEYCLOAK_MASTER_API_USER: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
|
|
||||||
KEYCLOAK_MASTER_API_USER_NAME: "{{ KEYCLOAK_MASTER_API_USER.username }}" # Master Administrator Username
|
|
||||||
KEYCLOAK_MASTER_API_USER_PASSWORD: "{{ KEYCLOAK_MASTER_API_USER.password }}" # Master Administrator Password
|
|
||||||
|
|
||||||
# Dictionaries
|
# Dictionaries
|
||||||
KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}"
|
KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}"
|
||||||
KEYCLOAK_DICTIONARY_REALM: >-
|
KEYCLOAK_DICTIONARY_REALM: >-
|
||||||
|
|||||||
@@ -28,14 +28,17 @@ BUILTIN_FILTERS: Set[str] = {
|
|||||||
"int", "join", "last", "length", "list", "lower", "map", "min", "max", "random",
|
"int", "join", "last", "length", "list", "lower", "map", "min", "max", "random",
|
||||||
"reject", "rejectattr", "replace", "reverse", "round", "safe", "select",
|
"reject", "rejectattr", "replace", "reverse", "round", "safe", "select",
|
||||||
"selectattr", "slice", "sort", "string", "striptags", "sum", "title", "trim",
|
"selectattr", "slice", "sort", "string", "striptags", "sum", "title", "trim",
|
||||||
"truncate", "unique", "upper", "urlencode", "urlize", "wordcount", "xmlattr",
|
"truncate", "unique", "upper", "urlencode", "urlize", "wordcount", "xmlattr","contains",
|
||||||
|
|
||||||
# Common Ansible filters (subset, extend as needed)
|
# Common Ansible filters (subset, extend as needed)
|
||||||
"b64decode", "b64encode", "basename", "dirname", "from_json", "to_json",
|
"b64decode", "b64encode", "basename", "dirname", "from_json", "to_json",
|
||||||
"from_yaml", "to_yaml", "combine", "difference", "intersect",
|
"from_yaml", "to_yaml", "combine", "difference", "intersect",
|
||||||
"flatten", "zip", "regex_search", "regex_replace", "bool",
|
"flatten", "zip", "regex_search", "regex_replace", "bool",
|
||||||
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
||||||
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict", "password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml", "tojson",
|
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict",
|
||||||
|
"password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml",
|
||||||
|
"tojson", "to_nice_json",
|
||||||
|
|
||||||
|
|
||||||
# Date/time-ish
|
# Date/time-ish
|
||||||
"strftime",
|
"strftime",
|
||||||
|
|||||||
Reference in New Issue
Block a user