[[providers]]
== Providers

Providers supply the key/values pairs that are used for variable substitution
and conditionals. Each provider's keys are automatically prefixed with the name
of the provider in the context of the {agent}.

For example, if a provider named `foo` provides
`{"key1": "value1", "key2": "value2"}`, the key/value pairs are placed in
`{"foo" : {"key1": "value1", "key2": "value2"}}`. To reference the keys, you
would use `{{foo.key1}}` and `{{foo.key2}}`.

=== Provider configuration

The provider configuration is specified under the top-level `providers`
key in the `elastic-agent.yml` configuration. By default, all registered
providers are enabled. If a provider cannot connect, it produces no mappings.

The following example shows two providers, `local` and `local_dynamic`, that
supply custom keys:

[source,yaml]
----
providers:
  local:
    vars:
      foo: bar
  local_dynamic:
    vars:
      - item: key1
      - item: key2
----

To explicitly disable a provider, set `enabled: false`. Because all providers
are prefixed and have no name collisions, the name of the provider is the key in
the configuration.

[source,yaml]
----
providers:
  docker:
    enabled: false
----

{agent} supports two broad types of providers: <<context-providers,context>> and
<<dynamic-providers,dynamic>>.

[[context-providers]]
=== Context providers

Context providers provide the current context of the running {agent}, for
example, agent information (id, version), host information (hostname, IP
addresses), and environment information (environment variables).

They can only provide a single key/value mapping. Think of them as singletons;
an update of a key/value mapping will result in a re-evaluation of the entire
configuration. These providers are normally very static, but that's not
required. It is possible for a value to change resulting in re-evaluation.

Context providers use ECS naming when possible to ensure that documentation and
understanding across projects is the same.

{agent} supports the following context providers:

[[local-provider]]
==== Local

Provides custom keys to use as variables. For example:

[source,yaml]
----
providers:
  local:
    vars:
      foo: bar
----

[[agent-provider]]
==== Agent provider

Provides information about the {agent}. The available keys are:

|===
|Key |Type |Description

|`agent.id`
|`string`
|Current agent ID

|`agent.version`
|`object`
|Current agent version information object

|`agent.version.version`
|`string`
|Current agent version

|`agent.version.commit`
|`string`
|Version commit

|`agent.version.build_time`
|`date`
|Version build time

|`agent.version.snapshot`
|`boolean`
|Version is snapshot build
|===


[[host-provider]]
==== Host provider

Provides information about the current host. The available keys are:

|===
|Key |Type |Description

|`host.name`
|`string`
|Host name

|`host.platform`
|`string`
|Host platform

|`host.architecture`
|`string`
|Host architecture

|`host.ip[]`
|`[]string`
|Host IP addresses

|`host.mac[]`
|`[]string`
|Host MAC addresses
|===

[[env-provider]]
==== Env Provider

Provides access to the environment variables as key/values.

For example, if you set the variable foo:

[source,shell]
----
foo=bar elastic-agent run
----

You can reference the environment variable as `${env.foo}`.

[[dynamic-providers]]
=== Dynamic Providers

Dynamic providers provide an array of multiple key/value mappings. Each
key/value mapping is combined with the previous context provider's key/value
mapping to provide a new unique key/value mapping that is used to generate a
configuration.

[[local-dynamic-provider]]
==== Local dynamic provider

Allows you to define multiple key/values to generate multiple configurations.

For example, the following agent policy defines a local dynamic provider that
defines 3 values for `item`:

[source,yaml]
----
inputs:
 - type: logfile
   paths: "/var/${item}/app.log"

providers:
    vars:
      - item: key1
      - item: key2
      - item: key3
----

The configuration generated by this policy looks like:

[source,yaml]
----
inputs:
 - type: logfile
   paths: "/var/key1/app.log"
 - type: logfile
   paths: "/var/key2/app.log"
 - type: logfile
   paths: "/var/key3/app.log"
----

[[docker-provider]]
==== Docker Provider

Provides inventory information from Docker. The available keys are:


|===
|Key |Type |Description

|`docker.id`
|`string`
|ID of the container

|`docker.cmd`
|`string`
|Arg path of container

|`docker.name`
|`string`
|Name of the container

|`docker.image`
|`string`
|Image of the container

|`docker.labels`
|`string`
|Labels of the container

|`docker.ports`
|`string`
|Ports of the container

|`docker.paths`
|`object`
|Object of paths for the container

|`docker.paths.log`
|`string`
|Log path of the container
|===

Imagine that the Docker provider provides the following inventory:

[source,json]
----
[
    {
       "id": "1",
       "mapping:": {"id": "1", "paths": {"log": "/var/log/containers/1.log"}},
       "processors": {"add_fields": {"container.name": "my-container"}}
    },
    {
        "id": "2",
        "mapping": {"id": "2", "paths": {"log": "/var/log/containers/2.log"}},
        "processors": {"add_fields": {"container.name": "other-container"}}
    }
]
----

{agent} automatically prefixes the result with `docker`:


[source,json]
---
[
    {"docker": {"id": "1", "paths": {"log": "/var/log/containers/1.log"}}},
    {"docker": {"id": "2", "paths": {"log": "/var/log/containers/2.log"}},
]
---

To set the log path dynamically in the configuration, use a variable in the
{agent} policy to return path information from the provider:

[source,yaml]
----
inputs:
  - type: logfile
    path: "${docker.paths.log}"
----

The policy generated by this configuration looks like:

[source,yaml]
----
inputs:
  - type: logfile
    path: "/var/log/containers/1.log"
    processors:
      - add_fields:
          container.name: my-container
  - type: logfile
    path: "/var/log/containers/2.log"
    processors:
      - add_fields:
          container.name: other-container
----
