[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Container infrastructure](index.md) > Managed Service for Kubernetes > Using Cloud Marketplace products > Editing website images with Thumbor

# Editing website images using Thumbor in Yandex Managed Service for Kubernetes

# Editing website images using Thumbor


[Thumbor](https://thumbor.readthedocs.io/en/latest/) is an [open-source](https://github.com/thumbor/thumbor) project for on-demand image processing. Thumbor provides basic settings for editing images. For example, you can use it to resize the original image, increase its contrast ratio, or remove the red-eye effect.

Thumbor is a convenient tool you can use to make images for websites, e.g., to create thumbnails for video previews. Thumbor supports image caching. This allows you to reduce labor costs for your website support.

In the example below, images are posted to a website and edited using Thumbor. The edit includes resizing and adding a watermark. To upload images faster, a CDN is configured for the website using [Yandex Cloud CDN](../../cdn/concepts/index.md).

To edit images using Thumbor and enable the CDN:

1. [Install Thumbor](#install).
1. [Prepare images for Thumbor testing](#images).
1. [Configure Cloud CDN](#cdn).
1. [Check the result](#check-result).

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


## Required paid resources {#paid-resources}

The support cost for this solution includes:

* Fee for using the master and outgoing traffic in a Managed Service for Kubernetes cluster (see [Managed Service for Kubernetes pricing](../../managed-kubernetes/pricing.md)).
* Fee for using computing resources, OS, and storage in cluster nodes (VMs) (see [Compute Cloud pricing](../../compute/pricing.md)).
* Fee for a public IP address assigned to cluster nodes (see [Virtual Private Cloud pricing](../../vpc/pricing.md#prices-public-ip)).
* Fee for an Object Storage bucket: data storage and data operations (see [Object Storage pricing](../../storage/pricing.md)).
* Fee for Cloud CDN: Outbound traffic (see [Object Storage pricing](../../cdn/pricing.md)).


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

### Set up your infrastructure {#infra}

{% list tabs group=instructions %}

- Manually {#manual}

   1. [Create these service accounts](../../iam/operations/sa/create.md):

      * Service account for the resources with the `k8s.clusters.agent` and `vpc.publicAdmin` [roles](../../managed-kubernetes/security/index.md#yc-api) for the folder where the Managed Service for Kubernetes cluster is being created. This service account will be used to create resources for the Managed Service for Kubernetes cluster.

      * Service account for nodes with the [container-registry.images.puller](../../container-registry/security/index.md#required-roles) role for the folder with the Docker image [registry](../../container-registry/concepts/registry.md). The nodes will pull Docker images from the registry under this account.

         You can use the same service account for both operations.

      * The `thumbor-sa` service account for Thumbor.

   1. [Create security groups](../../managed-kubernetes/operations/connect/security-groups.md) for the Managed Service for Kubernetes cluster and its node groups.

        {% note warning %}
        
        The configuration of security groups determines performance and availability of the cluster and the services and applications running in it.
        
        {% endnote %}

   1. [Create a Managed Service for Kubernetes cluster](../../managed-kubernetes/operations/kubernetes-cluster/kubernetes-cluster-create.md) and a [node group](../../managed-kubernetes/operations/node-group/node-group-create.md) with any suitable configuration. When creating it, specify the preconfigured security groups.
   1. [Create a bucket](../../storage/operations/buckets/create.md) in Yandex Object Storage.
   1. [Grant the `thumbor-sa` service account](../../storage/operations/objects/edit-acl.md) the `READ` permission for the bucket.

- 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 [k8s-for-thumbor.tf](https://github.com/yandex-cloud-examples/yc-mk8s-thumbor/blob/main/k8s-for-thumbor.tf) configuration file to the same working directory.

      This file describes:

      * Network.
      * Subnet.
      * Service accounts for various services:

         * For the Managed Service for Kubernetes cluster and node group.
         * For Thumbor.
         * For creating Object Storage buckets.

      * Managed Service for Kubernetes cluster.
      * Node group.
      
      * [Security groups](../../vpc/concepts/security-groups.md) which contain [rules](../../managed-kubernetes/operations/connect/security-groups.md) required for the Managed Service for Kubernetes cluster and its node groups.

        {% note warning %}
        
        The configuration of security groups determines performance and availability of the cluster and the services and applications running in it.
        
        {% endnote %}

      * Static access key for bucket creation.
      * Bucket.

   1. In `k8s-for-thumbor.tf`, specify the following:

      * [Folder ID](../../resource-manager/operations/folder/get-id.md).
      * [Kubernetes version](../../managed-kubernetes/concepts/release-channels-and-updates.md) for the Managed Service for Kubernetes cluster and node groups.

   1. Make sure the Terraform configuration file is correct using this command:

      ```bash
      terraform validate
      ```

      If the file contains any errors, Terraform will point them out.

   1. Create an 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 %}

### Install additional dependencies {#prepare}

1. If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

   The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

1. [Install kubect](https://kubernetes.io/docs/tasks/tools/install-kubectl) and [configure it to work with the new cluster](../../managed-kubernetes/operations/connect/index.md#kubectl-connect).


## Add a certificate to Certificate Manager {#add-certificate}

Certificates from [Yandex Certificate Manager](../../certificate-manager/index.md) are supported. You can [issue a new Let's Encrypt® certificate](../../certificate-manager/operations/managed/cert-create.md) or [upload one of your own](../../certificate-manager/operations/import/cert-create.md).

The certificate must be located in the same [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) as your CDN resource.

For a Let's Encrypt® certificate, pass an [ownership check](../../certificate-manager/operations/managed/cert-validate.md) for the domain specified in the certificate.


## Install Thumbor {#install}

1. Create a [static access key](../../iam/concepts/authorization/access-key.md) for the `thumbor-sa` service account and save it to the `sa-key.json` file:

   ```bash
   yc iam access-key create --service-account-name thumbor-sa \
      --format json > sa-key.json
   ```

1. [Install Thumbor](../../managed-kubernetes/operations/applications/thumbor.md) with the following settings:

   * **Namespace**: `thumbor`.
   * **Application name**: `thumbor`.
   * **Bucket name**: Bucket to which you uploaded your images.
   * **Object Storage static access key**: Contents of the `sa-key.json` file.
   * **Unsigned URLs**: Allowed.

## Prepare images for Thumbor testing {#images}

1. Download images:

   * [poster_rodents_bunnysize.jpg](https://peach.blender.org/wp-content/uploads/poster_rodents_bunnysize.jpg)
   * [poster_bunny_bunnysize.jpg](https://peach.blender.org/wp-content/uploads/poster_bunny_bunnysize.jpg)
   * [cc.xlarge.png](https://mirrors.creativecommons.org/presskit/icons/cc.xlarge.png) ([Creative Commons](https://en.wikipedia.org/wiki/Creative_Commons) logo)

1. Upload the images to the bucket:

   {% list tabs group=instructions %}

   - Manually {#manual}

      1. In the [management console](https://console.yandex.cloud), select the folder to upload an object to.
      1. Navigate to **Object Storage**.
      1. Click the bucket name.
      1. Click **Upload**.
      1. In the window that opens, select the required files and click **Open**.
      1. Click **Upload**.
      1. Refresh the page.

      In the management console, the information about the number of objects and storage space used in the bucket is updated with a few minutes' delay.

   - Terraform {#tf}

      You can only upload objects to a bucket after you create it. Therefore, a separate configuration file is used for uploading images.

      1. Download the [images-for-thumbor.tf](https://github.com/yandex-cloud-examples/yc-mk8s-thumbor/blob/main/images-for-thumbor.tf) configuration file to the working directory containing the `k8s-for-thumbor.tf` file. This file describes Object Storage objects, i.e., the images you downloaded to upload to the bucket.
      1. In the `images-for-thumbor.tf` file, specify relative or absolute paths to the images. For example, if your images are stored in the same directory as the configuration files, specify:

         * `poster_rodents_bunnysize.jpg`
         * `poster_bunny_bunnysize.jpg`
         * `cc.xlarge.png`

      1. Run the `terraform init` command in the directory with the configuration files. This command initializes the provider specified in the configuration files and enables you to use its resources and data sources.
      1. Make sure the Terraform configuration file is correct using this command:

         ```bash
         terraform validate
         ```

         If the file contains any errors, Terraform will point them out.

      1. Start image upload to the bucket:

         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 %}

## Configure the CDN {#cdn}

1. Get Thumbor's external IP address:

   ```bash
   kubectl -n thumbor get svc thumbor \
      -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
   ```

1. Create an origin group in Cloud CDN:

   ```bash
   yc cdn origin-group create \
      --name thumbor \
      --origin source=<Thumbor_IP_address>,enabled=true
   ```

   Result example:

   ```text
   id: "123***"
   folder_id: b1g86q4m5vej********
   name: thumbor
   use_next: true
   origins:
     - id: "234****"
       origin_group_id: "345***"
       source: cdn.example.com
       enabled: true
   ```

   This will get you the origin group ID in the `origin_group_id` parameter. You will need this ID in the next step.

1. Create a CDN resource and connect the origin group to it:

   ```bash
   yc cdn resource create \
      --cname <resource_domain_name> \
      --origin-group-id=<origin_group_ID> \
      --origin-protocol=https \
      --ignore-query-string \
      --cert-manager-ssl-cert-id <certificate_ID> \
      --forward-host-header
   ```

   Resource domain name example: `cdn.example.com`

   Result example:

   ```text
   id: bc855oumelrq********
   folder_id: b1g86q4m5vej********
   cname: cdn.example.com
   created_at: "2022-01-15T15:13:42.827643Z"
   updated_at: "2022-01-15T15:13:42.827671Z"
   active: true
   options:
     edge_cache_settings:
       enabled: true
       default_value: "345600"
     query_params_options:
       ignore_query_string:
         enabled: true
         value: true
     host_options:
       forward_host_header:
         enabled: true
         value: true
     stale:
       enabled: true
       value:
         - error
         - updating
   origin_group_id: "345***"
   origin_group_name: thumbor
   origin_protocol: HTTPS
   ssl_certificate:
     type: CM
     status: CREATING
   ```

   It takes 15 to 30 minutes to connect a CDN resource.

1. On the CDN resource page in the [management console](https://console.yandex.cloud), get the CDN provider's domain name, e.g., `e1b83ae3********.topology.gslb.yccdn.ru`.

1. Configure a CNAME record for your domain:

   1. Navigate to your domain’s DNS settings on your DNS hosting provider’s website.
   1. Prepare a CNAME record so that it points to the address on the `.yccdn.cloud.yandex.net` domain you copied earlier. For example, if the website domain name is `cdn.example.com`, create a CNAME record or replace an existing one for `cdn`:

      ```http
      cdn CNAME e1b83ae3********.topology.gslb.yccdn.ru.
      ```

## Check the result {#check-result}

Open your website at the URL:

* `https://<resource_domain_name>/unsafe/300x400/filters:watermark(cc.xlarge.png,10,-10,80,20)/poster_bunny_bunnysize.jpg`
* `https://<resource_domain_name>/unsafe/600x800/filters:watermark(cc.xlarge.png,10,-10,80,20)/poster_bunny_bunnysize.jpg`
* `https://<resource_domain_name>/unsafe/400x300/filters:watermark(cc.xlarge.png,-10,10,80,15)/poster_rodents_bunnysize.jpg`
* `https://<resource_domain_name>/unsafe/800x600/filters:watermark(cc.xlarge.png,-10,10,80,15)/poster_rodents_bunnysize.jpg`

You will see the prepared images of different sizes. Each image carries a [Creative Commons](https://en.wikipedia.org/wiki/Creative_Commons) watermark.

{% note info %}

If you cannot access the resource at the specified URL, [make sure](../../managed-kubernetes/operations/connect/security-groups.md) the security groups for the Managed Service for Kubernetes cluster and its node groups are configured correctly. If a rule is missing, [add it](../../vpc/operations/security-group-add-rule.md).

{% endnote %}

## 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:

1. [Delete all objects](../../storage/operations/objects/delete.md) from the buckets.
1. Delete the other resources depending on how you created them:

    {% list tabs group=instructions %}

    - Manually {#manual}

        1. [CDN resource](../../cdn/operations/resources/delete-resource.md).
        1. [CDN origin group](../../cdn/operations/origin-groups/delete-group.md).
        1. [Node group](../../managed-kubernetes/operations/node-group/node-group-delete.md).
        1. [Managed Service for Kubernetes cluster](../../managed-kubernetes/operations/kubernetes-cluster/kubernetes-cluster-delete.md).
        1. [Public static IP](../../vpc/operations/address-delete.md) if you reserved one for the cluster.
        1. [Service accounts](../../iam/operations/sa/delete.md).
        1. [Buckets](../../storage/operations/buckets/delete.md).

    - 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 %}