# Creating an instance group from a Container Optimized Image in Compute Cloud

# Creating an instance group from a Container Optimized Image


To run multiple instances of the service in Docker containers, you can create an instance group from a [Container Optimized Image](../../../cos/concepts/index.md). In such groups, you can update Docker containers with VM metadata using the [COI or Docker Compose specification](../../../cos/concepts/coi-specifications.md).

{% note alert %}

When creating instance groups, keep the [limits](../../concepts/limits.md) in mind. Not to disrupt the component Instance Groups, do not update or delete manually created resources: [target group](../../../network-load-balancer/concepts/target-resources.md) Network Load Balancer, VMs, and disks. Instead of this, change or delete the entire group.

{% endnote %}

In Instance Groups, all operations are performed under a service account. If you don't have a service account, [create one](../../../iam/operations/sa/create.md).

To be able to create, update, and delete VMs in the group, [assign](../../../iam/operations/sa/assign-role-for-sa.md) the [compute.editor](../../security/index.md#compute-editor) role to the service account.

To create an instance group based on a Container Optimized Image:

1. If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../../cli/quickstart.md#install).

1. 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.

1. View a description of the CLI command to create an instance group:

   {% list tabs group=instructions %}

   - CLI {#cli}

     ```bash
     yc compute instance-group create --help
     ```

   {% endlist %}

1. Check whether the folder contains any networks:

   {% list tabs group=instructions %}

   - CLI {#cli}

     ```bash
     yc vpc network list
     ```

   {% endlist %}

   If there are not any, [create one](../../../vpc/operations/network-create.md).

1. Create a YAML file and give it a name, e.g., `specification.yaml`.

1. Get the ID of the latest version of the [public](../images-with-pre-installed-software/get-list.md) Container Optimized Image.
   
   A Container Optimized Image in [Container Registry](../../../container-registry/index.md) may get updates and modifications that come with new releases. This will not automatically update the [VM](../../concepts/vm.md) image to the latest version. To create an [instance group](../../concepts/instance-groups/index.md) with the latest Container Optimized Image version, perform an availability check:
   
   {% list tabs group=instructions %}
   
   - CLI {#cli}
   
     ```bash
     yc compute image get-latest-from-family container-optimized-image --folder-id standard-images
     ```
   
     Result:
   
     ```bash
     id: <latest_COI_version_ID>
     folder_id: standard-images
     ...
     ```
   
   - Yandex Cloud Marketplace {#marketplace}
   
     1. Go to the Cloud Marketplace page and select the image with the configuration you need:
        * [Container Optimized Image](https://yandex.cloud/en/marketplace/products/yc/container-optimized-image).
        * [Container Optimized Image GPU](https://yandex.cloud/en/marketplace/products/yc/container-optimized-image-gpu).
     1. Under **Product IDs**, copy the `image_id` value.
   
   {% endlist %}

1. In the `specification.yaml` file you created, specify the following:

   * General information about the group:

     ```yaml
     name: container-optimized-group
     service_account_id: <service_account_ID>
     description: "This instance group was created from YAML config."
     ```

     Where:

     * `name`: Instance group name. The name must be unique within the folder. It can only contain lowercase Latin letters, numbers, and hyphens. The first character must be a letter. The last character cannot be a hyphen. The name can be up to 63 characters long.
     * `service_account_id`: Service account ID.

        To be able to create, update, and delete VMs in the group, [assign](../../../iam/operations/sa/assign-role-for-sa.md) the [compute.editor](../../security/index.md#compute-editor) role to the service account.

       You cannot delete a service account while it is linked to an instance group.

     * `description`: Instance group description.

   * [Instance template](../../concepts/instance-groups/instance-template.md):

     ```yaml
     instance_template:
       platform_id: standard-v3
       resources_spec:
         memory: 2G
         cores: 2
       boot_disk_spec:
         mode: READ_WRITE
         disk_spec:
           image_id: <latest_COI_version_ID>
           type_id: network-hdd
           size: 32G
       network_interface_specs:
         - network_id: c64mknqgnd8a********
           primary_v4_address_spec: {}
           security_group_ids:
             - enps0ar5s3ti********
       placement_policy:
        placement_group_id: rmppvhrgm77g********
       metadata:
         docker-container-declaration: |-
           spec:
             containers:
               - name: nginx
                 image: cr.yandex/mirror/nginx:1.17.4-alpine
                 securityContext:
                   privileged: false
                 tty: false
                 stdin: false
     ```

     By default, the disk size is specified in bytes. You can specify a different unit of measurement using the applicable suffix.
     
     | Suffix | Prefix and multiplier | Example |
     | ----- | ----- | ----- |
     | `k` | kilo- (2^10^) | `640k` = 640 × 2^10^ = `655360` |
     | `m` | mega- (2^20^) | `48m` = 48 × 2^20^ = `50331648` |
     | `g` | giga- (2^30^) | `10g` = 10 × 2^30^ = `10737418240` |
     | `t` | tera- (2^40^) | `4t` = 4 × 2^40^ = `4398046511104` |
     | `p` | peta- (2^50^) | `2p` = 2 × 2^50^ = `2251799813685248` |

     Where:

     * `platform_id`: Platform ID.
     * `memory`: Amount of RAM.
     * `cores`: Number of vCPUs.
     * `mode`: Disk access mode:
         * `READ_ONLY`: Read-only access.
         * `READ_WRITE`: Read/write access.
     * `image_id`: Container Optimized Image public image ID.
     * `type_id`: Disk type.
     * `size`: Disk size. It must be at least 30 GB.
     * `network_id`: `default-net` network ID.
     * `primary_v4_address_spec`: IPv4 specification. Only IPv4 is currently available. You can [allow public access to the group instances](../../concepts/instance-groups/instance-template.md#instance-template) by specifying the IP version for the public IP address.
     * `security_group_ids`: List of [security group](../../../vpc/concepts/security-groups.md) IDs.
     * `metadata`: Values to write to the VM metadata.
     * `docker-container-declaration`: Key in the VM metadata that is used with the [COI specification of the Docker container](../../../cos/concepts/coi-specifications.md). In the metadata, you can use the [Docker Compose specification](../../../cos/concepts/coi-specifications.md#compose-spec). To do this, specify the `docker-compose` key instead of the `docker-container-declaration` key.
     * `placement_policy`: (Optional) [Instance placement group](../../concepts/placement-groups.md) parameters:
       * `placement_group_id`: Placement group ID.
   * [Policies](../../concepts/instance-groups/policies/index.md):

     ```yaml
     deploy_policy:
       max_unavailable: 1
       max_expansion: 0
     scale_policy:
       fixed_scale:
         size: 3
     allocation_policy:
       zones:
         - zone_id: ru-central1-a
           instance_tags_pool:
           - first
           - second
           - third
     ```

     Where:

     * `deploy_policy`: Instance deployment policy for the group.
     * `scale_policy`: Instance scaling policy for the group.
     * `allocation_policy`: Policy for allocating VM instances across [availability zones](../../../overview/concepts/geo-scope.md).

     Full code for the `specification.yaml` file:

     ```yaml
     name: container-optimized-group
     service_account_id: <service_account_ID>
     description: "This instance group was created from YAML config."
     instance_template:
       service_account_id: <service_account_ID> # ID of the service account to access private Docker images.
       platform_id: standard-v3
       resources_spec:
         memory: 2G
         cores: 2
       boot_disk_spec:
         mode: READ_WRITE
         disk_spec:
           image_id: <latest_COI_version_ID>
           type_id: network-hdd
           size: 32G
       network_interface_specs:
         - network_id: c64mknqgnd8a********
           primary_v4_address_spec: {}
           security_group_ids:
             - enps0ar5s3ti********
       placement_policy:
         placement_group_id: rmppvhrgm77g********
       metadata:
         docker-container-declaration: |-
           spec:
             containers:
               - name: nginx
                 image: cr.yandex/mirror/nginx:1.17.4-alpine
                 securityContext:
                   privileged: false
                 tty: false
                 stdin: false
     deploy_policy:
       max_unavailable: 1
       max_expansion: 0
     scale_policy:
       fixed_scale:
         size: 3
     allocation_policy:
       zones:
          - zone_id: ru-central1-a
            instance_tags_pool:
            - first
            - second
            - third
     ```

     {% note info %}

     To use the [Docker Compose specification](../../../cos/concepts/coi-specifications.md#compose-spec) in `specification.yaml`, specify the `docker-compose` key instead of the `docker-container-declaration` key.

     {% endnote %}

1. Create an instance group in the default folder:

   {% list tabs group=instructions %}

   - CLI {#cli}

     ```bash
     yc compute instance-group create --file specification.yaml
     ```

     This command creates a group of three similar instances with the following characteristics:
     * Name: `container-optimized-group`.
     * Based on the latest version of the public Container Optimized Image.
     * With a running Docker container based on `cr.yandex/mirror/nginx:1.17.4-alpine`.
     * Network: `default-net`.
     * Availability zone: `ru-central1-a`.
     * vCPUs: 2; RAM: 2 GB.
     * Network HDD: 32 GB.

   {% endlist %}