Deploy Fleet server using API

Hi,
I am trying to create fully automated script for SIEM deployment. There is one issue. I am not able to install fleet server. I want it to be fully automated no UI interaction. So first i need to create policy using API which i was able to do. Then I need to add fleet server integration to this policy and enroll fleet server using agent package and policy token. I just cannot add fleet to my policy using API. Can someone please provide me any tips for that. This is code responsible for creation of a policy:

fleet_policy_id=$(curl --request POST \
  --url 'https://10.*.*.*:5601/api/fleet/agent_policies?sys_monitoring=true' \
  --header 'Accept: */*' \
  --header 'Authorization: Basic *********************** \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xxx' \
  --data '{
  "name": "Agent policy 11",
  "description": "",
  "namespace": "default",
  "monitoring_enabled": [
    "logs",
    "metrics"
  ]
}' --insecure | jq -r '.item.id')

echo $fleet_policy_id

response=$(curl --request POST \
  --url 'https://10.*.*.*:5601/api/fleet/package_policies' \
  --header 'Authorization: Basic **************************** \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xx' \
  --data '{
  "name": "Fleet",
  "policy_id": "$fleet_policy_id",
  "package": {
    "name": "fleet_server",
    "version": "1.2.0"
  }

}' --insecure)

echo $response

I get the policy created in fleet server but cannot assign fleet integration to it:

Thank you in advance for any help

Hey @krzychohoho,

could you try to pass has_fleet_server: true to the first request?
It should create an agent policy and automatically add Fleet Server integration, so the second request shouldn't be needed

Please let me know if that helped

That was it! Thank you very much!

1 Like

One more thing. Creating fleet policy using this method indeed creates a fleet policy inside kibana:


BUT! When I am trying to enroll a fleet server i get this error:

Error: fail to enroll: fail to execute request to fleet-server: dial tcp *.*.*.*:8220: connect: connection refused

It looks like registering this policy does not make elasticsearch listen on 8220 port.

This is my bashscript to create the policy:

fleet_policy_id=$(curl --request POST \
  --url 'https://'"${ip}"':5601/api/fleet/agent_policies?sys_monitoring=true' \
  --header 'Accept: */*' \
  --header 'Authorization: Basic '"${kibana_authorization}"'' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xxx' \
  --data '{
  "name": "fleet-server-policy",
  "description": "",
  "namespace": "default",
  "monitoring_enabled": [
    "logs",
    "metrics"
  ],
  "has_fleet_server": "true"
}' --insecure)

echo $fleet_policy_id

And then I call this script to install and enroll fleet server:

#!/bin/bash

echo "kibana_authorization in enrollment is $kibana_authorization"
enrollment_token=$(curl --request GET \
  --url 'https://'"${ip}"':5601/api/fleet/enrollment_api_keys' \
  --header 'Authorization: '"Basic ${kibana_authorization}"'' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xx' --insecure | jq -r '.list[] | select(.policy_id == "fleet-server-policy") | .api_key')

echo $enrollment_token


sudo yes | ./elastic-agent-$version-linux-x86_64/elastic-agent install --url=https://$ip:8220 \
  --fleet-server-es=https://$ip:9200 \
  --fleet-server-service-token=$enrollment_token \
  --fleet-server-policy=fleet-server-policy \
  --certificate-authorities=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-es-ca=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-cert=/etc/elasticsearch/instance/instance.crt \
  --fleet-server-cert-key=/etc/elasticsearch/instance/instance.key

Am I missing something? Can you please take a look at it? Thank you in advance.

I can see that there is no fleet registered inside Kibana:

How to get around it using only API? I want to make it 100% automatic.

For enrollment of Fleet Server, you should be using a service token instead of the enrollment key.
You can generate it by POST /api/fleet/service_tokens

The second thing to fix is to remove --url from the agent install command.
--url should be only used when enrolling non-Fleet Server agent

Thank you for the quick response.
Below is the corrected script that I used to deploy the Fleet server:

#!/bin/bash
fleet_policy_id=$(curl --request POST \
  --url 'https://*.*.*.*:5601/api/fleet/service-tokens?sys_monitoring=true' \
  --header 'Accept: */*' \
  --header 'Authorization: Basic ' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xxx' \
  --data '{
  "name": "fleet-server-policy",
  "description": "",
  "namespace": "default",
  "monitoring_enabled": [
    "logs",
    "metrics"
  ],
  "has_fleet_server": "true"
}' --insecure | jq -r ' .value')

echo $fleet_policy_id

sudo yes | ../elastic-agent-8.6.1-linux-x86_64/elastic-agent install --url=https://*.*.*.*:8220 \
  --fleet-server-es=https://*.*.*.*:9200 \
  --fleet-server-service-token=$fleet_policy_id \
  --fleet-server-policy=fleet-server-policy \
  --certificate-authorities=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-es-ca=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-cert=/etc/elasticsearch/instance/instance.crt \
  --fleet-server-cert-key=/etc/elasticsearch/instance/instance.key

As a result of this script, I receive the service-token like this: AAEAAWVsYXN0aWMvZmxlZXQtc2VydmVyL3Rva2VuLTE2NzgzNjkzODAyMzc6UzQzMFlqQ0tTdVNFN0c4b0lBeHQ3UQ.

But it still does not register fleet server inside Kibana ui. I was following POST requests in my browser while setting up fleet in GUI. But it actually makes on POST with " POST /api/fleet/service_tokens"

One more thing. when I am not using url while isntalling it tries to connect to locahlost:80.

Would you be able to provide me an example of this procedure?

Thank you in advance

I think it should be more like this.
You should first create an agent policy and then in another request you should POST /api/fleet/service_tokens to receive the token that next you use in the agent enrollment

#!/bin/bash
fleet_policy_id=$(curl --request POST \
  --url 'https://'"${ip}"':5601/api/fleet/agent_policies?sys_monitoring=true' \
  --header 'Accept: */*' \
  --header 'Authorization: Basic '"${kibana_authorization}"'' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xxx' \
  --data '{
  "name": "fleet-server-policy",
  "description": "",
  "namespace": "default",
  "monitoring_enabled": [
    "logs",
    "metrics"
  ],
  "has_fleet_server": "true"
}' --insecure)

service_token=$(curl --request POST \
  --url 'https://*.*.*.*:5601/api/fleet/service-tokens?sys_monitoring=true' \
  --header 'Accept: */*' \
  --header 'Authorization: Basic ' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'kbn-xsrf: xxx' \
  --data '{}' --insecure | jq -r ' .value')

echo $service_token

sudo yes | ../elastic-agent-8.6.1-linux-x86_64/elastic-agent install --fleet-server-es=https://*.*.*.*:9200 \
  --fleet-server-service-token=$service_token \
  --fleet-server-policy=fleet-server-policy \
  --certificate-authorities=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-es-ca=/etc/elasticsearch/ca/ca.crt \
  --fleet-server-cert=/etc/elasticsearch/instance/instance.crt \
  --fleet-server-cert-key=/etc/elasticsearch/instance/instance.key

Its almost there. There is fleet visible here:

But there is no fleet server here:

and here

Why is it so?
One more thing. I provide url beacause without it there is error saying that if I provide ca.crt I have to add url

I think you need one more POST to
/api/fleet/fleet_server_hosts with payload like

 {"name":"Default","host_urls":["https://127.0.0.1:8220"],"is_default":true}

Make sure to use https