[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Basic infrastructure](../infrastructure/index.md) > Tools > Getting started with Packer

# Getting started with Packer


[Packer](https://www.packer.io/) enables you to create [VM disk images](../../compute/concepts/image.md) and set their properties in a configuration file. This guide describes how to create a disk image in [Yandex Compute Cloud](../../compute/index.md) using Packer.

In this scenario, Packer will create and launch a [Debian 11](https://yandex.cloud/en/marketplace/products/yc/debian-11) virtual machine from Cloud Marketplace, with a [nginx](https://nginx.org/en/) web server installed on it. Following that, it will delete the VM and create an image of its boot disk. After that, it will also delete the disk.

For more information about the resources you can create with Packer, see [this provider guide](https://www.packer.io/docs/builders/yandex).

To create an image:

1. [Get your cloud ready](#before-you-begin).
1. [Install Packer](#install-packer).
1. [Prepare the image configuration](#prepare-image-config).
1. [Create an image](#create-image).
1. [Check the image](#check-image).

If you no longer need the image you created, [delete it](#clear-out).


## Get your cloud ready {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).


### Configure the environment and infrastructure {#prepare-environment}

1. [Create](../../vpc/quickstart.md) a cloud network with a single subnet in your folder.
1. Get an [IAM token](../../iam/operations/iam-token/create.md).
1. Make sure your account has enough permissions to create resources in Compute Cloud. The minimum [role](../../compute/security/index.md#compute-editor) you need for the folder is `compute.editor`.

    If working under a service account, [assign](../../iam/operations/roles/grant.md#cloud-or-folder) the `compute.editor` role for the folder to it.

    If you want to create resources in other Yandex Cloud services, e.g., subnets in VPC, assign the relevant [service roles](../../iam/roles-reference.md).


### Required paid resources {#paid-resources}

The cost of creating a disk image using Packer includes:

* Fee for storing created images (see [Yandex Compute Cloud pricing](../../compute/pricing.md#prices-storage)).
* Fee for VM computing resources (see [Yandex Compute Cloud pricing](../../compute/pricing.md#prices-instance-resources)).


## Install and configure Packer {#install-packer}

{% note warning %}

Yandex Cloud requires Packer 1.5 or higher.

Do not use popular package managers, such as Homebrew or APT, to install Packer. Their repositories may contain obsolete versions.

{% endnote %}

You can install Packer from a [mirror](#from-y-mirror) or the [HashiCorp website](#from-hashicorp-site):


### From a mirror {#from-y-mirror}

Install a Packer distribution kit for your platform from a [mirror](https://hashicorp-releases.yandexcloud.net/packer/):

{% list tabs group=operating_system %}

- Linux {#linux}

  1. Download a Packer distribution kit from the [mirror](https://hashicorp-releases.yandexcloud.net/packer/) and extract it into the `packer` directory:

      ```bash
      mkdir packer
      wget https://hashicorp-releases.yandexcloud.net/packer/1.11.2/packer_1.11.2_linux_amd64.zip -P ~/packer
      unzip ~/packer/packer_1.11.2_linux_amd64.zip -d ~/packer
      ```

      This example uses version `1.11.2`. For the latest Packer version, see the [mirror](https://hashicorp-releases.yandexcloud.net/packer/).

  1. Add Packer to the `PATH` variable: 

      1. Add the following line to the `.profile` file:

          ```bash
          export PATH="$PATH:/home/<username>/packer"
          ```

      1. Save your changes.

      1. Restart the shell:

          ```bash
          exec -l $SHELL
          ```

  1. Make sure you installed Packer:

      ```bash
      packer --version
      ```

      Result:
      
      ```text
      Packer v1.11.2
      ```


- Windows {#windows}

  1. Create the `packer` folder.
  1. Download a Packer distribution kit from the [mirror](https://hashicorp-releases.yandexcloud.net/packer/) and extract it into the `packer` folder:
  1. Add `packer` to the `PATH` variable:

      1. Click **Start** and type **Change system environment variables** in the Windows search bar.
      1. Click **Environment Variables...** at the bottom right.
      1. In the window that opens, find the `PATH` parameter and click **Edit**.
      1. Add your folder path to the list.
      1. Click **OK**.

  1. Run a new command line session and make sure you installed Packer:

      ```bash
      packer --version
      ```

      Result:

      ```text
      Packer v1.11.2
      ```

- macOS {#macos}

  1. Download a Packer distribution kit from the [mirror](https://hashicorp-releases.yandexcloud.net/packer/) and extract it into the `packer` directory:

      ```bash
      mkdir packer
      curl --location --output ~/packer/packer_1.11.2_darwin_amd64.zip https://hashicorp-releases.yandexcloud.net/packer/1.11.2/packer_1.11.2_darwin_amd64.zip
      unzip ~/packer/packer_1.11.2_darwin_amd64.zip -d ~/packer
      ```

      This example uses version `1.11.2`. For the latest Packer version, see the [mirror](https://hashicorp-releases.yandexcloud.net/packer/).

  1. Add Packer to the `PATH` variable: 

      ```bash
      echo 'export PATH="$PATH:$HOME/packer"' >> ~/.bash_profile
      source ~/.bash_profile
      ```

  1. Restart the shell:

      ```bash
      exec -l $SHELL
      ```

  1. Make sure you installed Packer:

      ```bash
      packer --version
      ```

      Result:
      
      ```text
      Packer v1.11.2
      ```

{% endlist %}


### From the HashiCorp website {#from-hashicorp-site}

Download and install a Packer distribution kit following [this guide on the Packer website](https://www.packer.io/intro/getting-started/install.html#precompiled-binaries).


### Configure the Yandex Compute Builder plugin {#configure-plugin}

To configure the [plugin](https://developer.hashicorp.com/packer/plugins/builders/yandex):

1. Create a file named `config.pkr.hcl` with the following contents:

    ```hcl
    packer {
      required_plugins {
        yandex = {
          version = ">= 1.1.2"
          source  = "github.com/hashicorp/yandex"
        }
      }
    }
    ```

1. Install the plugin:

    ```bash
    packer init <path_to_config.pkr.hcl>
    ```

    Result:

    ```text
    Installed plugin github.com/hashicorp/yandex v1.1.2 in ...
    ```

## Prepare the image configuration {#prepare-image-config}

1. [Get](../../resource-manager/operations/folder/get-id.md) the folder ID.
1. [Get](../../vpc/operations/subnet-get-info.md) the subnet ID and the [availability zone](../../overview/concepts/geo-scope.md) it resides in.
1. Create a JSON file with any name, e.g., `image.json`. Add this configuration to it:

    
    ```json
    {
      "builders": [
        {
          "type":      "yandex",
          "token":     "<IAM_token>",
          "folder_id": "<folder_ID>",
          "zone":      "<availability_zone>",

          "image_name":        "debian-11-nginx-not_var{{isotime | clean_resource_name }}",
          "image_family":      "debian-web-server",
          "image_description": "my custom debian with nginx",

          "source_image_family": "debian-11",
          "subnet_id":           "<subnet_ID>",
          "use_ipv4_nat":        true,
          "disk_type":           "network-ssd",
          "ssh_username":        "debian"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "inline": [
            "echo 'updating APT'",
            "sudo apt-get update -y",
            "sudo apt-get install -y nginx",
            "sudo su -",
            "sudo systemctl enable nginx.service",
            "curl localhost"
          ]
        }
      ]
    }
    ```




    Where:

    * `token`: [IAM token](../../iam/concepts/authorization/iam-token.md).
    * `folder_id`: ID of the folder where you are going to create the VM and its image.
    * `zone`: Availability zone the VM will be created in, e.g., `ru-central1-d`.
    * `subnet_id`: ID of the subnet where you are going to create the VM and its image.

{% note warning %}

You cannot use both the `provisioner "shell"` and `metadata` parameters in the configuration file at the same time.

{% endnote %}

You can learn more about image configuration properties in [this Yandex Compute Builder overview article](https://www.packer.io/docs/builders/yandex).


## Create an image {#create-image}

1. Build the image using the configuration properties:

    ```bash
    packer build image.json
    ```

1. Wait for the build to complete:

    ```bash
    ...
    ==> Wait completed after 2 minutes 43 seconds
    ==> Builds finished. The artifacts of successful builds are:
    --> yandex: A disk image was created: debian-11-nginx-2024-08-26t15-30-39z (id: fd82d63b9bgc********) with family name debian-web-server
    ```


## Check the image {#check-image}

Make sure you created the image:

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to the [management console](https://console.yandex.cloud).
  1. Navigate to **Compute Cloud**.
  1. Open the ![image](../../_assets/console-icons/layers.svg) **Images** section. Make sure the new disk image is there.

- 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 image list
  ```

  Result:

  ```text
  +----------------------+--------------------------------------+-------------------+----------------------+--------+
  |          ID          |                 NAME                 |      FAMILY       |     PRODUCT IDS      | STATUS |
  +----------------------+--------------------------------------+-------------------+----------------------+--------+
  | fd82d63b9bgc******** | debian-11-nginx-2024-08-26t15-30-39z | debian-web-server | f2eerqfup7lg******** | READY  |
  +----------------------+--------------------------------------+-------------------+----------------------+--------+
  ```

{% endlist %}


### Delete the resources you created {#clear-out}

To stop paying for the resources you created:

* [Delete](../../compute/operations/image-control/delete.md) the image you created.
* Delete the [subnet](../../vpc/operations/subnet-delete.md) and [cloud network](../../vpc/operations/network-delete.md) if created specifically for the purpose of this tutorial.