> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Grupos de instancias

> Mantenga un conjunto de instancias idénticas en un recuento objetivo, colóquelas en una nueva plantilla de lanzamiento y envíelas con una dirección pública compartida.

Un grupo de instancias es una plantilla de lanzamiento más un recuento de destino. La plataforma mantiene ese número de instancias ejecutándose desde esa plantilla, reemplaza las que fallan y las distribuye entre los hosts.

Es una primitiva para máquinas idénticas e intercambiables. Todo lo que hace se deriva de eso: las réplicas no pueden tener direcciones fijas, un cambio de plantilla no toca lo que ya está en ejecución, y un grupo es lo que hace que una dirección pública sea respondida por varias instancias a la vez.

<CardGroup cols={2}>
  <Card title="Crear una agrupación" icon="layers" href="#creating-a-pool">
    La plantilla de lanzamiento, los límites de tamaño y cómo se nombran las réplicas.
  </Card>

  <Card title="Dimensionamiento y curación" icon="activity" href="#sizing-and-convergence">
    Lo que converge el grupo, lo que reemplaza y el contador para alertar.
  </Card>

  <Card title="Cambiar una plantilla" icon="refresh-cw" href="#changing-the-template">
    Por qué editar la plantilla no cambia nada, y qué hace una actualización.
  </Card>

  <Card title="Una dirección pública compartida" icon="globe" href="#one-address-for-the-whole-pool">
    Anycast a través de las réplicas, y las formas en que no es un balanceador de carga.
  </Card>
</CardGroup>

<a id="creating-a-pool" />

## Crear una agrupación

<Tabs>
  <Tab title="Console">
    Vaya a **Compute → Instance pools** y elija **Create instance pool**. Después de **Details** viene una tarjeta **Scaling** con **Min**, **Desired** y **Max**; el resto del formulario es la plantilla de lanzamiento, tarjeta por tarjeta, igual que la creación de una instancia: **Flavor**, **Image**, **Boot volume**, **Data volumes**, **Networking**, **IAM role**, **User data**.

    **Min** es el piso y **Max** es el techo. Puedes cambiar ambos más tarde con **Scale**.

    Los dos mapas de etiquetas a continuación se llaman así por la diferencia entre ellos: **Instance tags** se *estampan en cada réplica que lanza el grupo*, mientras que **Pool tags** *etiquetan el grupo en sí y no llegan a ninguna de sus instancias*.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST https://compute.sa-saopaulo-1.basaltic.sh/v1/instance-pools
    {
      "name": "web-asg",
      "desired_count": 3,
      "min_count": 2,
      "max_count": 6,
      "tags": { "team": "backend" },
      "template": {
        "flavor": "550e8400-e29b-41d4-a716-446655440000",
        "image": "app-base:20260807",
        "networks": [
          { "subnet": "9b2e4f1a-3c5d-4e6f-8a90-1b2c3d4e5f60",
            "security_groups": ["c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"] }
        ],
        "user_data": "I2Nsb3VkLWNvbmZpZwo...",
        "tags": { "role": "web" }
      }
    }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool create --name web-asg \
      --desired-count 3 --min-count 2 --max-count 6 --from-file pool.json
    ```

    Guarde la solicitud de API anterior como `pool.json`. Los indicadores sobrescriben los valores en ese archivo; el archivo proporciona la plantilla de inicio anidada.
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    pool, err := compute.New(cfg).CreateInstancePool(ctx, &compute.InstancePoolCreateRequest{
        Name:         "web-asg",
        DesiredCount: basaltic.Int(3),
        MinCount:     basaltic.Int(2),
        MaxCount:     basaltic.Int(6),
        Template: &compute.InstancePoolTemplateRequest{
            Flavor: "550e8400-e29b-41d4-a716-446655440000",
            Image: basaltic.String("app-base:20260807"),
            Networks: []*compute.NetworkConfig{
                {Subnet: "9b2e4f1a-3c5d-4e6f-8a90-1b2c3d4e5f60"},
            },
        },
    })
    ```
  </Tab>
</Tabs>

En las peticiones de creación y reemplazo, `template` es la configuración de inicio, en la misma forma que toma una [instancia independiente create](/es/compute/instances) — mismos nombres de campo, mismos tipos, mismos significados. No hay un recurso de plantilla de lanzamiento separado para crear, publicar o compartir; la plantilla pertenece al grupo.

Se requieren un flavor y una subred primaria: `template.flavor` y `template.networks[0].subnet`. El índice 0 es la NIC principal; el resto son extras.

<Warning>
  **Una plantilla no puede llevar una dirección fija dentro de `addresses` o un `mac` fijo.** Cada réplica se inicia desde la misma plantilla, por lo que una dirección fija haría que la segunda réplica pidiera una que la primera ya tenga. Ambos son rechazados con un `400` en lugar de ser abandonados en silencio.
</Warning>

<a id="iam-role-references-and-responses" />

### Referencias y respuestas de roles de IAM

Las solicitudes de creación y reemplazo aceptan `template.iam_role` como un UUID, CRN o cadena de nombre exacto para un rol en tu cuenta. Adjuntar el rol requiere `iam:PassRole` y autorización de confianza de instancia; consulte [Roles e identidad de instancia](/es/iam/roles).

Las respuestas de la agrupación devuelven un resumen de rol opcional dentro de `template`, en lugar de `iam_role_id`. Este extracto de respuesta muestra la identidad del archivo adjunto:

```json theme={null}
{
  "template": {
    "iam_role": {
      "id": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
      "crn": "crn:iam::my-account:role/deploy",
      "name": "deploy"
    }
  }
}
```

El resumen contiene solo `id`, `crn` y `name` y es visible con acceso de lectura de la agrupación, sin `iam:GetRole`. Excluye los campos de rol confidenciales, como las políticas. `template.iam_role` se omite cuando no hay ningún rol adjunto, el rol se ha eliminado o pertenece a otra cuenta. La apertura de los detalles de IAM del rol todavía requiere `iam:GetRole`.

<a id="subnet-references-and-responses" />

### Referencias y respuestas de subred

Las solicitudes de creación y reemplazo toman `template.networks[].subnet` como una cadena: un UUID o un CRN completo de VPC/subred. Un nombre de subred sin más no es suficiente, porque los nombres de subred solo son únicos dentro de su VPC.

Las respuestas de grupo incrustan toda la subred en cada NIC de plantilla, en lugar del anterior `subnet_id`. La incrustación lleva la VPC principal y el resumen de la tabla de rutas nullable descrito en [ubicación de subred](/es/networking/subnets#reading-placement):

```json theme={null}
{
  "template": {
    "networks": [
      {
        "subnet": {
          "id": "9b2e4f1a-3c5d-4e6f-8a90-1b2c3d4e5f60",
          "crn": "crn:network:sa-saopaulo-1:my-account:vpc/production/subnet/private",
          "name": "private",
          "cidr": "10.0.1.0/24",
          "vpc": { "id": "c3d4e5f6-a7b8-4901-c2d3-e4f5a6b7c8d9", "name": "production" },
          "route_table": { "id": "…", "crn": "…", "name": "private-routes" }
        },
        "floating_ip_assignment": "none"
      }
    ]
  }
}
```

Por lo tanto, `subnet.name` y `subnet.vpc.name` son legibles directamente desde el grupo; no se necesita ninguna subred o VPC separada para mostrar dónde aterrizan las réplicas. En el SDK de Go estos son `nic.Subnet` y `nic.Subnet.VPC`.

`subnet` es **null** cuando la subred referenciada ya no se resuelve, como una subred eliminada después de que se almacenó la plantilla. Trate esto como una ubicación no disponible en lugar de "sin subred": muéstrelo como no disponible y actualícelo antes de actuar sobre él. La plantilla todavía nombra una subred en la que el grupo no puede iniciarse, por lo que el siguiente reemplazo que lanza falla.

<Warning>
  **Nunca devuelva el objeto incrustado.** Las solicitudes toman una cadena, por lo que un reemplazo construido a partir de una respuesta tiene que convertir la `subnet` de cada NIC a su `id` o `crn` — vea [Cambiar la plantilla](#changing-the-template). Una `subnet` nulo no tiene referencia para copiar: suministre una válida antes de la `PATCH`, o la ubicación de las tiendas de reemplazo que el pool no puede usar.
</Warning>

<a id="the-image-is-resolved-once" />

### La imagen se resuelve una vez

`template.image` toma las mismas tres formas que instance create — un id, `name:version`, o un `name` desnudo. A diferencia de la creación de instancias, **la referencia se resuelve una vez, cuando se crea el grupo (o cuando se reemplaza la plantilla), y el id de imagen resultante es lo que arranca cada réplica**, incluidos los reemplazos generados meses después.

Eso es deliberado. Una etiqueta re-resuelta por réplica permitiría a un miembro curado arrancar una compilación más nueva que sus hermanos, y un grupo cuyos miembros no son idénticos es la premisa de la ruptura primitiva silenciosa. Para mover un grupo a una nueva compilación, cambie la plantilla y actualice.

<a id="what-the-replicas-are-called" />

### Cómo se llaman las réplicas

Cada réplica recibe un **número de secuencia**, estable mientras tenga el espacio, y se llama `<pool-name>-<sequence_num>` — `web-asg-0`, `web-asg-1`, y así sucesivamente. Un reemplazo se hace cargo del número liberado.

`GET /v1/instance-pools/{pool_id}/instances` Devoluciones completas `Instance` Los objetos en
`instances`, más paginación `meta`Cada objeto incluye su estado, direcciones, tipo de instancia, imagen y rol; no necesita una solicitud de instancia separada para cada miembro. Lee la secuencia de réplicas desde la lista de instancias de nivel superior. `metadata["basalt:pool:sequence_num"]`. Su valor es una cadena, incluyendo
`"0"` para la primera ranura.

Filtrar esta lista con `name`, `crn`, `current_state`, `flavor` o `image`. También acepta `limit` y `marker`. Mientras `meta.has_more` es true, solicita la siguiente página usando `meta.marker` como `marker`, manteniendo los mismos filtros y límites. Recoge `instances` de cada página para listar todos los miembros coincidentes.

<Note>
  Los nombres de instancia son únicos por cuenta, por lo que un grupo llamado `web` no puede coexistir con una instancia que ya hayas nombrado `web-0`. Los nombres de grupo son de 1 a 127 caracteres de letras, dígitos, punto, guion y subrayado, únicos por cuenta.
</Note>

<a id="per-replica-disks-and-addresses" />

### Discos y direcciones por réplica

`template.volumes` crea un disco con cada réplica y lo recupera con esa réplica. `delete_on_termination` es por defecto `true`; póngalo en `false` y una réplica escalada, reemplazada o destruida con el pool **libera** su volumen de nuevo a `available` en lugar de destruirlo.

`template.networks[0].floating_ip_assignment` le da a **cada réplica su propia** IP flotante en su NIC principal, asignada a medida que el grupo se escala hacia afuera y liberada a medida que se escala hacia adentro. Una NIC en `template.networks[]` lleva su propia bandera, por lo que una interfaz secundaria puede ser la pública. Cada dirección cuenta contra su cuota `floating_ips`.

Eso es algo diferente de la dirección compartida del grupo —
[Ver más abajo](#one-address-for-the-whole-pool).

<a id="sizing-and-convergence" />

## Dimensionamiento y convergencia

Los tres campos de dimensionamiento son enteros mutables. Los valores resultantes deben satisfacer `0 ≤ min_count ≤ desired_count ≤ max_count ≤ 100`. En crear solamente, los límites omitidos por defecto a `desired_count`.

En `PATCH`, los límites omitidos mantienen sus valores almacenados. Si omite `desired_count`, el objetivo actual se sujeta en los nuevos límites: elevar el mínimo por encima de él eleva el objetivo; bajar el máximo por debajo de él baja el objetivo. Un objetivo que ya está dentro de los límites no cambia.

Si envía explícitamente `desired_count`, debe ajustarse a los límites resultantes. El tamaño no válido devuelve `400` sin aplicar ninguna parte de la actualización, incluidas las etiquetas o una plantilla enviada con ella. Cero es válido, incluyendo ambos límites en cero. El redimensionamiento no reemplaza la plantilla de lanzamiento ni solicita una actualización.

Estos controles se aplican a los grupos administrados por el cliente. Los grupos de propiedad de un servicio administrado no se pueden redimensionar a través de la API de grupo de instancias; usa los controles de ese servicio.

<a id="automatic-scaling" />

### Escalado automático

Una política de `autoscaling` ajusta `desired_count` dentro de los límites configurados. La misma política está disponible en [load balancers](/es/load-balancers#scaling). La creación o actualización de una directiva no cambia la plantilla de inicio.

El seguimiento de objetivos de CPU requiere `min_count` de al menos 1.

<Tabs>
  <Tab title="Console">
    Abre la agrupación y elige **Scale**. Establezca **Minimum count**, **Maximum count** y **Desired count**, y luego active **Automatic scaling**. Elija una **Metric source** y establezca su objetivo; para CPU, use **Target CPU (%)**. Elija **Scale** para guardar. La pestaña **Scaling** muestra la política y las decisiones de escalado recientes.
  </Tab>

  <Tab title="API">
    ```http theme={null}
    PATCH /v1/instance-pools/{pool_id}
    ```

    ```json theme={null}
    {
      "min_count": 1,
      "max_count": 10,
      "autoscaling": {
        "enabled": true,
        "metrics": [
          { "source": "cpu", "target_type": "utilization", "target_value": 60 }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool update "$POOL_ID" \
      --min-count 1 --max-count 10 \
      --autoscaling '{"enabled":true,"metrics":[{"source":"cpu","target_type":"utilization","target_value":60}]}'
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    _, err := compute.New(cfg).UpdateInstancePool(ctx, poolID, &compute.InstancePoolUpdateRequest{
        MinCount: basaltic.Int(1),
        MaxCount: basaltic.Int(10),
        Autoscaling: &compute.AutoscalingPolicy{
            Enabled: true,
            Metrics: []*compute.ScalingMetric{{
                Source: "cpu", TargetType: "utilization", TargetValue: 60,
            }},
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    ```
  </Tab>
</Tabs>

El objetivo es la utilización de CPU como porcentaje de las vCPU asignadas de los miembros. Los miembros deben estar corriendo y haber pasado su período de calentamiento antes de que se evalúe la demanda. El escalado espera mientras la capacidad converge, los miembros se retiran o se está actualizando.

También puedes escalar desde una métrica que publiques a [Telemetry](/es/telemetry), como la profundidad de la cola. El propietario de la política necesita `telemetry:ReadMetrics`; ese permiso se comprueba de nuevo mientras se ejecuta la política. Solo son válidas las métricas de la cuenta y la región del grupo.

```json theme={null}
{
  "min_count": 0,
  "max_count": 10,
  "autoscaling": {
    "enabled": true,
    "metrics": [{
      "source": "telemetry",
      "name": "queue_depth",
      "labels": { "queue": "jobs" },
      "sample_aggregation": "last",
      "series_aggregation": "sum",
      "expected_series": 1,
      "window_seconds": 120,
      "max_age_seconds": 90,
      "target_type": "average_value",
      "target_value": 100
    }]
  }
}
```

Una profundidad de cola de 750 con un objetivo de 100 trabajos por instancia recomienda ocho instancias, antes de aplicar límites y límites de paso. Las muestras se agregan dentro de cada serie primero, luego entre series. `expected_series` debe coincidir con el número de series seleccionadas; una serie faltante impide la escala. Las métricas de contador pueden usar `sample_aggregation: "rate"` para tener en cuenta los reajustes antes de que las tasas se combinen en las series.

Publicar un cero nuevo cuando la cola está vacía. Los datos que faltan, están obsoletos o incompletos nunca significan cero y no pueden eliminar la capacidad. Las métricas de demanda personalizadas pueden hacer crecer un grupo desde cero; las políticas de CPU no pueden. Con varias métricas, la recomendación de capacidad válida más grande gana. Los datos que faltan aún permiten una recomendación de escalado válida de otra métrica.

El calentamiento predeterminado es de 180 segundos, el tiempo de reutilización es de 60 segundos y la estabilización de reducción es de 300 segundos. Cada decisión añade como máximo cuatro instancias o elimina como máximo una. Estos límites y `drain_seconds` (por defecto 120) son configurables. El tiempo de enfriamiento y la estabilización permanecen en vigor durante los reinicios del servicio. Lea `autoscaling_status.reason` y `autoscaling_status.history` para la condición de espera actual y los cambios recientes de capacidad.

Aún puedes cambiar el tamaño manualmente. La evaluación automática se reanuda después del tiempo de reutilización. Para detener los cambios automáticos, envíe la política con `enabled: false`; su configuración de métrica se conserva cuando se envía de vuelta. Las políticas se reemplazan en su totalidad, por lo que debe incluir la configuración de la métrica cuando inhabilite una.

La escalabilidad inicial marca primero un miembro como retirado y lo retira de los conjuntos de backend del balanceador de carga y de las IP flotantes compartidas. La eliminación espera el acuse de recibo de retiro y el período de gracia de drenaje. Esto no invoca un gancho de cierre de aplicación; los trabajos de larga ejecución deben tolerar la terminación de la instancia. Las sesiones TCP, UDP y WebSocket de larga duración pueden terminar en el plazo de drenaje. Los cambios en la membresía de reenvío de IP flotante compartida también pueden cambiar la ubicación de la conexión durante la retirada.

<a id="adjusting-the-bounds" />

### Ajuste de los límites

La siguiente secuencia comienza con un mínimo de 2, el deseado 3 y el máximo 6. Eleva el objetivo a 4, lo baja a 2 y luego escala a cero. Escalar a cero retira a todos los miembros; sus discos siguen `delete_on_termination`.

<Tabs>
  <Tab title="Console">
    Abra el grupo y elija **Scale** para abrir **Scale instance pool**. Establezca **Minimum count** en 4, mantenga **Maximum count** en 6 y deje **Desired count** sin cambios. Elija **Scale**; el objetivo se convierte en 4.

    Vuelva a abrir **Scale**, establezca **Minimum count** en 2 y **Maximum count** en 2, y deje **Desired count** sin cambios; el objetivo se convierte en 2. Para escalar a cero, vuelva a abrir el diálogo y establezca ambos límites en 0, de nuevo dejando **Desired count** sin cambios. La consola omite un valor deseado sin cambios para que la API pueda ajustarlo automáticamente.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    PATCH /v1/instance-pools/{pool_id}
    { "min_count": 4 }

    PATCH /v1/instance-pools/{pool_id}
    { "min_count": 2, "max_count": 2 }

    PATCH /v1/instance-pools/{pool_id}
    { "min_count": 0, "max_count": 0 }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool update <pool-id> --min-count 4
    basaltic compute instance-pool update <pool-id> --min-count 2 --max-count 2
    basaltic compute instance-pool update <pool-id> --min-count 0 --max-count 0
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    c := compute.New(cfg)
    pool, err := c.UpdateInstancePool(ctx, poolID,
        &compute.InstancePoolUpdateRequest{MinCount: basaltic.Int(4)})
    if err != nil { return err }
    pool, err = c.UpdateInstancePool(ctx, poolID,
        &compute.InstancePoolUpdateRequest{
            MinCount: basaltic.Int(2), MaxCount: basaltic.Int(2),
        })
    if err != nil { return err }
    pool, err = c.UpdateInstancePool(ctx, poolID,
        &compute.InstancePoolUpdateRequest{
            MinCount: basaltic.Int(0), MaxCount: basaltic.Int(0),
        })
    if err != nil { return err }
    ```

    Un puntero nil omite un campo; `basaltic.Int(0)` envía un cero explícito.
  </Tab>
</Tabs>

Crear el grupo devuelve `201` inmediatamente. Las instancias son generadas por un reconciliador de fondo, que es también lo que converge el grupo hacia `desired_count` cada vez que lo cambias, así que observa el grupo en lugar de esperar miembros en la respuesta de creación.

Cuatro contadores le dicen dónde se encuentra una agrupación, y confundir dos de ellos es la fuente habitual de una falsa alarma:

| Campo de juego | Pregunta que responde |
| - | - |
| `desired_count` | Cuántos has pedido. |
| `member_count` | Cuántos alberga la agrupación, en funcionamiento o no. Esto es lo que refleja el `status`. |
| `live_count` | ¿Cuántos son **up** — miembros en `current_state: running`. **Este es el número para alertar o escalar.** |
| `stale_instance_count` | Cuántos están en una plantilla diferente a la actual. |

<Info>
  `status: "active"` significa `member_count == desired_count` — el grupo tiene los miembros que se le pidieron. **No es una afirmación de que todos ellos están arriba.** Un grupo puede ser `active` con `live_count` por debajo de `desired_count` cuando los miembros se han detenido. Consulta `live_count` para saber cuántos miembros están activos.

  `scaling` significa que no mantiene su objetivo y está convergiendo: después de una creación, después de un cambio en `desired_count`, y durante la duración de una actualización. `error` significa un error de error activo — lea cada entrada en `faults` — y todavía está reconciliado: el grupo sigue siendo reintentado. `deleting` es un desmontaje en curso.
</Info>

Los códigos de escalado (`POOL_LAUNCH_FAILED`, `POOL_SCALE_OUT_FAILED`, `POOL_SCALE_IN_FAILED`) se borran cuando el grupo alcanza su objetivo. Un cambio de tamaño posterior no los borra primero: un grupo que no pudo generarse y se está escalando de nuevo aún no ha demostrado que el error está detrás de él.

| Código | Significado y recuperación |
| - | - |
| `POOL_LAUNCH_FAILED` | Los miembros iniciales no fueron lanzados. Se despeja cuando el grupo alcanza su objetivo. |
| `POOL_SCALE_OUT_FAILED` | El escalado no alcanzó `desired_count`. Se despeja cuando el grupo alcanza su objetivo. |
| `POOL_SCALE_IN_FAILED` | La escalada no alcanzó `desired_count`. Se despeja cuando el grupo alcanza su objetivo. |
| `POOL_REFRESH_FAILED` | Una actualización continua no se completó. Vuelva a intentar la actualización. |
| `POOL_DELETE_FAILED` | El desmantelamiento de la agrupación falló. Vuelve a intentar la eliminación. |

<a id="what-gets-replaced-and-what-does-not" />

### Qué se reemplaza y qué no

Cada paso, el grupo reemplaza cualquier miembro cuyo `current_state` es `error` o `deleted`, y cualquier enlace cuya instancia se ha eliminado de debajo de él. El reemplazo toma el número de secuencia liberado y se inicia desde la plantilla actual del grupo.

<Warning>
  **El grupo no realiza una comprobación de estado de nada dentro del invitado, y no reemplaza a un miembro que detuvo.** Una réplica que es `stopped`, o que se ejecuta pero sirve errores, sigue siendo un miembro: `live_count` Cae para una parada, y nada cambia en absoluto para una aplicación en cuña.

  La sustitución se determina por el fallo de la instancia, no por el fallo de la carga de trabajo. Si necesitas una comprobación de estado a nivel de aplicación, pon un balanceador de carga al frente.
</Warning>

Escalar elimina los **números de secuencia más altos primero**, por lo que una escala de 5 a 3 retira `-4` y `-3`. Cada retiro ejecuta la eliminación de instancia completa, por lo que su cuota, sus volúmenes y sus direcciones se manejan exactamente como para una instancia independiente.

Las réplicas se distribuyen entre los hosts: mejor esfuerzo. Cada nueva réplica evita los hosts que sus hermanos ya ocupan, pero cuando la flota no tiene espacio, la propagación se elimina en lugar de que el lanzamiento falle, por lo que las réplicas pueden terminar compartiendo un host.

<a id="changing-the-template" />

## Cambiar la plantilla

`PATCH /v1/instance-pools/{pool_id}` cambia `desired_count`, `min_count`, `max_count`, `autoscaling`, las `tags` del pool, la `template`, o cualquier combinación. Cada campo es opcional; el envío de ninguno de ellos es un `400` en lugar de un silencioso no-op.

<Tabs>
  <Tab title="Console">
    La pestaña **Settings** del grupo edita tres partes del mismo: **Tags** en el grupo y **Instance tags** y **Instance metadata** en la plantilla de lanzamiento. **Minimum count**, **Maximum count** y **Desired count** están bajo **Scale** en el encabezado.

    <Warning>
      El resto de la plantilla es solo API. No hay control de consola para el tipo de instancia de la plantilla, imagen, volumen de arranque, red, claves SSH, rol IAM o datos de usuario — la página del grupo muestra estos como detalles de solo lectura, y cambiar cualquiera de ellos es un `PATCH`.
    </Warning>

    Debido a que el `PATCH` reemplaza la plantilla por completo, al guardar cualquiera de las dos tarjetas de plantilla se reenvía toda la configuración almacenada: la consola convierte la subred integrada de cada NIC de nuevo a su ID para que no se pierda ninguna interfaz. Si la subred de cualquier NIC no se resuelve, informa a la interfaz y no envía nada, en lugar de guardar una plantilla corta de una NIC.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    PATCH /v1/instance-pools/{pool_id}
    { "desired_count": 4,
      "template": { "...": "the whole launch config" } }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool update <pool-id> --desired-count 4
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    pool, err := compute.New(cfg).UpdateInstancePool(ctx, poolID,
        &compute.InstancePoolUpdateRequest{DesiredCount: basaltic.Int(4)})
    ```
  </Tab>
</Tabs>

<Warning>
  **Una nueva `template` reemplaza la almacenada por completo.** Cualquier cosa que se omita se borra, no se mantiene — reemplazo en lugar de una fusión profunda, por lo que un array `networks` o `volumes` más corto no puede ser leído como una truncado y silenciosamente soltar una interfaz o un disco. Envía toda la configuración que quieras.
</Warning>

Cuando se construye un reemplazo a partir de una respuesta de grupo, convierta el resumen de rol a una referencia de cadena: por ejemplo, establezca `template.iam_role` al `id` o `crn` del resumen. No devuelva el objeto de resumen. Omitir `iam_role` de un reemplazo borra el adjunto para futuros lanzamientos.

De igual manera, convierta la `subnet` incrustada de cada NIC de respuesta a su cadena `id` o `crn` en la solicitud de reemplazo — vea [referencias y respuestas de subred](#subnet-references-and-responses). Una subred nula necesita una referencia de reemplazo válida; no copie los objetos de respuesta directamente en la solicitud. Haga esto para **cada** entrada de `networks`, no solo la primaria: una NIC extra que se ha eliminado porque su subred no pudo convertirse es una interfaz sin la que se inicia la próxima réplica.

Un cambio de plantilla decide lo que el grupo lanza **a continuación**. Las instancias que ya se están ejecutando mantienen lo que arrancaron, porque una máquina virtual en vivo no puede cambiar el tipo de instancia, el nivel, la subred o sus etiquetas en su lugar.

Así que entre la edición y un roll, el grupo tiene legítimamente miembros de dos plantillas diferentes. `stale_instance_count` es cuántas instancias hay en la más antigua, y un valor diferente a cero es la señal de que un cambio de plantilla aún no se ha implementado.

<Note>
  Esta es la misma división entre "editar la plantilla" y "reemplazar las instancias" que un `PATCH` que reemplaza silenciosamente a cada miembro en ejecución borraría — una operación destructiva que lleva la forma de una edición.
</Note>

<a id="rolling-the-pool" />

### Rodando la agrupación

<Tabs>
  <Tab title="Console">
    1. Abra **Instance pools** y seleccione su grupo.
    2. Elija **Roll instances** junto a **Scale**.
    3. Confirme el reemplazo de cada miembro en ejecución en una plantilla antigua o desconocida. Los miembros de la plantilla actual se conservan. Sin margen de sobrecarga, el rollo espera; use **Scale** para aumentar **Maximum count** por encima de **Desired count** (hasta 100).
    4. Observa **Roll in progress** e **Stale instances**. Un conteo de cero no significa que el rollo haya terminado mientras que **Roll in progress** permanece.

    **Refresh** recarga los datos de la página. No se rotan instancias.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/instance-pools/{pool_id}/refresh
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool refresh <pool-id>
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    pool, err := compute.New(cfg).RefreshInstancePool(ctx, poolID)
    ```
  </Tab>
</Tabs>

Responde `202` con el grupo tal como está, y reemplaza todos los miembros no lanzados desde la plantilla actual, incluyendo cualquiera que sea anterior al seguimiento de plantillas. Asíncrono, y deliberadamente así: cada reemplazo es un arranque de VM, y una solicitud que esperaba se agotaría mucho antes de que un grupo de cualquier tamaño terminara.

<Steps>
  <Step title="Un miembro por pase">
    El conciliador retira a un miembro obsoleto a la vez, el más antiguo primero, de modo que el rollo recorre el grupo en un orden predecible.
  </Step>

  <Step title="Y solo una vez que la agrupación está entera">
    La próxima retirada espera hasta que el grupo esté por encima del tamaño deseado con todos los miembros en ejecución. Una plantilla que no arranca, por lo tanto, **detiene el rollo con el grupo intacto**, en lugar de bajarlo una instancia a la vez.
  </Step>

  <Step title="La capacidad no se hunde">
    Con el margen de maniobra, el grupo lanza una instancia sobre su objetivo, por lo que un reemplazo ya está en servicio antes de que se retire cualquier cosa. `desired_count` no se toca — el aumento se deriva, no se escribe en lo que usted pidió.
  </Step>
</Steps>

<Warning>
  Cuando `max_count == desired_count`, una actualización espera en lugar de retirar un miembro obsoleto por debajo de la capacidad deseada. Esto también se aplica si una actualización de límites elimina el espacio libre durante un lanzamiento. El escalamiento y la curación normales continúan; la reducción deseada todavía puede retirar a los miembros como parte del escalamiento.

  Aumenta `max_count` por encima de `desired_count` para permitir que continúe la actualización gradual. Por ejemplo, con un valor deseado de 3 y un máximo de 3, aumenta el máximo a 4 y deja el valor deseado sin cambios mediante [los controles de tamaño](#adjusting-the-bounds). La actualización en espera se reanuda automáticamente. Al alcanzar el límite de 100 de la plataforma, añadir capacidad libre requiere reducir primero el valor deseado, lo que reduce la capacidad solicitada.
</Warning>

Observe `refresh_in_progress` y `stale_instance_count` para el progreso del rollo, y `member_count` y `live_count` para la capacidad. Un conteo de cero obsoletos solo significa que ningún miembro usa una plantilla antigua. Después de que se borre el indicador de actualización, es posible que el grupo aún necesite quitar su miembro de aumento y converger al deseado. Espere a que la bandera sea false, `status: "active"`, y ambos conteos sean iguales antes de tratar la capacidad como liquidada.

Si se vuelve a preguntar mientras se está ejecutando un rollo, se acepta y no se reinicia.

<a id="two-sets-of-tags" />

### Dos conjuntos de etiquetas

Un grupo lleva dos mapas de etiquetas y responden a preguntas diferentes.

<Columns cols={2}>
  <Card title="tags" icon="tag">
    Etiqueta el **recurso de grupo**. Leído por las condiciones de IAM como `basalt:ResourceTag/<key>` y utilizado para la atribución de costos. Toma efecto inmediatamente, no toca ninguna instancia y reemplaza todo el conjunto — un objeto vacío los borra, un campo omitido los deja solos.
  </Card>

  <Card title="Etiquetas de template.tags" icon="tags">
    Estampado en **cada réplica de la agrupación lanza**. Parte de la configuración de lanzamiento, por lo que cambiarlo afecta solo a lanzamientos futuros y necesita una actualización para alcanzar lo que ya está en ejecución.
  </Card>
</Columns>

Editar `template.tags` solo es la forma más fácil de terminar con un grupo cuyos miembros llevan dos conjuntos de etiquetas diferentes, lo que importa si una política de IAM o un informe de costos tiene claves en ellos. `stale_instance_count` es cuántas instancias aún están en el conjunto antiguo.

<a id="one-address-for-the-whole-pool" />

## Una dirección para toda la agrupación

`POST /v1/instance-pools/{pool_id}/floating-ips` vincula una IP flotante que ya ha asignado al grupo. Una IP pública, respondida por cada réplica — una dirección anycast — en oposición a `template.networks[0].floating_ip_assignment`, que da a cada réplica la suya propia.

<Tabs>
  <Tab title="Console">
    La pestaña **Floating IPs** del grupo muestra sus direcciones compartidas y ofrece **Attach floating IP**, que selecciona las direcciones que tienes que no están adjuntas a nada.

    **One address, every replica** explica la membresía y la preparación. Las columnas **Members**, **Healthy**, **Unhealthy** y **Unknown health** distinguen la membresía de la elegibilidad de tráfico. Un grupo vacío conserva la propiedad de sus direcciones compartidas.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/instance-pools/{pool_id}/floating-ips
    { "floating_ip": "3f9a1c7e-5b2d-4e8a-9c1f-6d3b7a2e5c9f" }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool attach-floating-ip <pool-id> --floating-ip <floating-ip-id>
    basaltic compute instance-pool detach-floating-ip <pool-id> <floating-ip-id>
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    c := compute.New(cfg)
    fip, err := c.AttachInstancePoolFloatingIP(ctx, poolID,
        &compute.InstancePoolFloatingIPAttachRequest{FloatingIP: floatingIPID})
    err = c.DetachInstancePoolFloatingIP(ctx, poolID, floatingIPID)
    ```
  </Tab>
</Tabs>

El `attached_to` de la IP flotante nombra el CRN canónico del grupo, incluso cuando `members` está vacío. Todas las réplicas activas pueden convertirse en miembros, incluidas las réplicas del mismo host. Lea la interfaz embebida y los resúmenes de instancia en `members` para identificarlos; vea [Leyendo los enlaces](/es/networking/floating-ips#reading-the-bindings).

La membresía se mantiene para usted: un miembro de escalada se une, un miembro de escalada se va, un miembro reemplazado se intercambia. No hay que realizar ningún acoplamiento por réplica, y los propios acoplamiento y desconectado del servicio de red se rechazan en la dirección de un grupo; use estos dos extremos.

<a id="it-is-not-a-load-balancer" />

### No es un balanceador de carga

Con más de un miembro, el borde de la región elige **un miembro por conexión**, mediante el hash de las direcciones y puertos del flujo, y cada paquete de esa conexión va a la misma. Eso extiende las conexiones a través de instancias independientes y sobrevive a la pérdida de un host.

<Warning>
  Sin una IP flotante configurada `health_check`, el estado indica la actividad del invitado, no la preparación de la aplicación. Los miembros de arranque permanecen en la lista como no activos y no reciben tráfico hasta que se admiten; las imágenes que nunca se comunican con el servicio de metadatos de instancia se admiten después de unos minutos. Configure una comprobación de preparación si el tráfico debe esperar a su aplicación. Los miembros no saludables no reciben tráfico, y si todos fallan la dirección se oscurece.

  Las conexiones en curso a un miembro que se va terminan. No hay terminación TLS, enrutamiento de solicitudes ni manera de ponderar a los miembros.
</Warning>

<a id="requirements-and-removal" />

### Requisitos y retiro

La IP flotante debe ser **unattached** (`attached_to: null`) y suya, y la subred del grupo debe ya enrutar `0.0.0.0/0` a una puerta de enlace de internet. La adjunción es idempotente: volver a adjuntar la misma dirección al mismo grupo la devuelve sin cambios. Un `409` significa que la dirección ya está adjunta a algo, o ya pertenece a otro grupo.

`DELETE /v1/instance-pools/{pool_id}/floating-ips/{floating_ip_id}` detiene el enrutamiento de la dirección al grupo. En la consola es la acción de fila en la pestaña **Floating IPs**, confirmada como **Detach floating IP**.

<Note>
  **La dirección no se libera.** La asignaste, permanece tuya y no adjunta, para reutilizarla o liberarla con `DELETE /v1/floating-ips/{floating_ip_id}`. Desconectar uno del grupo no contiene respuestas `204`.
</Note>

`GET /v1/instance-pools/{pool_id}/floating-ips` lista las direcciones compartidas con sus miembros actuales en `floating_ips`, más paginación `meta`, usando la misma forma de respuesta que la lista de IP flotante de nivel superior. Acepta `name`, `crn`, `limit` y `marker`. Las IP flotantes no tienen nombre, por lo que si se proporciona `name` se devuelve una lista vacía. Mientras `meta.has_more` es true, pasa `meta.marker` como `marker` en la siguiente solicitud, preservando los filtros y el límite, y recolecta `floating_ips` de cada página.

Las direcciones por réplica no están aquí, pertenecen a la réplica y se leen desde la [lista de NIC](/es/compute/attachments#network-interfaces) de la instancia.

<a id="deleting-a-pool" />

## Eliminar un grupo

<Tabs>
  <Tab title="Console">
    **Delete pool** está en la pestaña **Settings** de la agrupación, en la zona de peligro. La confirmación reitera el costo (termina todas las máquinas virtuales del grupo) y necesita que se escriba de nuevo el nombre del grupo.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    DELETE /v1/instance-pools/{pool_id}
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance-pool delete <pool-id>
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    err := compute.New(cfg).DeleteInstancePool(ctx, poolID)
    ```
  </Tab>
</Tabs>

Derriba todas las instancias que posee el pool y deja caer el pool. Es idempotente, y responde `204`.

Eliminar el grupo es la única forma de eliminar sus miembros: eliminar una réplica directamente solo libera su número de secuencia, y el grupo genera un reemplazo para ella en la siguiente pasada.

<a id="permissions" />

## Permisos

Cada operación de grupo autoriza contra `crn:compute:<region>:<account>:instance-pool/<name>`, que es el valor que una declaración de política de IAM debe nombrar para ampliar un permiso a un grupo.

<Note>
  Una actualización autoriza como **`compute:UpdateInstancePool`**, la misma acción que un `PATCH`, no como una acción propia. Por lo tanto, otorgar a alguien la capacidad de editar un grupo también le otorga la capacidad de rodarlo, lo que reemplaza a todos los miembros en ejecución.
</Note>

Las réplicas se lanzan como el principal que creó el grupo, de modo que el permiso `compute:CreateInstance` del principal — y su `iam:PassRole` en `template.iam_role`, si la plantilla tiene uno — es lo que se ejecuta bajo cada curación y escalado posterior. Consulte [policies](/es/iam/policies) y [roles](/es/iam/roles).

<a id="troubleshooting" />

## Solución de problemas

<AccordionGroup>
  <Accordion title="La agrupación dice activa pero la capacidad está baja" icon="activity">
    `active` significa `member_count == desired_count`, no que los miembros estén activos. Lee `live_count`. Un espacio entre ellos son los miembros que existen y no se están ejecutando (detenidos, todavía arrancando o enclavados) y el grupo no reemplaza a un miembro detenido.
  </Accordion>

  <Accordion title="Una actualización no está progresando" icon="loader">
    Primero compara `max_count` con `desired_count`. Si no hay espacio libre para sobretensiones, aumente el máximo por encima del deseado (hasta 100). La actualización permanece solicitada y se reanuda sin otra llamada de actualización. Los cambios de límites durante una actualización pueden ponerlo en este estado de espera; el escalado normal continúa.

    Con espacio libre, el rollo espera un reemplazo por encima del deseado con **cada** miembro corriendo antes de retirar al siguiente. Si la nueva plantilla no arranca, el rollo se detiene allí por diseño en lugar de vaciar el grupo — compruebe los `faults` de la réplica más reciente y su [salida de consola](/es/compute/console).

    `stale_instance_count` deja de caer tan pronto como eso sucede, y `refresh_in_progress` permanece verdadero.
  </Accordion>

  <Accordion title="Edité la plantilla y nada cambió" icon="git-branch">
    Se esperaba. Cuando se construye un reemplazo a partir de una respuesta de grupo, convierta el resumen de rol a una referencia de cadena: por ejemplo, establezca `template.iam_role` al `id` o `crn` del resumen. No devuelva el objeto de resumen. Omitir `iam_role` de un reemplazo borra el adjunto para futuros lanzamientos.

    Un cambio de plantilla decide qué lanza el grupo a continuación; las instancias que ya se están ejecutando mantienen lo que arrancaron. `stale_instance_count` los cuenta, y `POST /v1/instance-pools/{pool_id}/refresh` los actualiza.
  </Accordion>

  <Accordion title="La plantilla perdió una tarjeta de red o un volumen de datos" icon="triangle-alert">
    `template` en un `PATCH` reemplaza por completo la configuración almacenada: se borra todo lo que se omita. Vuelve a leer el pool y prepara la solicitud completa de reemplazo, convirtiendo el resumen del rol en una referencia de cadena, como se describe en [Cambiar la plantilla](#changing-the-template).
  </Accordion>

  <Accordion title="La dirección compartida tiene menos miembros que el grupo tiene réplicas" icon="globe">
    Compare las réplicas en vivo del grupo con los resúmenes de miembros incrustados de la dirección. La membresía converge a medida que se colocan y eliminan réplicas; los miembros pueden compartir un host. Compruebe la `health` y la `reason` de cada miembro por separado: los miembros que arrancan o fallan permanecen en la lista pero no reciben tráfico. Una lista de miembros vacía no borra la propiedad `attached_to` del grupo.
  </Accordion>

  <Accordion title="Adjuntar una IP flotante al grupo de respuestas 400" icon="circle-x">
    Tres causas, y el mensaje dice cuál: el id falta o está mal formado; la subred del grupo no tiene ruta predeterminada a una puerta de enlace de Internet; o la región no tiene direcciones de grupo compartidas activadas. Un `409` es diferente — es una dirección ya adjunta a otra cosa, o ya poseída por otro grupo.
  </Accordion>

  <Accordion title="Una réplica que borré volvió" icon="rotate-cw">
    El grupo converge hacia `desired_count`, por lo que la eliminación de un miembro se lee como deriva y se rellena en el número de secuencia liberado. Baja `desired_count`, o elimina el grupo.
  </Accordion>

  <Accordion title="Crear o cambiar el tamaño de la agrupación responde 400 en el tamaño" icon="ruler">
    Utilice números enteros con `0 ≤ min_count ≤ max_count ≤ 100`. Un `desired_count` explícito debe caer dentro de esos límites. Al crear, los límites omitidos se establecen por defecto en los deseados; al actualizar, conservan los límites almacenados. Omita lo deseado en la actualización para sujetarlo automáticamente. El tamaño no válido no aplica ninguna de las actualizaciones. Para crecer más allá del máximo original, aumente `max_count` antes o junto con desired.
  </Accordion>
</AccordionGroup>

<a id="next" />

## Siguiente

<CardGroup cols={2}>
  <Card title="Instancias" icon="server" href="/es/compute">
    Todo lo que es una réplica: tipos de instancia, imágenes, discos, interfaces y el ciclo de vida.
  </Card>

  <Card title="Imágenes" icon="disc" href="/es/compute/images">
    Fijar una compilación para que las réplicas de un grupo permanezcan idénticas.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.