Detener e Iniciar instancias EC2 usando Cloud Custodian

Hello World 🙂

Siguiendo con nuestra serie sobre la optimización de costos y el manejo eficiente de las instancias EC2 en la nube, hoy exploraremos como detener e iniciar instancias en un horario predeterminado, esta vez utilizando Cloud Custodian.

Cloud Custodian es una herramienta de código abierto diseñada para administrar recursos en la nube de manera automatizada y basada en políticas. Según su sitio web, Cloud Custodian ofrece una amplia gama de opciones para ayudar a las organizaciones a gestionar sus recursos en la nube de manera eficiente y segura

Cloud Custodian le permite administrar sus recursos en la nube filtrándolos, etiquetándolos y luego aplicándoles acciones. YAML DSL permite la definición de reglas para habilitar una infraestructura de nube bien administrada que sea segura y optimizada en costos.

cloudcustodian.io

En el escenario de hoy, vamos a trabajar con dos grupos de instancias EC2, cada uno asignado a un horario específico para encender y apagar las instancias. Esta configuración refleja un caso más realista y práctico.

En primer lugar, crearemos una política para asignar un tag a cada instancia, según el grupo que correspondan app=Blue o app=Green, y también vamos a agregar un tag para todas las instancias optimization=true . Luego, configuraremos otra política para definir los horarios de encendido y apagado, y haremos uso de los tags definidos. Esta última política generará automáticamente nuestra Lambda Functions con el código necesario para realizar la tarea, lo cual es una ventaja significativa de utilizar Cloud Custodian para esta tarea. Con Cloud Custodian, nos olvidamos completamente de la creación de la función Lambda, ya que la política se encarga de eso. Es importante destacar que Cloud Custodian, en su núcleo, utiliza Python para llevar a cabo estas acciones.

Para la creación de la función Lambda, necesitaremos un rol de IAM que nos otorgue los permisos necesarios para trabajar. Este rol será creado utilizando Terraform. Además, utilizaremos Terraform para crear nuestras dos instancias EC2, así como la VPC donde estarán ubicadas dichas instancias. Todo el código necesario para generar estos recursos estará disponible en el repositorio de GitHub. En esta ocasión, nos enfocaremos exclusivamente en Cloud Custodian.

Requisitos;

  • Una cuenta en AWS.

El proyecto tiene la siguiente estructura;

1- Antes de comenzar a trabajar en nuestra máquina, vamos a generar un entorno virtual de Python3 donde instalaremos Cloud Custodian. Esto nos permitirá trabajar de manera más controlada, aprovechando todas las ventajas que ofrecen los entornos virtuales.

  • apt update && apt install python3.8-venv -y
  • python3 -m venv custodian
  • source custodian/bin/activate
  • pip install c7n

2- Lo primero que debemos hacer es agregar correctamente los tags a las instancias. Para lograrlo, utilizaremos la siguiente política.

Nota: Es importante tener en cuenta que debemos actualizar el archivo ip.txt con las IP privadas de todas nuestras instancias que queremos que formen parte de este proceso, también agregar las direcciones IP que deseamos asignar a cada grupo, estos pasos son excluyente para poder continuar.

  • ip.txt
    • 10.XX.XX.XX
      10.XX.XX.XX
  •  1-add-tag-ec2-instances.yaml
    • policies:
      #Policy add tag for all the instances
        - name: Add-tag-for-all-instances
          description: |
            Add tag to all instances
          resource: ec2
          filters:
            - type: value
              key: "PrivateIpAddress"
              op: in
              value_from:
                url: file:./policies/ip/ip.txt #Actualizar
                format: txt
          actions:
            - type: tag
              key: 'optimization'
              value: 'True'
      #Policy to Add tag for Blue instances group
        - name: Add-tag-for-Blue-group
          description: |
            Add tag to Blue instances group
          resource: ec2
          filters:
            - type: value
              key: "PrivateIpAddress"
              op: in
              value: ["10.XX.XX.XX"] #Actualizar
          actions:
            - type: tag
              key: 'app'
              value: 'Blue'
      #Policy to Add tag for Green instances group
        - name: Add-tag-for-Green-group
          description: |
            Add tag to Green instances group
          resource: ec2
          filters:
            - type: value
              key: "PrivateIpAddress"
              op: in
              value: ["10.XX.XX.XX"] #Actualizar
          actions:
            - type: tag
              key: 'app'
              value: 'Green'

3- Una vez que hayamos definido las políticas para agregar los tags necesarios, pasaremos a definir las políticas para detener e iniciar las instancias. Es importante tener en cuenta que el horario utilizado por estas políticas se encuentra en UTC y que debemos tener el ARN del rol que va a utilizar las Lambda Functions. Cada grupo puede tener un horario diferente para el apagado y encendido de las instancias.

Para comprender mejor el funcionamiento de estas políticas, tomemos como ejemplo la política destinada al grupo Blue. Esta política generará una función Lambda que detendrá todas las instancias que tengan los tags «optimization=true» y «app=Blue«. Del mismo modo, se realizará un proceso similar para iniciar las instancias

  • 2-stop-ec2-instances.yaml
    • policies:
      #Stop EC2 instances with the tag "app:Blue"
        - name: stop-ec2-instances-daily-Blue
          description: |
            Lambda to stop ec2 instances with the tag "app:Blue"
          mode:
            type: periodic
            schedule: "cron(00 18 ? * 2-6 *)"  # UTC Time
            role: arn:aws:iam::012345678901:role/cloud-custodian-role
            tags:
              Creator: "@israel870730"
          resource: ec2
          filters:
            - and:
              - "tag:optimization": present
              - type: value
                key: "tag:app"
                value: "Blue"
              - "State.Name": running
          actions:
            - type: stop
      #Stop EC2 instances with the tag "app:Green"
        - name: stop-ec2-instances-daily-Green
          description: |
            Lambda to stop ec2 instances with the tag "app:Green"
          mode:
            type: periodic
            schedule: "cron(00 19 ? * 2-6 *)" # UTC Time
            role: arn:aws:iam::012345678901:role/cloud-custodian-role
            tags:
              Creator: "@israel870730"
          resource: ec2
          filters:
            - and:
              - "tag:optimization": present
              - type: value
                key: "tag:app"
                value: "Green"
              - "State.Name": running
          actions:
            - type: stop
  • 3-start-ec2-instances.yaml
    • policies:
      #Start EC2 instances with the tag "app:Blue"
        - name: start-ec2-instances-daily-Blue
          description: |
            Lambda to Start ec2 instances with the tag "app:Blue"
          mode:
            type: periodic
            schedule: "cron(00 07? * 2-6 *)" # UTC Time
            role: arn:aws:iam::012345678901:role/cloud-custodian-role
            tags:
              Creator: "@israel870730"
          resource: ec2
          filters:
            - and:
              - "tag:optimization": present
              - type: value
                key: "tag:app"
                value: "Blue"
              - "State.Name": stopped
          actions:
            - type: start
      #Start EC2 instances with the tag "app:Green"
        - name: start-ec2-instances-daily-Green
          description: |
            Lambda to Start ec2 instances with the tag "app:Green"
          mode:
            type: periodic
            schedule: "cron(00 10 ? * 2-6 *)" # UTC Time
            role: arn:aws:iam::012345678901:role/cloud-custodian-role
            tags:
              Creator: "@israel870730"
          resource: ec2
          filters:
            - and:
              - "tag:optimization": present
              - type: value
                key: "tag:app"
                value: "Green"          
              - "State.Name": stopped
          actions:
            - type: start

4- Ya tenemos todo lo necesario para ejecutar nuestras políticas, pero antes de proceder con la ejecución, es crucial validar que todo esté correctamente configurado y listo para su ejecución.

    • custodian  validate  policies/1-add-tag-ec2-instances.yaml
    • custodian  validate  policies/2-stop-ec2-instances.yaml
    • custodian  validate  policies/3-start-ec2-instances.yaml
  • Antes de ejecutar la política para agregar los tags, es una buena práctica utilizar la opción --dry-run para simular la ejecución y asegurarnos de que todo está configurado correctamente. Una vez que hayamos verificado que todo está en orden, podemos proceder a ejecutar la política sin problemas.
    • custodian run –dryrun -s output policies/1-add-tag-ec2-instances.yaml –cache-period 0 –region=us-west-1
    • custodian run -s output policies/1-add-tag-ec2-instances.yaml –cache-period 0 –region=us-west-1
    • Ahora podemos filtrar las instancias desde la consola de AWS usando los tag;
  • Ahora ya estamos en condiciones de ejecutar nuestras políticas;
    • custodian run –dryrun -s output policies/2-stop-ec2-instances.yaml –region=us-west-1 –cache-period 0
    • custodian run -s output policies/2-stop-ec2-instances.yaml –region=us-west-1 –cache-period 0
    • custodian run –dryrun -s output policies/3-start-ec2-instances.yaml –region=us-west-1 –cache-period 0
    • custodian run -s output policies/3-start-ec2-instances.yaml –region=us-west-1 –cache-period 0
  • Lambda Functions creadas
  • Instancias detenidas después de la ejecución de la función Lambda.

5- Una vez que las funciones Lambda se ejecuten, podemos dirigirnos a la sección de monitoreo para revisar las métricas correspondientes. Además, es útil acceder a CloudWatch y explorar los grupos de registros (Log Groups) que se han creado para obtener detalles adicionales sobre el rendimiento y la ejecución de nuestras funciones.

Conclusiones

Bueno, llegamos al final de esta entrada en la cual exploramos cómo utilizar Cloud Custodian para gestionar el encendido y apagado de instancias EC2 de manera sencilla. Gracias a las políticas definidas en archivos YAML, pudimos crear y gestionar Lambda Functions fácilmente. A través de un ejemplo práctico, pudimos comprender cómo trabajar con múltiples grupos y horarios, lo que nos brinda flexibilidad en la gestión de recursos.

En mi breve experiencia con Cloud Custodian puedo decir que es una herramienta sumamente útil para la administración de los recursos en AWS. Este ejemplo fue solo el inicio; con el uso adecuado de políticas, podemos ejecutar una amplia gama de operaciones, lo que nos permite optimizar aún más nuestros entornos en la nube. Siempre es bueno explorar las posibilidades que nos brindan estas herramientas y cómo pueden simplificar nuestras tareas diarias en la nube

Espero que esta entrada haya sido útil y que lo hayan disfrutado tanto como yo, si tienen alguna pregunta o comentario, no duden en compartirlo.

¡Nos vemos en la próxima entrada!

Nota: Todo el código utilizado lo pueden encontrar en Github.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.