Terraform
Briefly: On Linux, you typically install Terraform, the Yandex Cloud CLI (yc), run initialization, then configure authentication credentials (IAM token or service account key) for Terraform.
1. Terraform
Via official binary (universal):
# Example for amd64; adjust version and architecture if needed
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
Or via package manager (if you’re on Ubuntu/Debian and have the HashiCorp repo configured — as described in your distribution documentation).
2. Yandex Cloud CLI (yc)
curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
exec -l $SHELL # or open a new terminal
yc version
3. Profile and Cloud Access
Interactively (convenient for the first time):
yc init
You’ll need:
- Profile name (choose
defaultor create a new one) - OAuth token (it will provide a link to obtain it)
- Cloud name (it will suggest options — this affects billing, which cloud the invoice will be associated with)
- Folder name (it will suggest options)
- Default compute zone (it will suggest creating one from the list
ru-central1-a...k)
Then, yc will save the profile. To verify:
yc config list
yc resource-manager cloud list
yc resource-manager folder list
4. Terraform Variables (Yandex Provider)
The provider reads standard environment variables. At minimum, you need identifiers and one authentication method.
Option A — from user (IAM token from yc):
export YC_TOKEN=$(yc iam create-token)
export YC_CLOUD_ID="<your-cloud-id>"
export YC_FOLDER_ID="<your-folder-id>"
The IAM token is short-lived; for long-term use, a service account is more convenient.
Option B — service account (JSON key file):
export YC_SERVICE_ACCOUNT_KEY_FILE="/absolute/path/to/key.json"
export YC_CLOUD_ID="<cloud-id>"
```export YC_FOLDER_ID=""<folder-id>
(The variable name for the key file in the provider is exactly this — see the Yandex provider documentation.)
5. In the Terraform configuration directory
cd /path/to/your/terraform/project
terraform init
terraform plan
Practical Notes:
YC_TOKEN=$(yc iam create-token)needs to be refreshed periodically.- For CI and “always works” scenarios, it’s common to create a service account with required roles on the folder/cloud and a static key in JSON format.
cloud_idandfolder_idcan be obtained from the output ofyc resource-manager cloud list/folder listor from the Yandex Cloud console.
Bucket
How do I get access_key and secret_key for an existing bucket https://console.yandex.cloud/folders/b1g/storage/buckets/bucket?
In Yandex Object Storage, buckets do not have their own access_key / secret_key. Keys are issued to a service account (or you are using keys already created for it). The bucket is then “bound” via IAM permissions on the bucket or folder.
Via Console
- Open the folder
b1g→ Object Storage → bucketbucket. - Ensure there is a service account that needs access to the bucket (or create a new one).
- On the bucket: Access Permissions → grant a role like
storage.editor(or a role already configured for you with Object Storage access) to this service account. - Go to Service Accounts → the required account → Static Access Keys (or “Access Keys”) tab → Create New Key.
- Save the key ID and secret — the secret is shown only once.
Key ID = what is usually called access_key / AWS_ACCESS_KEY_ID in S3 clients, secret = secret_key / AWS_SECRET_ACCESS_KEY.
Via CLI (yc)
List service accounts in the folder:
yc iam service-account list --folder-id b1g
Create a static key (replace <SERVICE_ACCOUNT_ID> with the ID of the desired SA):
yc iam access-key create --service-account-id <SERVICE_ACCOUNT_ID>
The response will include key_id and secret — this is the key pair for S3 API.
It’s better to grant permissions on the bucket in advance (role on the bucket resource or folder), for example, storage.editor on the bucket — via console or IAM API; for typical scenarios, a role on the folder is often sufficient if that’s the practice in your organization.
Important
- An existing secret cannot be “viewed” again — only create a new key and revoke the old one if needed.
- For Terraform state in S3, use the same keys + endpoint
https://storage.yandexcloud.netand regionru-central1(or your region).
The official logic is described in the Yandex Cloud documentation on static access keys and access to Object Storage via S3 API.
Local repo
Navigate to the repository folder and use the service account key to initialize the Terraform repo in the folder:
terraform init \
-backend-config="access_key=<key_id>" \
-backend-config="secret_key=<secret>"
This will link the cloud folder with your local one.
Hashicorp restrictions
If you receiveruby
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:
Plugin signatures | Terraform | HashiCorp Developer
╷
│ 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
Then perform the steps below.
### What's happening
`yandex-cloud/yandex` has been successfully pulled, but **`hashicorp/null`** and **`hashicorp/local`** are missing. This often occurs when **`registry.terraform.io` is unreachable** (network, DNS, policy) or responds incorrectly: Terraform then reports that the provider "does not exist".
### What to do locally
1. **Yandex Cloud Mirror** — copy the Terraform config to your home directory (from the repository, copy `terraform.rc.example`):
```bash
cp ~/terraform.rc.example ~/.terraformrc
In it, set https://terraform-mirror.yandexcloud.net/ for registry.terraform.io/*/*, as described in the Yandex Cloud documentation.
-
Re-run:
cd ~/yc-cloud terraform init -
The code now explicitly declares the
localprovider inprovider.tf(previously onlynullwas declared), so versions are fixed in one place.
If direct access without a mirror is needed: check your VPN/proxy and ensure curl -sI https://registry.terraform.io works.```ruby
$ 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
```bash
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"
Usage
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 fails because the count_vars.vars file does not contain, and does not expect, three required provider variables: yc_cloud, yc_folder, yc_token. This file is for sizing and image definitions; credentials and cloud/folder identifiers are described separately in the repository.
What to do
Option A: Create a local terraform.tfvars file (not in Git) with content like this:
yc_cloud = "b1g..." # Cloud ID
yc_folder = "b1g0" # For the ya-cloud stack from docs
yc_token = "t1.…" # IAM token or OAuth; do not commit
Run:
terraform plan -input=false -var-file=terraform.tfvars -var-file=count_vars.vars -out=tfplan
Option B — via environment (convenient with yc iam create-token):
export TF_VAR_yc_cloud="$(yc config get cloud-id)" # or explicit b1g...
export TF_VAR_yc_folder="$(yc config get folder-id)" # or b1g0
export TF_VAR_yc_token="$(yc iam create-token)"
terraform plan -input=false -var-file=count_vars.vars -out=tfplan
````export YC_TOKEN=...` is **not automatically substituted** into `var.yc_token` — Terraform requires either **`TF_VAR_yc_token`** or `-var`/`-var-file`.
**Option C — two var files:** for example, `secrets.auto.tfvars` / `local.tfvars` with the `yc_*` trio + `count_vars.vars` as the second `-var-file`.
---
Regarding the truncated line in the terminal `export YC_CLOUD_ID=\"` — Terraform needs **`yc_cloud`**, not necessarily a separate variable `YC_CLOUD_ID`; it’s simpler to grab the ID from `yc resource-manager cloud list` or `yc config get cloud-id`.
The **Incomplete lock file** warning after `init`: if needed for CI or other OSes, run `terraform providers lock` with the required `-platform=...`, as Terraform suggests.
**Backend S3:** for `terraform init`/reading state, **static access keys** to Object Storage are required (see README/WORKFLOW §3.1); the `yc_token` is not used by the backend — this is a separate topic. If `init` has already passed, your keys are already configured.