[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Building a data platform](index.md) > Configuring a cold storage policy in Managed Service for OpenSearch

# Configuring a cold storage policy in Yandex Managed Service for OpenSearch

# Configuring a cold storage policy in Yandex Managed Service for OpenSearch


You can use [policies](../../managed-opensearch/concepts/index-policy.md) to automate some operations with indexes. For example, to optimize the use of storage, you can set a policy that will move _cold_ data to a specific host group and then repack that data using a [codec](../../managed-opensearch/concepts/indexing.md#codecs) with a higher compression ratio.

To configure such a policy:

1. [Set up your infrastructure](#infrastructure-prepare).
1. [Create a policy](#create-policy).
1. [Attach the policy to an index](#attach-policy).
1. [Test the policy](#check-policy).

If you no longer need the resources you created, [delete them](#clear-out).


## Getting started {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

* Managed Service for OpenSearch cluster: use of computing resources, storage and backup size (see [Managed Service for OpenSearch pricing](../../managed-opensearch/pricing.md)).
* Public IP addresses if public access is enabled for cluster hosts (see [Yandex Virtual Private Cloud pricing](../../vpc/pricing.md)).


## Set up your infrastructure {#infrastructure-prepare}

1. Prepare a Managed Service for OpenSearch cluster:

    {% list tabs group=instructions %}

    - Manually {#manual}

        1. [Create a Managed Service for OpenSearch cluster](../../managed-opensearch/operations/cluster-create.md#create-cluster) in any suitable configuration with the following settings:

            * Two or more host groups with the `DATA` role. Give two groups the names `hot` and `cold`.
            * Public access to any host group.

        1. If there are security groups in your cluster, make sure they allow connections to the [Managed Service for OpenSearch](../../managed-opensearch/operations/connect/index.md#configuring-security-groups).

    - Using Terraform {#tf}

        1. If you do not have Terraform yet, [install it](../infrastructure-management/terraform-quickstart.md#install-terraform).
        1. [Get the authentication credentials](../infrastructure-management/terraform-quickstart.md#get-credentials). You can add them to environment variables or specify them later in the provider configuration file.
        1. [Configure and initialize a provider](../infrastructure-management/terraform-quickstart.md#configure-provider). There is no need to create a provider configuration file manually, you can [download it](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
        1. Place the configuration file in a separate working directory and [specify the parameter values](../infrastructure-management/terraform-quickstart.md#configure-provider). If you did not add the authentication credentials to environment variables, specify them in the configuration file.

        1. Download the [opensearch-cold-storage-policy.tf](https://github.com/yandex-cloud-examples/yc-opensearch-cold-storage-policy/blob/main/opensearch-cold-storage-policy.tf) configuration file to the same working directory. This file describes:

            * [Network](../../vpc/concepts/network.md#network).
            * [Subnets](../../vpc/concepts/network.md#subnet).
            * [Security group](../../vpc/concepts/security-groups.md) and rules for connection to a Managed Service for OpenSearch cluster.
            * Managed Service for OpenSearch cluster.

        1. In the `opensearch-cold-storage-policy.tf` file, specify the following variables:

            * `version`: OpenSearch version.
            * `admin_password`: OpenSearch admin password.

        1. Validate your Terraform configuration files using this command:

            ```bash
            terraform validate
            ```

            Terraform will display any configuration errors detected in your files.

        1. Create the required infrastructure:

            1. Run this command to view the planned changes:
            
               ```bash
               terraform plan
               ```
            
               If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
            
            1. If everything looks correct, apply the changes:
               1. Run this command:
            
                  ```bash
                  terraform apply
                  ```
            
               1. Confirm updating the resources.
               1. Wait for the operation to complete.

            All the required resources will be created in the specified folder. You can check resource availability and their settings in the [management console](https://console.yandex.cloud).

    {% endlist %}

1. [Install an SSL certificate](../../managed-opensearch/operations/connect/index.md#ssl-certificate).

1. Check the connection to the cluster using [cURL](https://curl.haxx.se/):

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --request GET 'https://<FQDN_of_OpenSearch_host_with_public_access>:9200/'
    ```
    
    You can get the host FQDN with the [list of hosts in the cluster](../../managed-opensearch/operations/host-groups.md#list-hosts).
    
    If the connection is successful, you will see a message like this:
    
    ```bash
    {
      "name" : "....mdb.yandexcloud.net",
      "cluster_name" : "...",
      "cluster_uuid" : "...",
      "version" : {
      "distribution" : "opensearch",
      ...
      },
      "tagline" : "The OpenSearch Project: https://opensearch.org/"
    }
    ```

## Create a policy {#create-policy}

Create a policy that turns _hot_ data to _cold_ followed by archiving:

```bash
curl \
    --user admin:<password> \
    --cacert ~/.opensearch/root.crt \
    --header 'Content-Type: application/json' \
    --request PUT 'https://<OpenSearch_host_address_with_public_access>:9200/_plugins/_ism/policies/archive_policy' \
    --data '
        {
            "policy": {
                "description": "Example archive policy",
                "default_state": "hot",
                "schema_version": 1,
                "states": [
                    {
                        "name": "hot",
                        "actions": [
                            {
                                "allocation": {
                                    "require": { "groupname": "hot" }
                                }
                            }
                        ],
                        "transitions": [
                            {
                                "state_name": "cold",
                                "conditions": {
                                    "min_index_age": "1h"
                                }
                            }
                        ]
                    },
                    {
                        "name": "cold",
                        "actions": [
                            {
                                "allocation": {
                                    "require": { "groupname": "cold" }
                                }
                            }
                        ],
                        "transitions": [
                            {
                                "state_name": "archive",
                                "conditions": {
                                    "min_index_age": "2h"
                                }
                            }
                        ]
                    },
                    {
                        "name": "archive",
                        "actions": [
                            {
                                "repack": {
                                    "new_codec": "lzma"
                                }
                            }
                        ]
                    }
                ],
                "ism_template": {
                    "index_patterns": ["log*"],
                    "priority": 100
                }
            }
        }'
```

Where:

* `min_index_age`: Index age that triggers creation of a new index. The recommended value is 30 days (`30d`).
* `index_patterns`: Template for a new index name.
* `new_codec`: Name of the codec to repack the data.

For a quick test of the policy, the request example has the following `min_index_age` settings:
* For `hot`: 1 hour. After this time elapses, the data will turn _cold_.
* For `cold`: 2 hours. After this time elapses, the data will be repacked by the `lzma` codec (archiving).

You can specify smaller values but not less than five minutes: this is the default time after which the policy conditions are checked again.

## Attach the policy to an index {#attach-policy}

1. Create the `log-000001` index:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request PUT 'https://<OpenSearch_host_address_with_public_access>:9200/log-000001?pretty' \
        --data '
            {
                "settings": {
                    "index" : {
                        "routing" : {
                            "allocation" : {
                                "require" : {
                                    "groupname" : "hot"
                                }
                            }
                        }
                    }
                }
            }'
    ```

1. Check whether the policy is attached to the index:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_plugins/_ism/explain/log-000001?pretty'
    ```

    You will get a message similar to the following:

    ```bash
    {
      "log-000001" : {
        "index.plugins.index_state_management.policy_id" : "archive_policy",
        "index.opendistro.index_state_management.policy_id" : "archive_policy",
        "index" : "log-000001",
        "index_uuid" : "...",
        "policy_id" : "archive_policy",
        "enabled" : true
      },
      "total_managed_indices" : 1
    }
    ```

## Test the policy {#check-policy}

1. Add a document to the index:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request POST 'https://<OpenSearch_host_address_with_public_access>:9200/log-000001/_doc?pretty' \
        --data '
            {
                "num": "101",
                "name": "Valya",
                "age": "25"
            }'
    ```

1. Get a list of index shards five minutes after the document is created:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_cat/shards/log-000001?pretty'
    ```

    The results will display the shards of the `log-000001` index and the addresses of the hosts the shards reside on:

    ```bash
    log-000001 0 r STARTED 1 5.2kb 10.2.0.35 rc1b-lgio8pjp********.mdb.yandexcloud.net
    log-000001 0 p STARTED 1 5.2kb 10.1.0.4  rc1a-g36ksm4q********.mdb.yandexcloud.net 
    ```

1. Make sure the shard is located in the host group named `hot`. To do this, get a list of hosts with these attributes:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_cat/nodeattrs/?v&h=node,attr,value&pretty'
    ```

    The results will contain the following lines:

    ```bash
    node                                       attr       value
    rc1b-lgio8pjp********.mdb.yandexcloud.net  groupname  hot
    rc1a-g36ksm4q********.mdb.yandexcloud.net  groupname  hot
    ...
    ```

1. Get a list of shards for the `log-000001` index again one hour after [creating the index](#attach-policy):

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_cat/shards/log-000001?pretty'
    ```

    One hour is the policy condition for moving the index to the host group named `cold`.

    The results will display the shards of the `log-000001` index and the new addresses of the hosts the shards reside on:

    ```bash
    log-000001 0 r STARTED 1 5.2kb 10.2.0.22 rc1b-is77nbdv********.mdb.yandexcloud.net
    log-000001 0 p STARTED 1 5.2kb 10.1.0.25 rc1a-qocaisq1********.mdb.yandexcloud.net
    ```

1. Re-request a list of hosts with these attributes:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_cat/nodeattrs/?v&h=node,attr,value&pretty'
    ```

    The results will contain the following lines:

    ```bash
    node                                       attr       value
    rc1b-is77nbdv********.mdb.yandexcloud.net  groupname  cold
    rc1a-qocaisq1********.mdb.yandexcloud.net  groupname  cold
    ...
    ```

1. Another hour later, get a list of shards for the `log-000001` index again:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/_cat/shards/log-000001?pretty'
    ```

    Two hours is the policy condition for applying the new codec (transfer to archive).

    The results will display the shards of the `log-000001` index and the addresses of the hosts the shards reside on:

    ```bash
    log-000001 0 r STARTED 1 4.8kb 10.2.0.22 rc1b-is77nbdv********.mdb.yandexcloud.net
    log-000001 0 p STARTED 1 4.8kb 10.1.0.25 rc1a-qocaisq1********.mdb.yandexcloud.net 
    ```

    The shards will now be smaller because the data was repacked by a new codec with a higher compression ratio.

1. Get the index settings and make sure the `lzma` codec is listed in them:

    ```bash
    curl \
        --user admin:<password> \
        --cacert ~/.opensearch/root.crt \
        --header 'Content-Type: application/json' \
        --request GET 'https://<OpenSearch_host_address_with_public_access>:9200/log-000001/_settings?pretty'
    ```

    Result:

    ```bash
    {
      "log-000001" : {
        "settings" : {
          "index" : {
            ...
            "codec" : "lzma",
            "routing" : {
              "allocation" : {
                "require" : {
                  "groupname" : "cold"
                }
              }
            },
            ...
          }
        }
      }
    }
   ```

## Delete the resources you created {#clear-out}

Some resources are not free of charge. Delete the resources you no longer need to avoid paying for them:

{% list tabs group=instructions %}

- Manually {#manual}

    [Delete the Managed Service for OpenSearch cluster](../../managed-opensearch/operations/cluster-delete.md).

- Using Terraform {#tf}

    1. In the terminal window, go to the directory containing the infrastructure plan.
    
        {% note warning %}
    
        Make sure the directory has no Terraform manifests with the resources you want to keep. Terraform deletes all resources that were created using the manifests in the current directory.
    
        {% endnote %}
    
    1. Delete resources:
    
        1. Run this command:
    
            ```bash
            terraform destroy
            ```
    
        1. Confirm deleting the resources and wait for the operation to complete.
    
        All the resources described in the Terraform manifests will be deleted.

{% endlist %}