На локальной машине настроить Terraform и Yandex Cloud, чтобы подключаться к облаку

Terraform

Кратко: на Linux обычно ставят Terraform, Yandex Cloud CLI (yc), проходят инициализацию, затем для Terraform задают учётные данные (IAM-токен или ключ сервисного аккаунта).

1. Terraform

Через официальный бинарник (универсально):

# пример для amd64; при необходимости замените версию и архитектуру
TERRAFORM_VERSION=1.9.8
wget "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip"
unzip "terraform_${TERRAFORM_VERSION}_linux_amd64.zip"
sudo mv terraform /usr/local/bin/
terraform version

Или через пакетный менеджер (если у вас Ubuntu/Debian и настроен HashiCorp repo — как в вашей документации дистрибутива).

2. Yandex Cloud CLI (yc)

curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
exec -l $SHELL   # или откройте новый терминал
yc version

3. Профиль и доступ к облаку

Интерактивно (удобно в первый раз):

yc init

Понадобятся:

  • profile name (выбрать default или создать новый)
  • OAuth token (сообщит ссылку, как получить)
  • cloud name (предложит выбрать - от этого будет зависеть биллинг, на какое облако будет выставляться счет)
  • folder name (предложит выбрать)
  • default compute zone (предложит создать из списка ru-central1-a...k)

Дальше yc сохранит профиль; проверка:

yc config list
yc resource-manager cloud list
yc resource-manager folder list

4. Переменные для Terraform (провайдер Yandex)

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

Вариант A — от пользователя (IAM-токен из yc):

export YC_TOKEN=$(yc iam create-token)
export YC_CLOUD_ID="<ваш-cloud-id>"
export YC_FOLDER_ID="<ваш-folder-id>"

IAM-токен недолговечный; для долгой работы удобнее сервисный аккаунт.

Вариант B — сервисный аккаунт (ключ JSON):

export YC_SERVICE_ACCOUNT_KEY_FILE="/absolute/path/to/key.json"
export YC_CLOUD_ID="<cloud-id>"
export YC_FOLDER_ID="<folder-id>"

(Имя переменной для файла ключа в провайдере — именно такое, см. документацию провайдера Yandex.)

5. В каталоге с конфигурацией Terraform

cd /path/to/your/terraform/project
terraform init
terraform plan

Практические замечания:

  • YC_TOKEN=$(yc iam create-token) периодически нужно обновлять.
  • Для CI и «всегда работает» обычно делают сервисный аккаунт с нужными ролями на каталог/облако и статический ключ в JSON.
  • cloud_id и folder_id можно взять из вывода yc resource-manager cloud list / folder list или из консоли Yandex Cloud.

Bucket

Как мне получить access_key и secret_key для существующего бакета https://console.yandex.cloud/folders/b1g/storage/buckets/bucket ?

В Yandex Object Storage у бакета нет своих access_key / secret_key. Ключи выдаются сервисному аккаунту (или вы используете ключи, уже созданные для него). Бакет при этом «привязывается» через права IAM на бакет или на каталог.

Через консоль

  1. Откройте каталог b1gObject Storage → бакет bucket.
  2. Убедитесь, что есть сервисный аккаунт, которому нужен доступ к бакету (или создайте новый).
  3. На бакете: Права доступа → выдайте роль вроде storage.editor (или уже настроенную у вас роль с доступом к Object Storage) этому сервисному аккаунту.
  4. Перейдите в Сервисные аккаунтынужный аккаунт → вкладка Статические ключи доступа (или «Ключи доступа») → Создать новый ключ.
  5. Сохраните идентификатор ключа и секретсекрет показывается один раз.

Идентификатор ключа = то, что в S3-клиентах обычно называют access_key / AWS_ACCESS_KEY_ID, секрет = secret_key / AWS_SECRET_ACCESS_KEY.

Через CLI (yc)

Список сервисных аккаунтов в каталоге:

yc iam service-account list --folder-id b1g

Создать статический ключ (подставьте id нужного СА):

yc iam access-key create --service-account-id <SERVICE_ACCOUNT_ID>

В ответе будут key_id и secret — это и есть пара для S3 API.

Права на бакет лучше выдать заранее (роль на ресурс бакета или на каталог), например для storage.editor на бакете — через консоль или API IAM; для типовых сценариев часто достаточно роли на каталог, если так принято у вас в организации.

Важно

  • Существующий секрет нельзя «посмотреть» снова — только создать новый ключ и отозвать старый при необходимости.
  • Для Terraform state в S3 используют те же ключи + endpoint https://storage.yandexcloud.net и регион ru-central1 (или ваш регион).

Официальная логика описана в документации Yandex Cloud про статические ключи доступа и доступ к Object Storage через S3 API.

local repo

Войдите в папку с репозиторием, используйте ключ от сервисного аккаунта для инициализации Terraform-репо в папке:

terraform init \
  -backend-config="access_key=<key_id>" \
  -backend-config="secret_key=<secret>"

Так вы свяжете облачную папку с локальной.

Hashicorp restrictions

Если вы получаете

terraform init   -backend-config="access_key=YCA" -backend-config="secret_key=YCN"
Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of yandex-cloud/yandex...
- Finding hashicorp/null versions matching "~> 3.2"...
- Finding latest version of hashicorp/local...
- Installing yandex-cloud/yandex v0.200.0...
- Installed yandex-cloud/yandex v0.200.0 (self-signed, key ID E40F590B50BB8E40)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
╷
│ Error: Failed to query available provider packages
│ 
│ Could not retrieve the list of available versions for provider hashicorp/null: provider
│ registry registry.terraform.io does not have a provider named
│ registry.terraform.io/hashicorp/null
│ 
│ All modules should specify their required_providers so that external consumers will get the
│ correct providers when using a module. To see which modules are currently depending on
│ hashicorp/null, run the following command:
│     terraform providers
╵
╷
│ Error: Failed to query available provider packages
│ 
│ Could not retrieve the list of available versions for provider hashicorp/local: provider
│ registry registry.terraform.io does not have a provider named
│ registry.terraform.io/hashicorp/local
│ 
│ All modules should specify their required_providers so that external consumers will get the
│ correct providers when using a module. To see which modules are currently depending on
│ hashicorp/local, run the following command:
│     terraform providers

То выполните шаги ниже.

Что происходит

yandex-cloud/yandex подтянулся, а hashicorp/null и hashicorp/local — нет. Так бывает, когда registry.terraform.io недоступен (сеть, DNS, политика) или отвечает некорректно: Terraform тогда пишет, что провайдера «нет».

Что сделать у себя

  1. Зеркало Yandex Cloud — в домашний каталог положить конфиг Terraform (из репозитория скопирован terraform.rc.example:

    cp ~/terraform.rc.example ~/.terraformrc
    

    В нём задаётся https://terraform-mirror.yandexcloud.net/ для registry.terraform.io/*/*, как в документации Yandex Cloud.

  2. Повторить:

    cd ~/yc-cloud
    terraform init
    
  3. В коде добавлено явное объявление провайдера local в provider.tf (раньше был только null), чтобы версии были зафиксированы в одном месте.

Если без зеркала нужен прямой доступ: проверьте VPN/прокси и что curl -sI https://registry.terraform.io открывается.

$ terraform init   -backend-config="access_key=YCA" -backend-config="secret_key=YCN"
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/null versions matching "~> 3.2"...
- Finding hashicorp/local versions matching "~> 2.5"...
- Finding latest version of yandex-cloud/yandex...
- Installing yandex-cloud/yandex v0.200.0...
- Installed yandex-cloud/yandex v0.200.0 (unauthenticated)
- Installing hashicorp/null v3.2.4...
- Installed hashicorp/null v3.2.4 (unauthenticated)
- Installing hashicorp/local v2.8.0...
- Installed hashicorp/local v2.8.0 (unauthenticated)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

╷
│ Warning: Incomplete lock file information for providers
│ 
│ Due to your customized provider installation methods, Terraform was forced to calculate
│ lock file checksums locally for the following providers:
│   - hashicorp/local
│   - hashicorp/null
│   - yandex-cloud/yandex
│ 
│ The current .terraform.lock.hcl file only includes checksums for linux_amd64, so Terraform
│ running on another platform will fail to install these providers.
│ 
│ To calculate additional checksums for another platform, run:
│   terraform providers lock -platform=linux_amd64
│ (where linux_amd64 is the platform to generate)
╵
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Terraform plan / apply

terraform plan -input=false -var-file=count_vars.vars -out=tfplan
terraform apply -auto-approve tfplan
terraform destroy -auto-approve -var-file="count_vars.vars"

Использование

terraform plan -input=false -var-file=count_vars.vars -out=tfplan
╷
│ Error: No value for required variable
│ 
│   on variable.tf line 1:
│    1: variable "yc_cloud" {}
│ 
│ The root module input variable "yc_cloud" is not set, and has no default value. Use a -var or
│ -var-file command line argument to provide a value for this variable.
╵
╷
│ Error: No value for required variable
│ 
│   on variable.tf line 3:
│    3: variable "yc_folder" {}
│ 
│ The root module input variable "yc_folder" is not set, and has no default value. Use a -var
│ or -var-file command line argument to provide a value for this variable.
╵
╷
│ Error: No value for required variable
│ 
│   on variable.tf line 5:
│    5: variable "yc_token" {}
│ 
│ The root module input variable "yc_token" is not set, and has no default value. Use a -var or
│ -var-file command line argument to provide a value for this variable.

terraform plan падает потому, что в count_vars.vars нет и не предполагаются три обязательные переменные провайдера: yc_cloud, yc_folder, yc_token. Этот файл — про сайзинг и образы; креды и идентификаторы облака/каталога в репозитории описаны отдельно.

Что сделать

Вариант A: завести terraform.tfvars (локально, не в Git) с примерно таким содержимым:

yc_cloud  = "b1g..."   # ID облака
yc_folder = "b1g0"  # для стека ya-cloud из доки
yc_token  = "t1.…"   # IAM-токен или OAuth; не коммитить

Запуск:

terraform plan -input=false -var-file=terraform.tfvars -var-file=count_vars.vars -out=tfplan

Вариант B — через окружение (удобно с yc iam create-token):

export TF_VAR_yc_cloud="$(yc config get cloud-id)"   # или явный b1g...
export TF_VAR_yc_folder="$(yc config get folder-id)" # или b1g0
export TF_VAR_yc_token="$(yc iam create-token)"
terraform plan -input=false -var-file=count_vars.vars -out=tfplan

export YC_TOKEN=... не подставляется в var.yc_token сам по себе — для Terraform нужен именно TF_VAR_yc_token или -var/-var-file.

Вариант C — два var-файла: например secrets.auto.tfvars / local.tfvars с тройкой yc_* + count_vars.vars вторым -var-file.


Про обрезанную строку в терминале export YC_CLOUD_ID=" — для Terraform нужен yc_cloud, не обязательно отдельная переменная YC_CLOUD_ID; проще взять ID из yc resource-manager cloud list или yc config get cloud-id.

Предупреждение про Incomplete lock file после init: при необходимости для CI/других ОС выполните terraform providers lock с нужными -platform=..., как подсказывает Terraform.

Бэкенд S3: для terraform init/чтения state нужны статические ключи к Object Storage (см. README/WORKFLOW §3.1); yc_token бэкенд не использует — это отдельная тема, если init уже прошёл, значит ключи у вас настроены.