# Deploy Fleet server using API

**URL:** <https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951>\
**Category:** Elastic Agent\
**Tags:** fleet\
**Created:** [March 3, 2023, 2:57pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951 "2023-03-03T14:57:51Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 3, 2023, 2:57pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/1 "2023-03-03T14:57:51Z")

</div>

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:

```auto
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:

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/b/3/b3dd9a23d3ab2abaa1050ea62d7d411f3e3df0bf.png)

Thank you in advance for any help

---

<div class="post-metadata">

**Author:** ![patrykkopycinski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/patrykkopycinski/32/45595_2.png) [@patrykkopycinski](https://discuss.elastic.co/u/patrykkopycinski)\
**Post date:** [March 3, 2023, 3:34pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/2 "2023-03-03T15:34:23Z")

</div>

> [@krzychohoho](#):
>
> ```auto
> --header 'kbn-xsrf: xx' \
> --data '{
> "name": "Fleet",
> "policy_id": "$fleet_policy_id",
> "package": {
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 3, 2023, 3:37pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/3 "2023-03-03T15:37:28Z")

</div>

> [@patrykkopycinski](#):
>
> ` has_fleet_server: true`

That was it! Thank you very much!

---

<div class="post-metadata">

**Author:** ![patrykkopycinski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/patrykkopycinski/32/45595_2.png) [@patrykkopycinski](https://discuss.elastic.co/u/patrykkopycinski)\
**Post date:** [March 3, 2023, 3:38pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/4 "2023-03-03T15:38:41Z")

</div>



---

<div class="post-metadata">

**Author:** ![warkolm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/warkolm/32/39224_2.png) [@warkolm](https://discuss.elastic.co/u/warkolm)\
**Post date:** [March 5, 2023, 10:56pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/5 "2023-03-05T22:56:32Z")

</div>



---

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 7, 2023, 12:29pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/6 "2023-03-07T12:29:40Z")

</div>

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

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/4/2/42952a274172ea2db0f94dab34a2750e1352e4dd.png)  
 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/d/f/df5d8df692f58e0336c82d1c7dec69a1bfd929f1.png)

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

```auto
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:

```auto
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:

```auto
#!/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.

---

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 7, 2023, 12:33pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/7 "2023-03-07T12:33:37Z")

</div>

> [@krzychohoho](#):
>
> `fail to enroll: fail to execute request to fleet-server: dial tcp`

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

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/6/0/60548f1a8f1b49d5544d25594d690b4d903bbf59.png)

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

---

<div class="post-metadata">

**Author:** ![patrykkopycinski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/patrykkopycinski/32/45595_2.png) [@patrykkopycinski](https://discuss.elastic.co/u/patrykkopycinski)\
**Post date:** [March 8, 2023, 7:36pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/8 "2023-03-08T19:36:47Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 9, 2023, 2:38pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/9 "2023-03-09T14:38:36Z")

</div>

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

```auto
#!/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

---

<div class="post-metadata">

**Author:** ![patrykkopycinski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/patrykkopycinski/32/45595_2.png) [@patrykkopycinski](https://discuss.elastic.co/u/patrykkopycinski)\
**Post date:** [March 9, 2023, 9:00pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/10 "2023-03-09T21:00:28Z")

</div>

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

```auto
#!/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

```

---

<div class="post-metadata">

**Author:** ![krzychohoho](https://avatars.discourse-cdn.com/v4/letter/k/c68b51/32.png) [@krzychohoho](https://discuss.elastic.co/u/krzychohoho)\
**Post date:** [March 15, 2023, 3:10pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/11 "2023-03-15T15:10:51Z")

</div>

> [@patrykkopycinski](#):
>
> ```auto
> 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:

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/a/b/ab58006cb62b08ce92d532d3010abd8f45c82582.png)

But there is no fleet server here:

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/3/a/3ad7f97c32903ceaa3100a7ef05da3e53fd9cf0a.png)

and here

 ![obraz](https://us1.discourse-cdn.com/elastic/original/3X/0/3/0375afa90f7ba1beb286585771006d78fc528a46.png)

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

---

<div class="post-metadata">

**Author:** ![patrykkopycinski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/patrykkopycinski/32/45595_2.png) [@patrykkopycinski](https://discuss.elastic.co/u/patrykkopycinski)\
**Post date:** [March 15, 2023, 3:55pm UTC](https://discuss.elastic.co/t/deploy-fleet-server-using-api/326951/12 "2023-03-15T15:55:56Z")

</div>

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

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

```

Make sure to use https
