使用Ansible创建Keycloak Realm

43次阅读
没有评论

问题描述

想要使用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的方法,你可以根据自己的需求选择适合的方法。

正文完