---
title: "Загрузка состояний Terraform в S3"
description: "Как настроить Remote State в Terraform с использованием S3-хранилища Timeweb Cloud: конфигурация backend, защита ключей доступа, создание инфраструктуры и использование состояния в других конфигурациях."
---

# Загрузка состояний Terraform в Object Storage

> Полный индекс документации для ИИ-агентов: [llms.txt](https://timeweb.cloud/llms.txt).

Terraform — это средство для создания и управления инфраструктурой в коде, которое дает возможность развертывать, модифицировать и удалять разнообразные ресурсы в облачных сервисах, такие как виртуальные сервера, сетевые элементы, хранилища данных и т.д. Он применяет язык настроек HCL (HashiCorp Configuration Language), который имеет декларативный и понятный человеку синтаксис. HCL позволяет задавать требуемое состояние инфраструктуры с помощью секций, параметров и формул.

Преимущества использования: 

-   Вы можете запустить одинаковый код Terraform на различных платформах и получать одинаковые результаты. 
-   Вы можете разделять свою инфраструктуру на отдельные модули и использовать их в разных задачах. 
-   Вы можете работать с разными облачными провайдерами и услугами с помощью единого интерфейса. 
-   Вы можете сохранять свой код настроек в системе управления версиями и отслеживать изменения по времени. 
-   Вы можете работать над своей инфраструктурой в команде и согласовывать свои действия с помощью удаленного хранилища состояний.

## Remote State

По умолчанию Terraform сохраняет своё состояние в локальном файле `.tfstate`. Однако при работе в команде использование локального файла усложняет работу с этим инструментом — каждый пользователь должен убедиться, что у него наиболее свежая версия файла с состоянием и что никто другой в данный момент времени не запускает создание ресурсов с аналогичным провайдером.

Механизм Remote State позволяет хранить файлы состояния в удалённом хранилище, что позволяет пользователям работать с самой свежей версией состояния и не думать о синхронизации. Terraform поддерживает следующие хранилища:

-   Terraform Cloud
-   HashiCorp Consul
-   Amason S3 (или другое S3-совместимое хранилище)
-   Google Cloud Storage
-   Azure Blob Storage
-   многие другие

Хранение состояния настраивается в конфигурации в блоке `backend`, например:

```shell
backend "s3" {
     endpoint   = ""
     bucket     = ""
     …
  }
```

Подробнее о конфигурации бэкэнда можно прочитать на сайте Terraform: [Backend Configuration](https://developer.hashicorp.com/terraform/language/settings/backends/configuration).

> [!NOTE]
> На данный момент Timeweb Cloud не поддерживает загрузку состояний в S3 для версий Terraform 1.6.0 и выше из-за [изменений в структуре конфигурации](https://github.com/hashicorp/terraform/releases/tag/v1.6.0).

## Подготовка

Предварительные шаги для создания инфраструктуры.

### Необходимые платные ресурсы

В этой статье будут созданы:

-   Две виртуальные машины ([тарифы](https://timeweb.cloud/services/vds-vps))
-   Один бакет Object Storage ([тарифы](https://timeweb.cloud/services/s3-storage))
-   Одна локальная сеть

### Создаём бакет

Чтобы использовать S3 в качестве хранилища состояния, нам необходимо создать бакет. Для этого перейдём в панель управления, в раздел «Хранилище S3».

![Image6](https://content.timeweb.com/assets/ee140d2b-b93a-431e-9151-5824dab1db79?width=1264&height=376)

Нажмём на кнопку «Заказать». Для примера возьмём минимальную конфигурацию:

![Screenshot 04 17 25 16:47:13](https://content.timeweb.com/assets/f3b37b0b-4fb4-4e58-b171-abc23994d714.png?width=1019&height=955)

На вкладке «Дашборд» бакета, который мы только что создали, отображаются настройки, которые позже укажем в файле `.tf`:

![Selection 255](https://content.timeweb.com/assets/3258ff3a-733e-4d6d-97ee-d5900f99bf2d.png?width=1008&height=941)

### Пишем конфигурацию

Теперь приступим к написанию конфигурации. 

1.  Добавляем папку `terraform_s3`, в которой будет наш проект.
2.  Создаём там файл `main.tf`.
3.  По [инструкции](https://timeweb.cloud/docs/terraform/nachalo-raboty-s-terraform) заполняем информацию о провайдере.

Должна получиться следующая структура файлов:

```shell
├── terraform_s3
│   ├── main.tf
```

И следующее содержимое файла `main.tf`:

```shell
terraform {
  required_providers {
    twc = {
      source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"
    }
  }
  required_version = ">= 1.5.3"
}

provider "twc" {
  token = "<your token>"
}
```

Теперь добавим настройки бэкенда в блок `terraform`.

```shell
  backend "s3" {
     endpoint = "https://s3.twcstorage.ru"
     region = "ru-1"
     bucket = "<bucket name>"
     key = "states/terraform.tfstate"
     access_key = "<your access key>"
     secret_key = "<your secret key>"
     skip_region_validation = true
     skip_credentials_validation = true
     skip_metadata_api_check = true
     skip_requesting_account_id = true
     skip_s3_checksum = true
     }
```

Параметры:

1.  `endpoint` — адрес S3-хранилища из панели управления.
2.  `region` — регион из панели управления.
3.  `bucket` — название бакета, где буду храниться наши конфигурации.
4.  `key` — путь к файлу в бакете вместе с названием файла. Например, `states/<название файла>.tfstate`.
5.  `access_key` и `secret_key` — ключи для доступа к бакету. Их можно получить в панели управления, на странице созданного ранее бакета
6.  `skip_region_validation` и `skip_credentials_validation` — флаги, с помощью которых мы пропускаем валидацию региона и ключей доступа на стороне AWS. Они нужны, так как мы используем не оригинальный AWS S3, а другое облако.

Вот пример, как должен выглядеть полный код файла `main.tf`:

```shell
terraform {
  required_providers {
    twc = {
      source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"
    }
  }
  required_version = ">= 1.5.3"

  backend "s3" {
    endpoint = "s3.twcstorage.ru"
    region = "ru-1"
    bucket = "<bucket name>"
    key  = "states/terraform.tfstate"
    access_key = "<your access key>"
    secret_key = "<your secret key>"
    skip_region_validation = true
    skip_credentials_validation = true
    }
}

provider "twc" {
  token = "<your token>"
}
```

После всех настроек выполним команду `terraform init`:

![Image1](https://content.timeweb.com/assets/d025f014-2cf3-4ff9-93ad-7d9a12c2363a?width=767&height=395)

### Защита данных

В конфигурации бэкэнда параметры `access_key` и `secret_key` содержат чувствительные данные, которые не должны быть доступны посторонним лицам. Их не рекомендуется хранить в явном виде в файле конфигурации.

1.  Можно установить переменные окружения `AWS_ACCESS_KEY_ID` и `AWS_SECRET_ACCESS_KEY` с соответствующими значениями ключей доступа к бакету. Тогда Terraform будет автоматически читать эти переменные при работе с бэкэндом.
2.  Использование параметров командной строки. Можно использовать параметр `-backend-config` при выполнении команды `init`:

```shell
terraform init -backend-config="access_key=1234" -backend-config="secret_key=1234"
```

## Создаём инфраструктуру

В файле `main.tf` опишем создание виртуальной машины и локальной сети:

1.  Укажем ОС.

```shell
data "twc_os" "example-os" {
  name = "ubuntu"
  version = "22.04"
}
```

2.  Укажем пресет.

```shell
data "twc_presets" "example-preset" {
  price_filter {
    from = 300
    to = 400
  }
}
```

3.  Добавим VPC.

```shell
resource "twc_vpc" "example-vpc" {
  name = "Example VPC"
  description = "Some example VPC"
  subnet_v4 = "192.168.0.0/24"
  location = "ru-1"
}
```

4.  Опишем конфигурацию сервера.

```shell
resource "twc_server" "example-server-with-local-network" {
  name = "Example server with local network"
  os_id = data.twc_os.example-os.id

  preset_id = data.twc_presets.example-preset.id

  local_network {
    id = twc_vpc.example-vpc.id
  }
}
```

5.  Добавим идентификатор приватной сети в выходные параметры, чтобы мы могли использовать его в других конфигурациях

```shell
output "tw-vpc" {
    value = twc_vpc.example-vpc.id
}
```

Содержимое конфигурации `main.tf` будет выглядеть так:

```shell
terraform {
  required_providers {
    twc = {

      source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"
    }
  }
  required_version = ">= 1.5.3"

  backend "s3" {
    endpoint = "s3.twcstorage.ru"
    region = "ru-1"
    bucket = "<bucket name>"
    key  = "states/terraform.tfstate"
    access_key = "<your access key>"
    secret_key = "<your secret key>"
    skip_region_validation = true
    skip_credentials_validation = true
    }
}

provider "twc" {
  token = "<your token>"
}

data "twc_os" "example-os" {
  name = "ubuntu"
  version = "22.04"
}

data "twc_presets" "example-preset" {
  price_filter {
    from = 300
    to = 400
  }
}

resource "twc_vpc" "example-vpc" {
  name = "Example VPC"
  description = "Some example VPC"
  subnet_v4 = "192.168.0.0/24"
  location = "ru-1"
}

resource "twc_server" "example-server-with-local-network" {
  name = "Example server with local network"
  os_id = data.twc_os.example-os.id

  preset_id = data.twc_presets.example-preset.id

  local_network {
    id = twc_vpc.example-vpc.id
  }
}

output "tw-vpc" {
    value = twc_vpc.example-vpc.id
}
```

Выполним команду `terraform validate`:

![D067189e 35ec 4bc3 8060 765d5f9ffb79](https://content.timeweb.com/assets/ec95b966-f322-4472-9cf0-6a5ba9d22337?width=565&height=49)

Затем `terraform plan`:

![A8ecc713 91cf 44ab 9110 E1fd97806e32](https://content.timeweb.com/assets/4b070049-6849-490b-922f-6cc9e6b6bff8?width=436&height=58)

И `terraform apply`:

![41ef13cf F6e3 42c9 B98b 0ceacdb3b9dd](https://content.timeweb.com/assets/a846d8b4-d34f-4af0-ab69-cf7166d5b15b?width=576&height=169)

После применения конфигурации в бакете автоматически будет создан файл состояния.

## Проверка и использование состояния

В панели управления можно проверить наличие файла состояния в бакете:

![Image7](https://content.timeweb.com/assets/b503b873-4ae5-4ca4-a468-65fd64cd4b3d?width=877&height=130)

Теперь попробуем использовать сохранённое состояние в другой конфигурации. 

Добавим новую папку `remote-state`:

```shell
mkdir remote-state
cd remote-state
```

Добавим файл `remote-state.tf` и заполним его следующим образом:

```shell
terraform {
  required_providers {
    twc = {
      source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"
    }
  }
  required_version = ">= 1.5.3"
}

provider "twc" {
  token = "<your token>"
}

data "terraform_remote_state" "vpc" {
  backend = "s3"
    config = {
    endpoint = "s3.twcstorage.ru"
    region = "ru-1"
    bucket = "<bucket name>"
    key  = "states/terraform.tfstate"
    skip_region_validation = true
    skip_credentials_validation = true
    access_key = "<your access key>"
    secret_key = "<your secret key>"
    }
}

data "twc_os" "example-os" {
  name = "ubuntu"
  version = "22.04"
}

data "twc_presets" "example-preset" {
  price_filter {
    from = 300
    to = 400
  }
}

resource "twc_server" "example-server-with-local-network" {
  name = "Example server with local network"
  os_id = data.twc_os.example-os.id
  preset_id = data.twc_presets.example-preset.id

  local_network {
    id = data.terraform_remote_state.vpc.outputs.tw-vpc
  }
}
```

В этом примере мы используем outputs из предыдущего файла `main.tf` для получения идентификатора локальной сети, и добавляем в эту сеть новый VPS.

Выполним команды:

-   `terraform init`
-   `terraform validate`
-   `terraform plan` 
-   `terraform apply`

Будет создан второй сервер в нужной локальной сети:

![Image4](https://content.timeweb.com/assets/a3146efa-f83b-4cf9-abe0-ec783b383cc8?width=307&height=187)

Чтобы удалить созданные ресурсы, выполните команду `terraform destroy` сначала во второй конфигурации, а затем в первой.

## Полезные ссылки

-   [Документация терраформ-провайдера Timeweb](https://github.com/timeweb-cloud/terraform-provider-timeweb-cloud)
-   [Документация Terraform CLI](https://developer.hashicorp.com/terraform/cli/run)
-   [Remote State](https://developer.hashicorp.com/terraform/language/state)
