[Yandex Cloud documentation](../../../index.md) > [Yandex Compute Cloud](../../index.md) > [Step-by-step guides](../index.md) > Creating a VM > Creating a VM instance with access to a Yandex Lockbox secret

# Creating a VM with access to a Yandex Lockbox secret

You can use the [metadata](../../concepts/vm-metadata.md) service to provide the ID of a [Yandex Lockbox secret](../../../lockbox/concepts/secret.md) to a [VM](../../concepts/vm.md) and then get the value of that secret from inside the VM using the [IAM token](../../../iam/concepts/authorization/iam-token.md) of the [service account](../../../iam/concepts/users/service-accounts.md) 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](../../concepts/metadata/directories.md#dir-user) both when [creating](../index.md#vm-create) and [updating](../vm-control/vm-update.md) a VM.

{% note info %}

To create, modify, and edit a [VM](../../concepts/vm.md), you need the `compute.editor` _minimum_ [role](../../security/index.md#compute-editor) for the [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder). To create a VM with a licensed image, you will additionally need the `license-manager.viewer` [role](../../../marketplace/security/index.md#license-manager-viewer).

To create a VM with a [public IP address](../../../vpc/concepts/address.md#public-addresses), you will additionally need the `vpc.publicAdmin` [role](../../../vpc/security/index.md#vpc-public-admin).

{% endnote %}

To provide a Yandex Lockbox secret to a VM via metadata:

1. [Create](../../../lockbox/operations/secret-create.md) a Yandex Lockbox secret.
1. [Create](../../../iam/operations/sa/create.md) a service account and [assign](../../../iam/operations/sa/assign-role-for-sa.md#binding-role-resource) the `lockbox.payloadViewer` [role](../../../lockbox/security/index.md#lockbox-payloadViewer) to it.
1. Create a file named `metadata.yaml` and paste into it the following metadata configuration for the new VM:

    **metadata.yaml**

    ```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
      - yq
    ```

    Where:
    * `my_secret`: [ID](../../../lockbox/operations/secret-get-info.md) of the secret you created.

        {% note warning %}

        Provide only the IDs of your secrets to the `user-data` folder, not their [values](../../../lockbox/concepts/secret.md#secret).

        {% endnote %}

    * `name`: Name of the local user to create on the VM, e.g., `admin`.
    * `ssh-authorized-keys`: Public SSH key of the new VM user.

1. Create a virtual machine:

    {% list tabs group=instructions %}

    - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder containing your secret and service account.
      1. Navigate to **Compute Cloud**.
      1. In the left-hand panel, select ![image](../../../_assets/console-icons/server.svg) **Virtual machines**.
      1. Click **Create virtual machine**.
      1. Under **Boot disk image**, select [Ubuntu 24.04 LTS](https://yandex.cloud/en/marketplace/products/yc/ubuntu-2404-lts-oslogin).
      1. Under **Location**, select an [availability zone](../../../overview/concepts/geo-scope.md) where your VM will reside.
      1. 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](../../../vpc/concepts/network.md#network) from the list.
      1. 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](../../../organization/concepts/membership.md) profile.
            
            If there are no SSH keys in your profile or you want to add a new key:
            
            1. Click **Add key**.
            1. Enter a name for the SSH key.
            1. Select one of the following:
            
                * `Enter manually`: Paste the contents of the public SSH key. You need to [create](../vm-connect/ssh.md#creating-ssh-keys) 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>/.ssh` directory. In Windows, unpack the archive to the `C:\Users\<user_name>/.ssh` directory. You do not need additionally enter the public key in the management console.
            
            1. Click **Add**.
            
            The system will add the SSH key to your organization user profile. If the organization has [disabled](../../../organization/operations/os-login-access.md) 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.
      1. Under **General information**, enter a name for your VM:

          * Length: between 3 and 63 characters.
          * It can only contain lowercase Latin letters, numbers, and hyphens.
          * It must start with a letter and cannot end with a hyphen.

      1. Under **Additional**, select the service account you created earlier.
      1. Under **Metadata**:

          * In the **Key** field, specify `user-data`.
          * In the **Value** field, paste the contents of the `metadata.yaml` configuration file you created earlier.
      1. Click **Create VM**.

    - CLI {#cli}

      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.

      Run this command:

      ```bash
      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 setting. If omitted, the VM ID will be used as the host name.
      * `--zone`: [Availability zone](../../../overview/concepts/geo-scope.md) the new VM will reside in.
      * `--network-interface`: [Network interface](../../concepts/network.md) settings for the new VM:

          * `subnet-name`: Name of the [subnet](../../../vpc/concepts/network.md#subnet) in the availability zone specified in the `--zone` parameter.
      * `--metadata-from-file`: The `user-data` key with the path to the `cloud-config` YAML configuration file for value, e.g., `--metadata-from-file user-data="/home/user/metadata.yaml"`.
      * `service-account-id`: [ID](../../../iam/operations/sa/get-id.md) of the service account with the `lockbox.payloadViewer` [role](../../../lockbox/security/index.md#lockbox-payloadViewer).

      {% cut "Result" %}

      ```text
      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_V1
      ```

      {% endcut %}

    - Terraform {#tf}

      If you do not have Terraform yet, [install it and configure the Yandex Cloud provider](../../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
      
      
      To manage infrastructure using Terraform under a service account or user accounts (a Yandex account, a federated account, or a local user), [authenticate](../../../terraform/authentication.md) using the appropriate method.

      1. In the configuration file, describe the resources you want to create:

          ```hcl
          # 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

          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](../../../overview/concepts/geo-scope.md) the VM and disk will reside in.
          * `service_account_id`: [ID](../../../iam/operations/sa/get-id.md) of the previously created service account with the `lockbox.payloadViewer` [role](../../../lockbox/security/index.md#lockbox-payloadViewer).
          * `name`: Name of the new VM, e.g., `my-vm`.
          * `subnet_id`: ID of the [subnet](../../../vpc/concepts/network.md#subnet) in the availability zone specified in the `zone` parameter.
          * `security_group_ids`: [Security group](../../../vpc/concepts/security-groups.md) ID.
          * `user-data`: Path to the `metadata.yaml` configuration file you created earlier.

          For more information about new resources, see [this provider guide](../../../terraform/index.md).

      1. Create the resources:

          1. In the terminal, navigate to the configuration file directory.
          1. Make sure the configuration is correct using this command:
          
             ```bash
             terraform validate
             ```
          
             If the configuration is valid, you will get this message:
          
             ```bash
             Success! The configuration is valid.
             ```
          
          1. Run this command:
          
             ```bash
             terraform plan
             ```
          
             You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
          1. Apply the configuration changes:
          
             ```bash
             terraform apply
             ```
          
          1. Type `yes` and 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](https://console.yandex.cloud).

    - API {#api}

      Use the [create](../../api-ref/Instance/create.md) REST API method for the [Instance](../../api-ref/Instance/index.md) resource or the [InstanceService/Create](../../api-ref/grpc/Instance/create.md) gRPC API call.

    {% endlist %}

1. [Connect to the new VM over SSH](../vm-connect/ssh.md). In the VM terminal:

    1. Get the IAM token of the service account linked to the VM and save that token to the `YC_TOKEN` variable. To do this, send the following request to the `computeMetadata` [folder](../../concepts/metadata/directories.md#dir-compute) in the metadata service:

        ```bash
        export YC_TOKEN=$(curl -sf -H Metadata-Flavor:Google 169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token | jq -r .access_token)
        ```
    1. Get the secret ID you provided to the `user-data` [folder](../../concepts/metadata/directories.md#dir-user) in the metadata service when creating the VM.

        ```bash
        export my_secret_id=$(curl -sf -H Metadata-Flavor:Google 169.254.169.254/latest/user-data | yq .datasource.secrets.my_secret | tr -d \")
        ```
    1. Get the secret value and save it to the `my_secret_value` variable. To do this, send the following request to the Yandex Lockbox API:

        ```bash
        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_value
        ```

        Result:

        ```bash
        admin@my-vm:~$ echo $my_secret_value
        my value
        ```

For more `user-data` key configuration examples, see the [Examples](create-with-cloud-init-scripts.md#examples) section.

#### Useful links {#see-also}

* [VM metadata](../../concepts/vm-metadata.md)
* [Creating a VM with metadata from environment variables](create-with-env-variables.md)
* [Creating a VM with a custom configuration script](create-with-cloud-init-scripts.md)