Cómo dejar de pagar por Elastic IPs en AWS: Disociar vs. Liberar

Detuviste tu instancia EC2 para ahorrar costos, pero al revisar la factura del mes te encuentras con cargos por una Elastic IP que juraste haber 'apagado'. Este es uno de los errores de facturación más comunes en AWS — y la razón es que detener una instancia no libera su Elastic IP. La IP sigue siendo tuya, sigue reservada, y AWS te cobra por eso.

TL;DR: Resumen del problema con Elastic IPs

Estado ¿Se cobra la EIP? ¿Qué hacer?
Instancia corriendo + EIP asociada No (uso activo) Nada, es el caso normal
Instancia detenida + EIP asociada Disociar y liberar si no la necesitas
EIP sin asociar a ningún recurso Liberar inmediatamente
EIP liberada No Ya no existe en tu cuenta

Cómo funcionan las Elastic IPs y por qué generan cargos

Una Elastic IP (EIP) es una dirección IPv4 pública estática que AWS reserva exclusivamente para tu cuenta. A diferencia de las IPs públicas automáticas que desaparecen al detener una instancia, una EIP persiste hasta que tú explícitamente la liberas.

El modelo de cobro de AWS es deliberado: las direcciones IPv4 públicas son un recurso escaso. AWS cobra por EIPs que están reservadas pero no están siendo utilizadas activamente. El criterio de 'uso activo' es concreto: una EIP está en uso cuando está asociada a una instancia EC2 en estado running, o a una interfaz de red elástica (ENI) que esté adjunta a una instancia en ejecución.

Piensa en una EIP como una plaza de aparcamiento reservada en un garaje. Mientras tu coche está aparcado ahí, pagas la tarifa normal. Pero si reservas la plaza y no aparecas el coche — o lo sacas y dejas la plaza vacía — sigues pagando la reserva. AWS cobra la plaza vacía para desincentivar el acaparamiento de IPs.

Cuando detienes una instancia EC2, la instancia pasa a estado stopped. La EIP sigue asociada a esa instancia, pero como la instancia no está corriendo, AWS considera la IP como 'no utilizada' y comienza a generar cargos por hora.

stateDiagram-v2 [*] --> Running: Instancia lanzada con EIP Running --> Stopped: ec2 stop-instances Stopped --> Running: ec2 start-instances Running --> Released: Disociar + Liberar EIP Stopped --> Released: Disociar + Liberar EIP Released --> [*] Running: Running ✅ Sin cargo por EIP Stopped: Stopped ⚠️ Cargo por EIP activo Released: EIP Liberada ✅ Sin cargo
  1. Estado Running + EIP asociada: sin cargo adicional por la EIP.
  2. Estado Stopped + EIP asociada: la EIP queda ociosa — cargo por hora activo.
  3. EIP sin asociar: también genera cargo, independientemente del estado de cualquier instancia.
  4. EIP liberada: devuelta al pool de AWS, sin cargo, sin acceso.

La diferencia crítica: Disociar vs. Liberar una Elastic IP

Aquí es donde muchos usuarios cometen el segundo error. Disociar y liberar son operaciones distintas con consecuencias muy diferentes.

Disociar (disassociate-address) desvincula la EIP de la instancia o ENI, pero la IP sigue siendo tuya. Sigue apareciendo en tu lista de Elastic IPs. Y sigue generando cargos porque ahora está en estado 'no asociada'.

Liberar (release-address) devuelve la IP a AWS definitivamente. Desaparece de tu cuenta, deja de generar cargos, y no puedes recuperarla (aunque en ocasiones AWS puede reasignarte la misma IP si está disponible, esto no está garantizado).

graph TD A["EIP asociada a instancia detenida"] --> B{"¿Qué acción tomas?"} B --> C["Solo Disociar"] B --> D["Disociar + Liberar"] B --> E["Solo Liberar"] C --> F["EIP queda sin asociar ⚠️ Cargo continúa"] D --> G["EIP devuelta a AWS ✅ Cargo eliminado"] E --> H["Error: debe disociarse primero si está asociada"] F --> I["Debes liberar para eliminar el cargo"] I --> G
  1. Disociar únicamente: la EIP queda flotante, sin recurso asociado — los cargos continúan.
  2. Liberar sin disociar primero: si la EIP está asociada a una instancia detenida, debes disociarla antes de poder liberarla.
  3. Disociar + Liberar: el único flujo que elimina los cargos completamente.

Cómo detener los cargos de Elastic IPs: paso a paso

Si ya no necesitas la EIP, el proceso es directo. Si la necesitas para el futuro (por ejemplo, tienes DNS apuntando a esa IP), evalúa si realmente vale la pena mantenerla reservada o si puedes actualizar el DNS cuando relances la instancia.

Paso 1: Identificar las EIPs que están generando cargos

Antes de liberar nada, audita qué EIPs tienes y cuáles están ociosas. Las EIPs sin asociar o asociadas a instancias detenidas son las candidatas al cargo. Este comando lista todas las EIPs de tu cuenta en la región configurada:

aws ec2 describe-addresses \
  --query 'Addresses[*].{IP:PublicIp,AllocationId:AllocationId,InstanceId:InstanceId,AssociationId:AssociationId,Domain:Domain}' \
  --output table \
  --region us-east-1

Fíjate en las filas donde InstanceId está vacío (EIP sin asociar) o donde la instancia asociada esté en estado stopped. Esas son las que están generando cargos ahora mismo.

Para cruzar el estado de la instancia directamente:

aws ec2 describe-instances \
  --filters 'Name=instance-state-name,Values=stopped' \
  --query 'Reservations[*].Instances[*].{InstanceId:InstanceId,State:State.Name,PublicIp:PublicIpAddress}' \
  --output table \
  --region us-east-1

Paso 2: Disociar la EIP de la instancia detenida

Con el AssociationId obtenido en el paso anterior, ejecuta la disociación. Necesitas el AssociationId, no el AllocationId — son identificadores distintos.

aws ec2 disassociate-address \
  --association-id eipassoc-0a1b2c3d4e5f67890 \
  --region us-east-1

Si la EIP ya estaba sin asociar (no tiene AssociationId), omite este paso y pasa directamente al siguiente.

Paso 3: Liberar la EIP para eliminar el cargo definitivamente

Una vez disociada, usa el AllocationId para liberar la IP. Para EIPs en VPC (que es el caso estándar hoy en día), siempre usa --allocation-id:

aws ec2 release-address \
  --allocation-id eipalloc-0a1b2c3d4e5f67890 \
  --region us-east-1

Si el comando no devuelve error, la IP fue liberada. Puedes verificar que ya no aparece en tu cuenta:

aws ec2 describe-addresses \
  --region us-east-1 \
  --output table

Paso 4: Verificar en Cost Explorer que el cargo se detiene

Los cargos por EIP se acumulan por hora. Después de liberar la IP, el cargo cesa en la siguiente hora. Para confirmar en Cost Explorer que el servicio AmazonEC2 ya no incluye cargos por direcciones IP elásticas, revisa el desglose por tipo de uso (Usage Type) buscando entradas del tipo ElasticIP:IdleAddress en tu región.

aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-01-31 \
  --granularity MONTHLY \
  --filter '{"Dimensions":{"Key":"USAGE_TYPE_GROUP","Values":["EC2: Elastic IP Addresses"]}}' \
  --metrics BlendedCost \
  --region us-east-1

El error que cometí y probablemente tú también: disociar sin liberar

El escenario clásico: recibes la alerta de facturación, entras a la consola, ves la EIP asociada a tu instancia detenida, haces clic en 'Disassociate' pensando que eso resuelve el problema. Cierras la consola satisfecho.

Al mes siguiente, el cargo sigue ahí. Vuelves a la consola y ves la EIP listada, ahora sin ningún recurso asociado. El estado dice exactamente lo que AWS cobra: 'Not associated'.

La suposición incorrecta es que 'disociar' equivale a 'devolver'. No lo hace. Disociar es como sacar el coche de la plaza de aparcamiento reservada — la plaza sigue siendo tuya y sigues pagando. Liberar es cancelar la reserva.

La causa raíz del error es que la consola de AWS presenta ambas acciones en el mismo menú contextual sin indicar claramente que disociar sin liberar mantiene el cargo. El flujo correcto siempre termina en Release.

Política IAM mínima para gestionar Elastic IPs

Si necesitas dar permisos a un rol o usuario para auditar y liberar EIPs sin acceso completo a EC2:

🔽 Ver política IAM mínima para gestión de EIPs
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DescribeElasticIPs",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeAddresses",
        "ec2:DescribeInstances"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ManageElasticIPs",
      "Effect": "Allow",
      "Action": [
        "ec2:DisassociateAddress",
        "ec2:ReleaseAddress"
      ],
      "Resource": "*"
    }
  ]
}

Las acciones DescribeAddresses y DescribeInstances requieren "Resource": "*" — no admiten restricción por ARN de recurso específico según la Service Authorization Reference de AWS.

Cuándo conservar una EIP aunque genere cargo

Hay casos legítimos donde mantener una EIP ociosa tiene sentido operativo:

  • DNS crítico: tienes registros A apuntando a esa IP y el TTL de propagación haría costoso un cambio. En este caso, evalúa si el costo de la EIP ociosa es menor que el riesgo operativo de cambiar la IP.
  • Allowlisting en terceros: la IP está en listas blancas de firewalls externos o APIs de socios que tardan días en actualizar. Perder la IP significa abrir un ticket de soporte con el tercero.
  • Instancia que se reiniciará pronto: si la instancia estará detenida menos de 24 horas, el costo acumulado puede ser menor que el riesgo de perder la IP.

En cualquier otro caso, libera la IP. Puedes asignar una nueva EIP cuando relances la instancia — el costo de reasignación es cero.

Próximos pasos: Cómo dejar de pagar por Elastic IPs de forma sistemática

Para evitar que esto vuelva a ocurrir, considera estas acciones preventivas:

  • Configura una alerta de AWS Budgets para el tipo de uso ElasticIP:IdleAddress — recibirás una notificación antes de que el cargo se acumule durante un mes completo.
  • Usa AWS Config con la regla eip-attached para detectar automáticamente EIPs no asociadas en tu cuenta. Esta regla managed está disponible en AWS Config y no requiere código personalizado.
  • Automatiza la auditoría mensual con el comando describe-addresses en un Lambda o script de CI/CD que alerte cuando haya EIPs sin InstanceId.
  • Consulta la documentación oficial de AWS sobre Elastic IP Addresses para revisar el modelo de precios actualizado — los precios y condiciones de cargo varían, siempre verifica la documentación oficial.

Glosario de términos clave

Término Definición operativa
Elastic IP (EIP) Dirección IPv4 pública estática reservada para una cuenta AWS. Persiste hasta ser liberada explícitamente.
AllocationId Identificador único de la EIP en tu cuenta (formato eipalloc-*). Se usa para liberar la IP.
AssociationId Identificador de la vinculación entre una EIP y una instancia o ENI (formato eipassoc-*). Se usa para disociar.
Disociar (Disassociate) Desvincular la EIP de un recurso. La IP sigue siendo tuya y puede seguir generando cargos.
Liberar (Release) Devolver la EIP al pool de AWS. Elimina el cargo y la IP desaparece de tu cuenta definitivamente.

Comentarios

Entradas populares de este blog

EC2 sin acceso a Internet en VPC personalizada: Internet Gateway y Route Table

Actualizar Contenido en CloudFront: Cómo Crear una Invalidación para Limpiar el Caché del Edge

Aumentar el Timeout de Lambda: Configuración, Límites y Diagnóstico en Producción