问题描述
想要使用Ansible创建Keycloak Realm,但是目前没有相应的模块可以实现。他尝试使用Keycloak的REST API通过uri
模块创建一个Token,然后通过REST发送一个JSON RealmRepresentation。但是他遇到了一些问题,无法成功创建Realm。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
根据最佳回答,URL的问题导致了创建Realm失败。正确的URL应该是https://keycloak-server/auth/admin/realms
。
以下是使用Ansible的uri
模块创建Keycloak Realm的示例代码:
- name: "Create Realm for service Keycloak"
uri:
url: "https://keycloak-server/auth/admin/realms"
method: POST
src: "realm.json"
remote_src: "no"
status_code:
- 201
headers:
Content-type: "application/json"
Accept: "application/json"
Authorization: "Bearer {{ keycloak_token.json.access_token }}"
register: keycloak_realm_create
请注意,返回的状态码应为”201 created”,uri
模块必须知道这是正确的。
这个方案只能成功创建一次Realm。因为在下一次运行时,REST API会返回409,导致uri
模块失败。为了保证幂等性,你需要先检查Realm是否存在。可以通过GET /auth/admin/realms/{{ keycloak_realm_name }}
来检查,如果返回码是404或200,则进行”POST”操作,否则进行”PUT”操作。以下是一个完整的示例:
- name: "Set facts"
set_fact:
keycloak_admin_user: "admin"
keycloak_admin_pass: "password"
keycloak_base_url: "https://keycloak.server"
keycloak_realm_name: "myrealm"
keycloak_realm_data_file: "realm.json"
- name: "Create Token for service Keycloak"
uri:
url: "{{ keycloak_base_url }}/auth/realms/master/protocol/openid-connect/token"
method: POST
body_format: form-urlencoded
body:
username: "{{ keycloak_admin_user }}"
password: "{{ keycloak_admin_pass }}"
grant_type: "password"
client_id: "admin-cli"
register: keycloak_token
- name: "Find out, if Realm {{ keycloak_realm_name }} for service Keycloak exists"
uri:
url: "{{ keycloak_base_url }}/auth/admin/realms/{{ keycloak_realm_name }}"
method: GET
status_code:
- 200
- 404
headers:
Accept: "application/json"
Authorization: "Bearer {{ keycloak_token.json.access_token }}"
register: keycloak_realm_exists
- name: "Create Realm {{ keycloak_realm_name }} for service Keycloak"
uri:
url: "{{ keycloak_base_url }}/auth/admin/realms"
method: POST
src: "{{ keycloak_realm_data_file }}"
remote_src: "no"
status_code:
- 201
headers:
Content-type: "application/json"
Accept: "application/json"
Authorization: "Bearer {{ keycloak_token.json.access_token }}"
register: keycloak_realm_create
when: "keycloak_realm_exists.status == 404"
- name: "Update Realm {{ keycloak_realm_name }} for service Keycloak"
uri:
url: "{{ keycloak_base_url }}/auth/admin/realms/{{ keycloak_realm_name }}"
method: PUT
src: "{{ keycloak_realm_data_file }}"
remote_src: "no"
status_code:
- 204
headers:
Content-type: "application/json"
Accept: "application/json"
Authorization: "Bearer {{ keycloak_token.json.access_token }}"
register: keycloak_realm_create
when: "keycloak_realm_exists.status == 200"
另外,我遇到了一个问题,就是在每次请求之后,如果不在下一次调用Keycloak之前刷新令牌,Keycloak服务器会返回403。但我认为这取决于管理员域的Realm令牌设置。
方案2
用户在评论中提到了另一种方法,即使用CURL命令来创建Realm。以下是一个示例命令:
curl -v -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @realm.json \
$KCHOST/auth/admin/realms
这个方法可以通过编写一个Shell脚本来实现,或者在Ansible中使用shell
模块。
以上是两种创建Keycloak Realm的方法,你可以根据自己的需求选择适合的方法。