Creating a VM with access to a Yandex Lockbox secret
You can use the metadata service to provide the ID of a Yandex Lockbox secret to a VM and then get the value of that secret from inside the VM using the IAM token of the service account linked to the VM.
Just like other user data, Yandex Lockbox secrets are provided in the user-data key. You can provide metadata to the user-data folder both when creating and updating a VM.
Note
To provide a Yandex Lockbox secret to a VM via metadata:
-
Create a Yandex Lockbox secret.
-
Create a service account and assign the
lockbox.payloadViewerrole to it. -
Create a file named
metadata.yamland paste into it the following metadata configuration for the new VM:metadata.yaml
#cloud-config datasource: Ec2: strict_id: false secrets: my_secret: <secret_ID> ssh_pwauth: no users: - name: <username> sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh-authorized-keys: - "<user_public_SSH_key>" packages: - jq - yqWhere:
-
Create a virtual machine:
Management consoleCLITerraformAPI-
In the management console
, select the folder containing your secret and service account. -
From the list of services, select Compute Cloud.
-
In the left-hand panel, select
Virtual machines. -
Click Create virtual machine.
-
Under Boot disk image, select the Ubuntu 24.04 LTS image.
-
Under Location, select the availability zone where your VM will reside.
-
Under Network settings, in the Subnet field, enter the ID of a subnet in the new VM's availability zone or select a cloud network from the list.
-
Under Access, select SSH key and specify the VM access credentials:
- Enter the VM user name in the Login field,
-
In the SSH key field, select the SSH key saved in your organization user profile.
If there are no SSH keys in your profile or you want to add a new key:
-
Click Add key.
-
Enter a name for the SSH key.
-
Select one of the following:
-
Enter manually: Paste the contents of the public SSH key. You need to create an SSH key pair on your own. -
Load from file: Upload the public part of the SSH key. You need to create an SSH key pair on your own. -
Generate key: Automatically create an SSH key pair.When adding a new SSH key, an archive containing the key pair will be created and downloaded. In Linux or macOS-based operating systems, unpack the archive to the
/home/<user_name>/.sshdirectory. In Windows, unpack the archive to theC:\Users\<user_name>/.sshdirectory. You do not need additionally enter the public key in the management console.
-
-
Click Add.
The system will add the SSH key to your organization user profile. If the organization has disabled the ability for users to add SSH keys to their profiles, the added public SSH key will only be saved in the user profile inside the newly created resource.
-
-
Under General information, enter a name for your VM:
- It must be from 2 to 63 characters long.
- It can only contain lowercase Latin letters, numbers, and hyphens.
- It must start with a letter and cannot end with a hyphen.
-
Under Additional, select the service account you created earlier.
-
Under Metadata:
- In the Key field, specify
user-data. - In the Value field, paste the contents of the
metadata.yamlconfiguration file you created earlier.
- In the Key field, specify
-
Click Create VM.
If you do not have the Yandex Cloud CLI installed yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the
yc config set folder-id <folder_ID>command. You can also set a different folder for any specific command using the--folder-nameor--folder-idparameter.Run this command:
yc compute instance create \ --name my-vm \ --hostname <host_name> \ --zone <availability_zone> \ --create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2404-lts-oslogin \ --network-interface subnet-name=<subnet_name>,ipv4-address=auto,nat-ip-version=ipv4 \ --metadata-from-file user-data="<path_to_configuration_file>" \ --service-account-id <service_account_ID>Where:
-
--name: Name of the new VM, e.g.,my-vm. -
--hostname: Host name for the new VM. This is an optional parameter. If omitted, the VM ID will be used as the host name. -
--zone: Availability zone the new VM will reside in. -
--network-interface: Network interface settings for the new VM:subnet-name: Name of the subnet in the availability zone specified in the--zoneparameter.
-
--metadata-from-file: Theuser-datakey with the path to thecloud-configYAML configuration file for value, e.g.,--metadata-from-file user-data="/home/user/metadata.yaml". -
service-account-id: ID of the service account with thelockbox.payloadViewerrole.
Result
done (31s) id: epde2t9aovjm******** folder_id: b1gt6g8ht345******** created_at: "2025-02-04T18:18:58Z" name: my-vm zone_id: ru-central1-b platform_id: standard-v2 resources: memory: "2147483648" cores: "2" core_fraction: "100" status: RUNNING metadata_options: gce_http_endpoint: ENABLED aws_v1_http_endpoint: ENABLED gce_http_token: ENABLED aws_v1_http_token: DISABLED boot_disk: mode: READ_WRITE device_name: epd27gmf2vu2******** auto_delete: true disk_id: epd27gmf2vu2******** network_interfaces: - index: "0" mac_address: d0:0d:e1:75:2a:c7 subnet_id: e2lqsms4cdl3******** primary_v4_address: address: 192.168.15.25 one_to_one_nat: address: 51.***.***.93 ip_version: IPV4 serial_port_settings: ssh_authorization: OS_LOGIN gpu_settings: {} fqdn: my-vm.ru-central1.internal scheduling_policy: {} service_account_id: ajegtlf2q28a******** network_settings: type: STANDARD placement_policy: {} hardware_generation: legacy_features: pci_topology: PCI_TOPOLOGY_V1If you do not have Terraform yet, install it and configure the Yandex Cloud provider.
-
In the configuration file, describe the resources you want to create:
# Creating a boot disk for the VM resource "yandex_compute_disk" "boot-disk" { type = "network-ssd" zone = "<availability_zone>" size = "20" image_id = "fd8bpal18cm4kprpjc2m" } # Creating a VM instance resource "yandex_compute_instance" "my-vm" { name = "<VM_name>" platform_id = "standard-v2" zone = "<availability_zone>" service_account_id = "<service_account_ID>" resources { cores = "2" memory = "4" } boot_disk { disk_id = yandex_compute_disk.boot-disk.id } network_interface { subnet_id = "<subnet_ID>" nat = true security_group_ids = ["<security_group_ID>"] } metadata = { user-data = "${file("<path_to_configuration_file>")}" } }Where:
zone: Availability zone the VM and disk will reside in.service_account_id: ID of the previously created service account with thelockbox.payloadViewerrole.name: Name of the new VM, e.g.,my-vm.subnet_id: ID of the subnet in the availability zone specified in thezoneparameter.security_group_ids: Security group ID.user-data: Path to themetadata.yamlconfiguration file you created earlier.
For more information about the resources being created, see the relevant TF provider articles.
-
Create the resources:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validateIf the configuration is correct, you will get this message:
Success! The configuration is valid. -
Run this command:
terraform planYou will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply -
Type
yesand press Enter to confirm the changes.
This will create all the resources you need in the specified folder. You can check the new resources and their settings using the management console
. -
Use the create REST API method for the Instance resource or the InstanceService/Create gRPC API call.
-
-
Connect to the new VM over SSH. In the VM terminal:
-
Get the IAM token of the service account linked to the VM and save that token to the
YC_TOKENvariable. To do this, send the following request to thecomputeMetadatafolder in the metadata service:export YC_TOKEN=$(curl -sf -H Metadata-Flavor:Google 169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token | jq -r .access_token) -
Get the secret ID you provided to the
user-datafolder in the metadata service when creating the VM.export my_secret_id=$(curl -sf -H Metadata-Flavor:Google 169.254.169.254/latest/user-data | yq .datasource.secrets.my_secret | tr -d \") -
Get the secret value and save it to the
my_secret_valuevariable. To do this, send the following request to the Yandex Lockbox API:export my_secret_value=$(curl -sf -H "Authorization: Bearer $YC_TOKEN" "https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/${my_secret_id}/payload" | jq -r .entries[0].textValue) echo $my_secret_valueResult:
admin@my-vm:~$ echo $my_secret_value my value
-
For more user-data key configuration examples, see Examples.