|
| 1 | +--- |
| 2 | +mapped_pages: |
| 3 | + - https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/connecting.html |
| 4 | +--- |
| 5 | + |
| 6 | +# Connecting [connecting] |
| 7 | + |
| 8 | +This page contains the information you need to connect and use the Client with {{es}}. |
| 9 | + |
| 10 | +### Connecting to Elastic Cloud [connecting-to-elastic-cloud] |
| 11 | + |
| 12 | +If you are using [Elastic Cloud](https://www.elastic.co/cloud), the client offers an easy way to connect to it. You must pass the Cloud ID that you can find in the cloud console and the corresponding API key. |
| 13 | + |
| 14 | +```go |
| 15 | +cfg := elasticsearch.Config{ |
| 16 | + CloudID: "CLOUD_ID", |
| 17 | + APIKey: "API_KEY" |
| 18 | +} |
| 19 | +es, err := elasticsearch.NewClient(cfg) |
| 20 | +``` |
| 21 | + |
| 22 | +::::{important} |
| 23 | +you need to copy and store the `API key` in a secure place since you will not be able to view it again in Elastic Cloud. |
| 24 | +:::: |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +### Connecting to a self-managed cluster [connecting-to-self-managed] |
| 29 | + |
| 30 | +Starting from version 8.0, {{es}} offers security by default with authentication and TLS enabled. |
| 31 | + |
| 32 | +To connect to the {{es}} cluster you need to configure the client to use the generated CA certificate. If you’re just getting started with {{es}} we recommend reading the documentation on configuring and starting {{es}} to ensure your cluster is running as expected. |
| 33 | + |
| 34 | +When you start {{es}} for the first time you’ll see a distinct block like the one below in the output from {{es}} (you may have to scroll up if it’s been a while): |
| 35 | + |
| 36 | +```sh |
| 37 | +---------------------------------------------------------------- |
| 38 | +-> Elasticsearch security features have been automatically configured! |
| 39 | +-> Authentication is enabled and cluster connections are encrypted. |
| 40 | +-> Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`): |
| 41 | + lhQpLELkjkrawaBoaz0Q |
| 42 | +-> HTTP CA certificate SHA-256 fingerprint: |
| 43 | + a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228 |
| 44 | +... |
| 45 | +---------------------------------------------------------------- |
| 46 | +``` |
| 47 | + |
| 48 | +Note down the `elastic` user password and HTTP CA fingerprint for the next sections. In the examples below they will be stored in the variables `ELASTIC_PASSWORD` and `CERT_FINGERPRINT` respectively. |
| 49 | + |
| 50 | +Depending on the circumstances there are two options for verifying the HTTPS connection, either verifying with the CA certificate itself or via the HTTP CA certificate fingerprint. |
| 51 | + |
| 52 | + |
| 53 | +### Verifying HTTPS with CA certificates [verifying-with-ca] |
| 54 | + |
| 55 | +The generated root CA certificate can be found in the `certs` directory in your {{es}} config location (`$ES_CONF_PATH/certs/http_ca.crt`). If you’re running {{es}} in Docker there is [additional documentation for retrieving the CA certificate](docs-content://deploy-manage/deploy/self-managed/install-elasticsearch-with-docker.md). |
| 56 | + |
| 57 | +Once you have the `http_ca.crt` file somewhere accessible pass the content of the file to the client via `CACert`: |
| 58 | + |
| 59 | +```go |
| 60 | +cert, _ := os.ReadFile("/path/to/http_ca.crt") |
| 61 | + |
| 62 | +cfg := elasticsearch.Config{ |
| 63 | + Addresses: []string{ |
| 64 | + "https://localhost:9200", |
| 65 | + }, |
| 66 | + Username: "elastic", |
| 67 | + Password: ELASTIC_PASSWORD |
| 68 | + CACert: cert |
| 69 | +} |
| 70 | +es, err := elasticsearch.NewClient(cfg) |
| 71 | +``` |
| 72 | + |
| 73 | + |
| 74 | +### Verifying HTTPS with certificate fingerprint [verifying-with-fingerprint] |
| 75 | + |
| 76 | +This method of verifying the HTTPS connection takes advantage of the certificate fingerprint value noted down earlier. Take this SHA256 fingerprint value and pass it to the Go {{es}} client via `ca_fingerprint`: |
| 77 | + |
| 78 | +```go |
| 79 | +cfg := elasticsearch.Config{ |
| 80 | + Addresses: []string{ |
| 81 | + "https://localhost:9200", |
| 82 | + }, |
| 83 | + Username: "elastic", |
| 84 | + Password: ELASTIC_PASSWORD |
| 85 | + CertificateFingerprint: CERT_FINGERPRINT |
| 86 | +} |
| 87 | +es, err := elasticsearch.NewClient(cfg) |
| 88 | +``` |
| 89 | + |
| 90 | +The certificate fingerprint can be calculated using openssl x509 with the certificate file: |
| 91 | + |
| 92 | +```sh |
| 93 | +openssl x509 -fingerprint -sha256 -noout -in /path/to/http_ca.crt |
| 94 | +``` |
| 95 | + |
| 96 | +If you don’t have access to the generated CA file from {{es}} you can use the following script to output the root CA fingerprint of the {{es}} instance with `openssl s_client`: |
| 97 | + |
| 98 | +```sh |
| 99 | +# Replace the values of 'localhost' and '9200' to the |
| 100 | +# corresponding host and port values for the cluster. |
| 101 | +openssl s_client -connect localhost:9200 -servername localhost -showcerts </dev/null 2>/dev/null \ |
| 102 | + | openssl x509 -fingerprint -sha256 -noout -in /dev/stdin |
| 103 | +``` |
| 104 | + |
| 105 | +The output of `openssl x509` will look something like this: |
| 106 | + |
| 107 | +```sh |
| 108 | +SHA256 Fingerprint=A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28 |
| 109 | +``` |
| 110 | + |
| 111 | + |
| 112 | +### Connecting without security enabled [connecting-without-security] |
| 113 | + |
| 114 | +::::{warning} |
| 115 | +Running {{es}} without security enabled is not recommended. |
| 116 | +:::: |
| 117 | + |
| 118 | + |
| 119 | +If your cluster is configured with [security explicitly disabled](elasticsearch://docs/reference/elasticsearch/configuration-reference/security-settings.md) then you can connect via HTTP: |
| 120 | + |
| 121 | +```go |
| 122 | +cfg := elasticsearch.Config{ |
| 123 | + Addresses: []string{ |
| 124 | + "http://localhost:9200", |
| 125 | + }, |
| 126 | +} |
| 127 | +es, err := elasticsearch.NewClient(cfg) |
| 128 | +``` |
| 129 | + |
| 130 | + |
| 131 | +### Connecting to multiple nodes [connecting-multiple-nodes] |
| 132 | + |
| 133 | +The Go {{es}} client supports sending API requests to multiple nodes in the cluster. This means that work will be more evenly spread across the cluster instead of hammering the same node over and over with requests. To configure the client with multiple nodes you can pass a list of URLs, each URL will be used as a separate node in the pool. |
| 134 | + |
| 135 | +```go |
| 136 | +cfg := elasticsearch.Config{ |
| 137 | + Addresses: []string{ |
| 138 | + "https://localhost:9200", |
| 139 | + "https://localhost:9201", |
| 140 | + }, |
| 141 | + CACert: caCert, |
| 142 | + Username: "elastic", |
| 143 | + Password: ELASTIC_PASSWORD, |
| 144 | +} |
| 145 | +es, err := elasticsearch.NewClient(cfg) |
| 146 | +``` |
| 147 | + |
| 148 | +By default nodes are selected using round-robin, but alternate node selection strategies can be implemented via the `elastictransport.Selector` interface and provided to the client configuration. |
| 149 | + |
| 150 | +::::{note} |
| 151 | +If your {{es}} cluster is behind a load balancer like when using Elastic Cloud you won’t need to configure multiple nodes. Instead use the load balancer host and port. |
| 152 | +:::: |
| 153 | + |
| 154 | + |
| 155 | + |
| 156 | +## Authentication [auth-reference] |
| 157 | + |
| 158 | +This section contains code snippets to show you how to authenticate with {{es}}. |
| 159 | + |
| 160 | + |
| 161 | +### Basic authentication [auth-basic] |
| 162 | + |
| 163 | +To set the cluster endpoints, the username, and the password programatically, pass a configuration object to the `elasticsearch.NewClient()` function. |
| 164 | + |
| 165 | +```go |
| 166 | +cfg := elasticsearch.Config{ |
| 167 | + Addresses: []string{ |
| 168 | + "https://localhost:9200", |
| 169 | + "https://localhost:9201", |
| 170 | + }, |
| 171 | + Username: "foo", |
| 172 | + Password: "bar", |
| 173 | +} |
| 174 | +es, err := elasticsearch.NewClient(cfg) |
| 175 | +``` |
| 176 | + |
| 177 | +You can also include the username and password in the endpoint URL: |
| 178 | + |
| 179 | +``` |
| 180 | +'https://username:password@localhost:9200' |
| 181 | +``` |
| 182 | + |
| 183 | + |
| 184 | +### HTTP Bearer authentication [auth-token] |
| 185 | + |
| 186 | +HTTP Bearer authentication uses the `ServiceToken` parameter by passing the token as a string. This authentication method is used by [Service Account Tokens](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-create-service-token) and [Bearer Tokens](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-get-token). |
| 187 | + |
| 188 | +```go |
| 189 | +cfg := elasticsearch.Config{ |
| 190 | + Addresses: []string{ |
| 191 | + "https://localhost:9200", |
| 192 | + }, |
| 193 | + ServiceToken: "token-value", |
| 194 | +} |
| 195 | +es, err := elasticsearch.NewClient(cfg) |
| 196 | +``` |
| 197 | + |
| 198 | + |
| 199 | +## Compatibility mode [compatibility-mode] |
| 200 | + |
| 201 | +The {{es}} server version 8.0 is introducing a new compatibility mode that allows you a smoother upgrade experience from 7 to 8. In a nutshell, you can use the latest 7.x `go-elasticsearch` Elasticsearch client with an 8.x Elasticsearch server, giving more room to coordinate the upgrade of your codebase to the next major version. |
| 202 | + |
| 203 | +If you want to leverage this functionality, please make sure that you are using the latest 7.x `go-elasticsearch` client and set the environment variable `ELASTIC_CLIENT_APIVERSIONING` to `true` or the configuration option `config.EnableCompatibilityMode` in the client `Config`. The client is handling the rest internally. For every 8.0 and beyond `go-elasticsearch` client, you’re all set! The compatibility mode is enabled by default. |
| 204 | + |
| 205 | + |
| 206 | +## Using the client [client-usage] |
| 207 | + |
| 208 | +The {{es}} package ties together two separate packages for calling the Elasticsearch APIs and transferring data over HTTP: `esapi` and `estransport`, respectively. |
| 209 | + |
| 210 | +Use the `elasticsearch.NewDefaultClient()` function to create the client with the default settings. |
| 211 | + |
| 212 | +```go |
| 213 | +es, err := elasticsearch.NewDefaultClient() |
| 214 | +if err != nil { |
| 215 | + log.Fatalf("Error creating the client: %s", err) |
| 216 | +} |
| 217 | + |
| 218 | +res, err := es.Info() |
| 219 | +if err != nil { |
| 220 | + log.Fatalf("Error getting response: %s", err) |
| 221 | +} |
| 222 | + |
| 223 | +defer res.Body.Close() |
| 224 | +log.Println(res) |
| 225 | +``` |
| 226 | + |
| 227 | + |
| 228 | +## Using the client in a function-as-a-service environment [connecting-faas] |
| 229 | + |
| 230 | +This section illustrates the best practices for leveraging the {{es}} client in a Function-as-a-Service (FaaS) environment. The most influential optimization is to initialize the client outside of the function, the global scope. This practice does not only improve performance but also enables background functionality as – for example – [sniffing](https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how). The following examples provide a skeleton for the best practices. |
| 231 | + |
| 232 | + |
| 233 | +### GCP Cloud Functions [connecting-faas-gcp] |
| 234 | + |
| 235 | +```go |
| 236 | +package httpexample |
| 237 | + |
| 238 | +import ( |
| 239 | + "github.com/elastic/go-elasticsearch/v8" |
| 240 | +) |
| 241 | + |
| 242 | +var client *elasticsearch.Client |
| 243 | + |
| 244 | +func init() { |
| 245 | + var err error |
| 246 | + |
| 247 | + ... # Client configuration |
| 248 | + client, err = elasticsearch.NewClient(cfg) |
| 249 | + if err != nil { |
| 250 | + log.Fatalf("elasticsearch.NewClient: %v", err) |
| 251 | + } |
| 252 | +} |
| 253 | + |
| 254 | +func HttpExample(w http.ResponseWriter, r *http.Request) { |
| 255 | + ... # Client usage |
| 256 | +} |
| 257 | +``` |
| 258 | + |
| 259 | + |
| 260 | +### AWS Lambda [connecting-faas-aws] |
| 261 | + |
| 262 | +```go |
| 263 | +package httpexample |
| 264 | + |
| 265 | +import ( |
| 266 | + "github.com/aws/aws-lambda-go/lambda" |
| 267 | + "github.com/elastic/go-elasticsearch/v8" |
| 268 | +) |
| 269 | + |
| 270 | +var client *elasticsearch.Client |
| 271 | + |
| 272 | +func init() { |
| 273 | + var err error |
| 274 | + |
| 275 | + ... # Client configuration |
| 276 | + client, err = elasticsearch.NewClient(cfg) |
| 277 | + if err != nil { |
| 278 | + log.Fatalf("elasticsearch.NewClient: %v", err) |
| 279 | + } |
| 280 | +} |
| 281 | + |
| 282 | +func HttpExample() { |
| 283 | + ... # Client usage |
| 284 | +} |
| 285 | + |
| 286 | +func main() { |
| 287 | + lambda.Start(HttpExample) |
| 288 | +} |
| 289 | +``` |
| 290 | + |
| 291 | +Resources used to assess these recommendations: |
| 292 | + |
| 293 | +* [GCP Cloud Functions: Tips & Tricks](https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations) |
| 294 | +* [Best practices for working with AWS Lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.md) |
| 295 | +* [AWS Lambda: Comparing the effect of global scope](https://docs.aws.amazon.com/lambda/latest/operatorguide/global-scope.md) |
0 commit comments