Cómo iniciar y detener la instancia de AWS EC2 según un cronograma basado en el tiempo

17

¿Hay una manera fácil de iniciar y detener instancias de AWS EC2 en un momento determinado cada día? Esto podría ahorrarme bastante dinero para mis servidores de desarrollo y prueba.

Tim
fuente

Respuestas:

16

Actualizar

AWS ha lanzado una herramienta llamada " Programador de instancias ", que incluye una guía de configuración completa que está vinculada desde esa página. Parece ser una mejora del Programador EC2 que describo a continuación, con algunas características más, pero es esencialmente lo mismo.

La guía a continuación seguirá funcionando, pero probablemente sea mejor mirar el programador de instancias para nuevas instalaciones.

Publicación original

AWS tiene una herramienta llamada Programador EC2 que le brinda un control muy flexible sobre el inicio y la detención de instancias EC2.

La herramienta le permite definir las horas de inicio y detención predeterminadas cuando configura la herramienta, que puede cambiar más adelante. Puede elegir qué instancias se controlan, usted y puede especificar diferentes tiempos de inicio y detención para cada instancia utilizando etiquetas.

Si bien es una gran herramienta, la documentación es algo vaga y confusa. Es como si la documentación hubiera sido escrita por un ingeniero que escribió la herramienta y sabe todo al respecto, en lugar de un escritor técnico.

Nota : si tiene comentarios o correcciones, los comentarios son apreciados. Si tiene una pregunta basada en esto, comience su propia pregunta.

¿Qué es el programador EC2?

Esta herramienta es una función Lambda que funciona con Cloudwatch Events y DynamoDB. Se implementa utilizando una plantilla de Cloudformation, que también configura los roles y políticas de IAM necesarios. Puedes leer sobre la arquitectura aquí .

Arquitectura del planificador de AWS EC2

Despliegue

Comience yendo a esta página y haciendo clic en "iniciar solución". En este momento el enlace directo está aquí , pero podría cambiar.

Seleccione la región en la que desea implementar los recursos en la parte superior de la consola. El script controla las instancias de EC2 en cualquier región, pero se ejecuta en una región.

Etiquetado de instancias EC2

Esto está cubierto en la documentación aquí , pero no es tan simple como podría ser.

Usted controla qué instancias se inician y detienen etiquetando sus instancias.

El caso más simple requiere que etiquete cada instancia de EC2 que desea que se inicie y se detenga de acuerdo con la programación. Para hacer esto, encuentre su instancia EC2 en la consola, haga clic en etiquetas y cree esta etiqueta

Etiquetado de instancias EC2 para el planificador

Para habilitar copiar y pegar:

  • Clave: planificador: ec2-begintop
  • Valor: verdadero

Si desea iniciar y detener una instancia específica en un horario diferente, agregue información adicional a la clave y al valor de la etiqueta. Por ejemplo, si desea que una instancia comience a las 1500 UTC y se detenga a las 2400 UTC los martes, jueves y viernes, ingrese lo siguiente.

Clave: planificador: ec2-begintop: tarde Valor: 1500; 2400; utc; martes, jueves, viernes

Tenga en cuenta que la palabra "tarde" puede ser cualquier cadena, "tarde" no tiene un significado especial.

Puede convertir UTC a su hora local utilizando esta herramienta .

Puede usar el editor de etiquetas para etiquetar instancias en masa. Eso podría permitirle configurar más fácilmente el etiquetado masivo, lo que podría ser útil para tener diferentes configuraciones para desarrollo, prueba y producción. Sin embargo, dudo que uses esto en producción.

Parámetros de CloudFormation

Cuando ejecuta la plantilla CloudFormation, debe ingresar muchos parámetros. La mayoría se puede dejar por defecto. Estos son algunos de los parámetros más importantes.

  • Nombre de pila: llámalo como quieras. Es justo lo que se llama en CloudFormation.
  • Nombre de etiqueta personalizada: esta es la "clave" de la etiqueta que coloca contra la instancia EC2. Déjelo en el valor predeterminado a menos que tenga una buena razón o necesite varias instalaciones.
  • Hora predeterminada de inicio / detención: hora UTC predeterminada para iniciar y detener las instancias
  • DynamoDB: la configuración se almacena en DynamoDB. Puede cambiar el nombre de la tabla y tal. Debido a que el nivel gratuito DynamoDB no caduca, es poco probable que se cobre a la mayoría de las personas.
  • (segunda pantalla) Permisos: este es un arenque rojo, consulte la sección a continuación. Déjelo como predeterminado y ejecútelo como administrador cuando intente configurar el Programador EC2.
  • Opciones de notificación: me pareció útil configurar notificaciones SNS para poder validar que funcionaba. No he pasado el tiempo para averiguar cómo deshabilitarlos, simplemente lo eliminé y volví a ejecutar la plantilla de Cloudformation para reinstalar.

Permisos, Políticas y Roles

La sección de permisos / rol de IAM de la plantilla CloudFormation es una pista falsa, es decir, es en gran medida irrelevante. Especifica solo el rol utilizado para ejecutar el script de CloudFormation, no importa los recursos creados o el rol utilizado cuando se ejecuta la función lambda. En retrospectiva, esto es obvio, pero no lo era para mí cuando comencé.

Cualquiera que sea el rol que ejecute este script, el mismo rol y los permisos en línea se crean dentro de IAM. La función Lambda se ejecuta utilizando una "función de planificador ec2" que crea el script.

He incluido mis políticas a continuación en caso de que sean útiles para alguien.

Eventos y métricas de CloudWatch

Si desea ver los registros de su función Lambda, vaya a Eventos de Cloudwatch. El registro es bastante bueno. También hay métricas, para que pueda ver cuándo se ejecuta, el tiempo para el que se ejecuta, etc.

Adicional

El código para la función lambda está disponible en Github .

Políticas

Generalmente no son necesarios, pero podrían ser para alguien, así que los incluiré.

Política para el rol de IAM

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "iam:CreateRole",
                "iam:GetRole",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DeleteRole",
                "dynamodb:*",
                "lambda:*",
                "SNS:Publish",
                "events:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "S3:GetObject",
            "Resource": [
                "arn:aws:s3:::solutions-us-west-2",
                "arn:aws:s3:::solutions-us-west-2/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:StartInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:123456789012:instance/i-0d112345Ab6789012"
            ]
        }
    ]
}

Política de confianza para el rol de IAM

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "cloudformation.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
Tim
fuente
Desde entonces, Amazon ha cambiado las cosas: "El Programador EC2 ha sido reemplazado por el Programador de instancias de AWS"
Max Barraclough
Gracias Max, he actualizado la respuesta para incluir un enlace. Viene con una guía de implementación completa, así que no creo que necesite proporcionar instrucciones completas.
Tim
1
Es increíble cómo les gusta complicar las cosas ...
Mehdi
10

Si solo desea iniciar y detener instancias, aquí hay otra versión de esto que también hace uso del servicio Lambda. Se supone que desea controlar una identificación de instancia específica. Puede controlar varias instancias agregando más identificadores separados por una coma. (por ejemplo, 'i-3453453', 'i-45656745'). Puede encontrar la identificación de su instancia en la sección Instancias de la consola de AWS.

En la consola Lambda

  1. Abra la consola de AWS Lambda y elija Crear función.
  2. Elija Autor desde cero.
  3. Ingrese un Nombre para su función, como "StopEC2Instances".
  4. Para Runtime, seleccione Python 2.7
  5. Expanda el menú desplegable Rol y elija Crear un rol personalizado. Esto abre una nueva pestaña o ventana en su navegador.
  6. En el menú desplegable Rol de IAM, seleccione Crear un nuevo Rol de IAM e ingrese un Nombre de rol, como "lambda_start_stop_ec2".
  7. Elija Ver documento de política, Editar, y luego elija Aceptar cuando se le solicite que lea la documentación. Reemplace todo el texto en la política con esto:

Código abajo

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Start*",
        "ec2:Stop*"
      ],
      "Resource": "*"
    }
  ]
}
  1. Elija Permitir para terminar de crear el rol y volver a la consola de AWS Lambda.
  2. Para detener sus instancias, reemplace todo el texto en el editor de código de función con lo siguiente:

Código abajo

import boto3
region = ' eu-west-1'
instances = ['i-0dd344443184503fa']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.stop_instances(InstanceIds=instances)
    print 'stopped your instances: ' + str(instances)

Recuerde reemplazar los valores de región e instancia por los suyos.

  1. En el menú desplegable Tiempo de ejecución, elija Python2.7.
  2. En Configuración básica, ingrese 10 segundos para la función Tiempo de espera.
  3. Elija Guardar
  4. Repita todos los pasos para crear otra función que inicie sus instancias, pero luego use este script de Python para iniciarlo todo:

Código abajo

import boto3
region = 'eu-west-1'
instances = [' i-0dd344443184503fa']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.start_instances(InstanceIds=instances)
    print 'started your instances: ' + str(instances)

Programar las funciones

Aquí creará un evento CloudWatch que activará su función Lambda por la noche

  1. Abra la consola de Amazon CloudWatch.
  2. Elija Eventos y luego elija Crear regla.
  3. Elija Programar en Origen del evento.
  4. Ingrese un intervalo de tiempo o una expresión cron que le indique a Lambda cuándo detener sus instancias. Para obtener más información sobre la sintaxis correcta, consulte Programar sintaxis de expresión para reglas.

Nota: Las expresiones de Cron se evalúan en UTC. Asegúrese de ajustar la expresión para su zona horaria preferida. Aquí hay un ejemplo que ejecutará la función todos los días a las 08:00 GMT / UTC):

0 08 * * ? *
  1. Elija Agregar destino y luego elija la función Lambda.
  2. Para Función, elija la función Lambda que detiene sus instancias.
  3. Elija Configurar detalles.
  4. Ingrese la siguiente información en los campos provistos: Para Nombre, ingrese un nombre significativo, como "StopEC2Instances". Para Descripción, agregue una descripción significativa, como "detiene las instancias de EC2 todos los días por la noche". Para Estado, seleccione Activado.
  5. Elija Crear regla.

Para reiniciar sus instancias por la mañana, repita estos pasos y use su hora de inicio preferida. Si desea enviar un mensaje de correo cada vez que las funciones fallan, puede configurar un tema de SNS y configurar el envío de ese mensaje en Depuración en la Ventana de creación de funciones de Lmbda.

La fuente de todo esto se puede encontrar aquí: documentación de AWS

netfed
fuente
¿Cómo puede hacer que el código de Python se vea bien en el editor, como se acaba de ver?
netfed
Haga clic en la ayuda '?' y encontrará más información sobre el uso del formato de descuento. serverfault.com/editing-help
jscott
1
Es un error en el código de formato. Debe colocar texto sin formato entre diferentes formatos, en este caso un bloque de código y un bloque numerado. Es por eso que puse "código debajo" en - no tiene sentido, en todos los lugares, pero funciona.
Tim
@Tim Gracias por aclarar. No sabía eso. También resolvió el formato de la expresión cron. Gracias de nuevo.
netfed