Connect to Elastic Maps Service
editConnect to Elastic Maps Service
editElastic Maps Service (EMS) is a service that hosts tile layers and vector shapes of administrative boundaries. If you are using Kibana’s out-of-the-box settings, Maps is already configured to use EMS.
If you are on a restricted or fully air-gapped environment, you may need to configure your firewall to enable access to EMS resources. Find below details on the domains and HTTP headers used by Elastic Maps Service. Alternatively, Elastic Maps Service can be disabled or installed locally.
Domains
editEMS requests are made to the following domains:
-
Tile Service:
tiles.maps.elastic.co
-
File Service:
vector.maps.elastic.co
Headers
editFind below examples of the request and response headers from Kibana and a minimal curl
request example showing the response headers sent by each service.
These headers may change without further notice at anytime and are shared for reference.
EMS Tile Service
editThe EMS Tile Service provides basemaps in three different styles as the default background for Maps visualizations. The basemaps use OpenStreetMap data following the OpenMapTiles schema and can be explored at maps.elastic.co.
Headers for the Tile Service JSON manifest describing the basemaps available.
Details
curl -I 'https://tiles.maps.elastic.co/v8.13/manifest?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=8.13.4' \ -H 'User-Agent: curl/7.81.0' \ -H 'Accept: */*' \ -H 'Accept-Encoding: gzip, deflate, br'
Server response
HTTP/2 200 server: BaseHTTP/0.6 Python/3.11.4 date: Mon, 20 Nov 2023 15:08:46 GMT content-type: application/json; charset=utf-8 elastic-api-version: 2023-10-31 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag content-encoding: gzip vary: Accept-Encoding x-varnish: 844076 5416505 accept-ranges: bytes varnish-age: 85285 cache-control: private, max-age=86400 via: 1.1 varnish (Varnish/7.0), 1.1 google alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Host: tiles.maps.elastic.co User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://deployment-host/app/maps/map Origin: https://deployment-host Connection: keep-alive Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site Pragma: no-cache Cache-Control: no-cache TE: trailers
server: BaseHTTP/0.6 Python/3.11.4 date: Mon, 20 Nov 2023 17:53:10 GMT content-type: application/json; charset=utf-8 elastic-api-version: 2023-10-31 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag content-encoding: gzip vary: Accept-Encoding x-varnish: 8848609 1142291 accept-ranges: bytes varnish-age: 65725 cache-control: private, max-age=86400 content-length: 341 via: 1.1 varnish (Varnish/7.0), 1.1 google alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Headers for a vector tile asset in protobuffer format from the Tile Service.
Details
$ curl -I 'https://tiles.maps.elastic.co/data/v3/1/1/0.pbf?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=8.13.4' \ -H 'User-Agent: curl/7.81.0' \ -H 'Accept: */*' \ -H 'Accept-Encoding: gzip, deflate, br'
Server response
HTTP/2 200 content-encoding: gzip content-length: 144075 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag x-varnish: 3269455 5976667 accept-ranges: bytes varnish-age: 9045 via: 1.1 varnish (Varnish/7.0), 1.1 google date: Mon, 20 Nov 2023 15:08:19 GMT age: 78827 last-modified: Thu, 16 Sep 2021 17:14:41 GMT etag: W/"232cb-zYEfNgd8rzHusLotRFzgRDSDDGA" content-type: application/x-protobuf vary: Accept-Encoding cache-control: public,max-age=3600 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Host: tiles.maps.elastic.co User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://deployment-host/app/maps/map Origin: https://deployment-host Connection: keep-alive Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site TE: trailers
content-encoding: gzip content-length: 101691 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag x-varnish: 4698676 3660338 accept-ranges: bytes varnish-age: 9206 via: 1.1 varnish (Varnish/7.0), 1.1 google date: Mon, 20 Nov 2023 15:05:29 GMT age: 75788 last-modified: Thu, 16 Sep 2021 17:14:41 GMT etag: W/"18d3b-ot9ckSsdpH7n+yJz4BXXQp6Zs08" content-type: application/x-protobuf vary: Accept-Encoding cache-control: public,max-age=3600 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Headers for an sprite image asset from the Tile Service
Details
curl -I 'https://tiles.maps.elastic.co/styles/osm-bright-desaturated/sprite.png' \ -H 'User-Agent: curl/7.81.0' \ -H 'Accept: image/avif,image/webp,*/*' \ -H 'Accept-Encoding: gzip, deflate, br'
Server response
HTTP/2 200 content-length: 17181 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag x-varnish: 8769943 4865354 accept-ranges: bytes varnish-age: 250 via: 1.1 varnish (Varnish/7.0), 1.1 google date: Tue, 21 Nov 2023 14:44:36 GMT age: 592 etag: W/"431d-/dqE/W5Q3FqkHikyDQtCuQqAdlY" content-type: image/png cache-control: public,max-age=3600 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Host: tiles.maps.elastic.co User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: image/avif,image/webp,*/* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://deployment-host/app/maps/map Origin: https://deployment-host Connection: keep-alive Sec-Fetch-Dest: image Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site Pragma: no-cache Cache-Control: no-cache TE: trailers
content-length: 17181 access-control-allow-origin: * access-control-allow-methods: GET, OPTIONS, HEAD access-control-allow-headers: Origin, Accept, Content-Type, kbn-version, elastic-api-version access-control-expose-headers: etag x-varnish: 3530683 3764574 accept-ranges: bytes varnish-age: 833 via: 1.1 varnish (Varnish/7.0), 1.1 google date: Mon, 20 Nov 2023 14:44:29 GMT age: 77048 etag: W/"431d-/dqE/W5Q3FqkHikyDQtCuQqAdlY" content-type: image/png cache-control: public,max-age=3600 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
EMS File Service
editEMS File Service provides the administrative boundaries used for choropleth mapping as static assets in GeoJSON or TopoJSON formats and can be explored at maps.elastic.co.
Headers for the File Service JSON manifest that declares all the datasets available.
Details
curl -I 'https://vector.maps.elastic.co/v8.13/manifest?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=8.13.4' \ -H 'User-Agent: curl/7.81.0' \ -H 'Accept: */*' \ -H 'Accept-Encoding: gzip, deflate, br'
Server response
HTTP/2 200 x-guploader-uploadid: ABPtcPp_BvMdBDO5jVlutETVHmvpOachwjilw4AkIKwMrOQJ4exR9Eln4g0LkW3V_LLSEpvjYLtUtFmO0Uwr61XXUhoP_A x-goog-generation: 1689593295246576 x-goog-metageneration: 1 x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 108029 content-encoding: gzip x-goog-hash: crc32c=T5gVpw== x-goog-hash: md5=6F8KWV8VTdx8FsN2iFehow== x-goog-storage-class: MULTI_REGIONAL accept-ranges: bytes content-length: 108029 access-control-allow-origin: * access-control-expose-headers: Authorization, Content-Length, Content-Type, Date, Server, Transfer-Encoding, X-GUploader-UploadID, X-Google-Trace, accept, elastic-api-version, kbn-name, kbn-version, origin server: UploadServer date: Tue, 21 Nov 2023 14:25:07 GMT expires: Tue, 21 Nov 2023 15:25:07 GMT cache-control: public, max-age=3600,no-transform age: 2170 last-modified: Mon, 17 Jul 2023 11:28:15 GMT etag: "e85f0a595f154ddc7c16c3768857a1a3" content-type: application/json alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Host: vector.maps.elastic.co User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://deployment-host/app/maps/map Origin: https://deployment-host Connection: keep-alive Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site Pragma: no-cache Cache-Control: no-cache
x-guploader-uploadid: ABPtcPoUFrCmjBeebnfRxSZp44ZHsZ-_iQg7794RU1Z7Lb2cNNxXsMRkIDa5s7VBEfyehvo-_9rcm1A3HfYW8geguUxKrw x-goog-generation: 1689593295246576 x-goog-metageneration: 1 x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 108029 content-encoding: gzip x-goog-hash: crc32c=T5gVpw== x-goog-hash: md5=6F8KWV8VTdx8FsN2iFehow== x-goog-storage-class: MULTI_REGIONAL accept-ranges: bytes content-length: 108029 access-control-allow-origin: * access-control-expose-headers: Authorization, Content-Length, Content-Type, Date, Server, Transfer-Encoding, X-GUploader-UploadID, X-Google-Trace, accept, elastic-api-version, kbn-name, kbn-version, origin server: UploadServer date: Tue, 21 Nov 2023 11:24:45 GMT expires: Tue, 21 Nov 2023 12:24:45 GMT cache-control: public, max-age=3600,no-transform age: 3101 last-modified: Mon, 17 Jul 2023 11:28:15 GMT etag: "e85f0a595f154ddc7c16c3768857a1a3" content-type: application/json alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 X-Firefox-Spdy: h2
Headers for a sample Dataset from the File Service in TopoJSON format.
Details
curl -I 'https://vector.maps.elastic.co/files/world_countries_v7.topo.json?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=8.13.4' \ -H 'User-Agent: curl/7.81.0' \ -H 'Accept: */*' \ -H 'Accept-Encoding: gzip, deflate, br'
Server response
HTTP/2 200 x-guploader-uploadid: ABPtcPpmMffchVgfHIr-SSC00WORo145oV-1q0asjqRvjLV_7cIgyfLRfofXV-BG7huMYABFypblcgdgXRBARhpo2c88ow x-goog-generation: 1689593325442971 x-goog-metageneration: 1 x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 587241 content-encoding: gzip x-goog-hash: crc32c=OcROeg== x-goog-hash: md5=8KKIwD6wbKa3YYXTnnFcZw== x-goog-storage-class: MULTI_REGIONAL accept-ranges: bytes content-length: 587241 access-control-allow-origin: * access-control-expose-headers: Authorization, Content-Length, Content-Type, Date, Server, Transfer-Encoding, X-GUploader-UploadID, X-Google-Trace, accept, elastic-api-version, kbn-name, kbn-version, origin server: UploadServer date: Tue, 21 Nov 2023 14:22:16 GMT expires: Tue, 21 Nov 2023 15:22:16 GMT cache-control: public, max-age=3600,no-transform age: 2202 last-modified: Mon, 17 Jul 2023 11:28:45 GMT etag: "f0a288c03eb06ca6b76185d39e715c67" content-type: application/json alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Host: vector.maps.elastic.co User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://deployment-host/app/maps/map Origin: https://deployment-host Connection: keep-alive Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site Pragma: no-cache Cache-Control: no-cache
x-guploader-uploadid: ABPtcPqIDSg5tyavvwwtJQa8a8iycoXOCkHBp_2YJbJJnQgb5XMD7nFwRUogg00Ou27VFIs95v7L99OMnvXR1bcb9RW-xQ x-goog-generation: 1689593325442971 x-goog-metageneration: 1 x-goog-stored-content-encoding: gzip x-goog-stored-content-length: 587241 content-encoding: gzip x-goog-hash: crc32c=OcROeg== x-goog-hash: md5=8KKIwD6wbKa3YYXTnnFcZw== x-goog-storage-class: MULTI_REGIONAL accept-ranges: bytes content-length: 587241 access-control-allow-origin: * access-control-expose-headers: Authorization, Content-Length, Content-Type, Date, Server, Transfer-Encoding, X-GUploader-UploadID, X-Google-Trace, accept, elastic-api-version, kbn-name, kbn-version, origin server: UploadServer date: Tue, 21 Nov 2023 12:16:01 GMT expires: Tue, 21 Nov 2023 13:16:01 GMT cache-control: public, max-age=3600,no-transform age: 29 last-modified: Mon, 17 Jul 2023 11:28:45 GMT etag: "f0a288c03eb06ca6b76185d39e715c67" content-type: application/json alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 X-Firefox-Spdy: h2
Disable Elastic Maps Service
editYou might experience EMS connection issues if your Kibana server or browser are on a private network or behind a firewall. If this happens, you can disable the EMS connection to avoid unnecessary EMS requests.
To disable EMS, change your kibana.yml file.
-
Set
map.includeElasticMapsService
tofalse
to turn off the EMS connection. -
Set
map.tilemap.url
to the URL of your tile server. This configures the default tile layer of Maps.
Host Elastic Maps Service locally
editFind more details about installing Elastic components in an air-gapped environment in the Elastic Stack documentation.
If you cannot connect to Elastic Maps Service from the Kibana server or browser clients, and your cluster has the appropriate license level, you can opt to host the service on your own infrastructure.
Elastic Maps Server is a self-managed version of Elastic Maps Service offered as a Docker image that provides both the EMS basemaps and EMS boundaries. The image is bundled with basemaps up to zoom level 8. After connecting it to your Elasticsearch cluster for license validation, you have the option to download and configure a more detailed basemaps database.
You can use docker pull
to download the Elastic Maps Server image from the Elastic Docker registry.
docker pull docker.elastic.co/elastic-maps-service/elastic-maps-server-ubi8:8.13.4
Start Elastic Maps Server and expose the default port 8080
:
docker run --rm --init --publish 8080:8080 \ docker.elastic.co/elastic-maps-service/elastic-maps-server-ubi8:8.13.4
Once Elastic Maps Server is running, follow instructions from the webpage at localhost:8080
to define a configuration file and optionally download a more detailed basemaps database.
Configuration
editElastic Maps Server reads properties from a configuration file in YAML format that is validated on startup. The location of this file is provided by the EMS_PATH_CONF
container environment variable and defaults to /usr/src/app/server/config/elastic-maps-server.yml
. This environment variable can be changed by making use of the -e
docker flag of the start command.
General settings
Specifies the host of the backend server. To allow remote users to connect, set the value to the IP address or DNS name of the Elastic Maps Server container. Default: your-hostname. Equivalent Kibana setting. |
|
|
Specifies the port used by the backend server. Default: |
|
Specify a path at which to mount the server if you are running behind a proxy. This setting cannot end in a slash ( |
|
Controls the display of the status page and the layer preview. Default: |
|
Verbosity of Elastic Maps Server logs. Valid values are |
|
Path of the basemaps database. Default: |
Elasticsearch connection and security settings
|
URL of the Elasticsearch instance to use for license validation. |
|
Credentials of a user with at least the |
|
Paths to one or more PEM-encoded X.509 certificate authority (CA) certificates that make up a trusted certificate chain for Elastic Maps Server. This chain is used by Elastic Maps Server to establish trust when connecting to your Elasticsearch cluster. Equivalent Kibana setting. |
|
Optional settings that provide the paths to the PEM-format SSL certificate and key files and the key password. These files are used to verify the identity of Elastic Maps Server to Elasticsearch and are required when |
|
Controls the verification of the server certificate that Elastic Maps Server receives when making an outbound SSL/TLS connection to Elasticsearch. Valid values are " |
Server security settings
|
Enables SSL/TLS for inbound connections to Elastic Maps Server. When set to |
|
Paths to one or more PEM-encoded X.509 certificate authority (CA) certificates that make up a trusted certificate chain for Elastic Maps Server. This chain is used by the Elastic Maps Server to establish trust when receiving inbound SSL/TLS connections from end users. Equivalent Kibana setting. |
|
Location of yor SSL key and certificate files and the password that decrypts the private key that is specified via |
|
An array of supported protocols with versions.
Valid protocols: |
|
Details on the format, and the valid options, are available via the
OpenSSL cipher list format documentation.
Default: |
Bind-mounted configuration
editOne way to configure Elastic Maps Server is to provide elastic-maps-server.yml
via bind-mounting. With docker-compose
, the bind-mount can be specified like this:
version: '2' services: Elastic Maps Server: image: docker.elastic.co/elastic-maps-service/elastic-maps-server-ubi8:8.13.4 volumes: - ./elastic-maps-server.yml:/usr/src/app/server/config/elastic-maps-server.yml
Environment variable configuration
editAll configuration settings can be overridden by environment variables that are named with all uppercase letters and by replacing YAML periods with underscores. For example elasticsearch.ssl.certificate
could be overridden by the environment variable ELASTICSEARCH_SSL_CERTIFICATE
. Boolean variables must use the true
or false
strings.
All information that you include in environment variables is visible through the ps
command, including sensitive information.
These variables can be set with docker-compose
like this:
version: '2' services: Elastic Maps Server: image: docker.elastic.co/elastic-maps-service/elastic-maps-server-ubi8:8.13.4 environment: ELASTICSEARCH_HOST: http://elasticsearch.example.org ELASTICSEARCH_USERNAME: 'ems' ELASTICSEARCH_PASSWORD: 'changeme'
Data
editElastic Maps Server hosts vector layer boundaries and vector tile basemaps for the entire planet. Boundaries include world countries, global administrative regions, and specific country regions. Basemaps up to zoom level 8 are bundled in the Docker image. These basemaps are sufficient for maps and dashboards at the country level. To present maps with higher detail, follow the instructions of the front page to download and configure the appropriate basemaps database. The most detailed basemaps at zoom level 14 are good for street level maps, but require ~90GB of disk space.
The available basemaps and boundaries can be explored from the /maps
endpoint in a web page that is your self-managed equivalent to https://maps.elastic.co.
Kibana configuration
editWith Elastic Maps Server running, add the map.emsUrl
configuration key in your kibana.yml file pointing to the root of the service. This setting will point Kibana to request EMS basemaps and boundaries from Elastic Maps Server. Typically this will be the URL to the host and port of Elastic Maps Server. For example, map.emsUrl: https://my-ems-server:8080
.
Status check
editElastic Maps Server periodically runs a status check that is exposed in three different forms:
- At the root of Elastic Maps Server, a web page will render the status of the different services.
-
A JSON representation of Elastic Maps Server status is available at the
/status
endpoint. -
The Docker
HEALTHCHECK
instruction is run by default and will inform about the health of the service, running a process equivalent to the/status
endpoint.
Elastic Maps Server won’t respond to any data request if the license validation is not fulfilled.
Logging
editLogs are generated in ECS JSON format and emitted to the standard output and to /var/log/elastic-maps-server/elastic-maps-server.log
. The server won’t rotate the logs automatically but the logrotate
tool is installed in the image. Mount /dev/null
to the default log path if you want to disable the output to that file.