Manage Kibana artefacts with Ansible

We want to be able to automate Elastic/Kibana provisioning as much as possible which includes Kibana roles and spaces. We use Ansible for provisioning and provisioning Elasticsearch is straightforward, however, we're struggling when it comes to Kibana.

I've used to following for creating new space(s) which works as advertised:

- name: Create Kibana spaces
  ansible.builtin.uri:
    url: "http://{{ kibana_host }}:{{ kibana_port }}/api/spaces/space"
...

In the body I include the rendered JSON for the space being created and the space is created. No problem here.

However, when I try to issue a 'DELETE' such as:

- name: Remove Kibana space(s) if they already exist(s)
  ansible.builtin.uri:
    url: "http://{{ kibana_host }}:{{ kibana_port }}/api/spaces/space/{{ item.space | replace(' ','_')  | lower }}"
...

I get a '401' (Not authorized) error although I use the HTTP 'DELETE' verb and provide the correct space name in the url which, in turn, results in an ugly '409' status later when I want to create the space (see above).

I know I may use DELETE kbn:/api/spaces/space/<space> from within the Kibana dev tools but it doesn't help in situations when you want to automate artefact creations outside of the Kibana-environment. Is the current situation such as there's an "internal endpoint" addressable with 'kbn' but the same ReST endpoint is not exposed externally on, say, 5601?

In all of the samples given I authenticate using a "superuser" with at least kibana_admin privileges!

I feel a little lost and if anybody could point me in the right direction I'd be very grateful.

DELETE requests should work as expected from any HTTP client

I've tested the following instructions and I could list, create, and delete spaces without issues (Kibana 8.10.3)

# List current single default space
$ curl -s -u "${ELASTIC_USER}:${ELASTIC_PASSWORD}" -X GET \
  -H 'kbn-xsrf: true' -H 'Content-Type: application/json' \
  ${KIBANA_HOST}/api/spaces/space | jq
[
  {
    "id": "default",
    "name": "Default",
    "description": "This is your default space!",
    "color": "#00bfb3",
    "disabledFeatures": [],
    "_reserved": true
  }
]

# Create a new space with minimal definition
$ curl -s -u "${ELASTIC_USER}:${ELASTIC_PASSWORD}" -X POST \
  -H 'kbn-xsrf: true' -H 'Content-Type: application/json' \
  ${KIBANA_HOST}/api/spaces/space \
  -d '{"id":"discuss", "name": "Discuss"}' | jq
{
  "id": "discuss",
  "name": "Discuss",
  "disabledFeatures": []
}

# List again to check the two spaces are available 
$ curl -s -u "${ELASTIC_USER}:${ELASTIC_PASSWORD}" -X GET \
  -H 'kbn-xsrf: true' -H 'Content-Type: application/json' \
  ${KIBANA_HOST}/api/spaces/space | jq
[
  {
    "id": "default",
    "name": "Default",
    "description": "This is your default space!",
    "color": "#00bfb3",
    "disabledFeatures": [],
    "_reserved": true
  },
  {
    "id": "discuss",
    "name": "Discuss",
    "disabledFeatures": []
  }
]

# Delete the space
$ curl -s -u "${ELASTIC_USER}:${ELASTIC_PASSWORD}" -X DELETE \
  -H 'kbn-xsrf: true' -H 'Content-Type: application/json' \
  ${KIBANA_HOST}/api/spaces/space/discuss | jq

# List again the spaces 
$ curl -s -u "${ELASTIC_USER}:${ELASTIC_PASSWORD}" -X GET \
  -H 'kbn-xsrf: true' -H 'Content-Type: application/json' \
  ${KIBANA_HOST}/api/spaces/space | jq
[
  {
    "id": "default",
    "name": "Default",
    "description": "This is your default space!",
    "color": "#00bfb3",
    "disabledFeatures": [],
    "_reserved": true
  }
]

Have you tried to run these type of queries outside of ansible?

Hi!

Thanks for your reply - it made me investigate this a little further and I finally got it to work. What I did was:

- name: Remove Kibana space(s) if they already exist(s)
  ansible.builtin.uri:
    url: "http://{{ kibana_host }}:{{ kibana_port }}/api/spaces/space/{{ item.space | replace(' ','')  | lower }}"
    url_username: "{{ kibana_manage_environment_username }}"
    url_password: "{{ kibana_manage_environment_password }}"
    force_basic_auth: true
    status_code: 204
    headers:
      kbn-xsrf: true
      Content-Type: application/json
    method: DELETE
  loop: "{{ spaces }}"
  tags:
    - spaces

The key point here is that I removed everything certificate related and replaced them with force_basic_auth: true and status_code: 204 and they made the trick.

Again, many thanks!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.