SSH con AWS Lambda
AWS Lambda es el servicio base de la oferta serverless de AWS, a grandes rasgos es un contenedor administrado y manejado por AWS del que no nos tenemos que preocupar mas que por su código. Últimamente se ha estado utilizando mucho para hacer automatizaciones de todo tipo gracias a su bajo costo y fácil implementación.
Un uso no muy común, pero muy útil para la lambda es ejecutar comandos mediante SSH, podemos mandar comandos hacia nuestras instancias EC2 y hacer algunas automatizaciones de procesos tediosos y repetitivos, por ejemplo, se puede obtener información de las maquinas y sus procesos, instalar el agente de Cloudwatch o SSM, etc, etc. La imaginación aquí es el limite.
En este articulo tratare de explicar que se requiere para hacer una implementación de Lambda con Python 2.7 para hacer SSH a nuestras instancias usando la librería de Paramiko. Paramiko es una librería para la implementación de SSHv2.
Empezaremos por crear una Lambda Layer que contenga la librería de Paramiko.
Para crearla necesitaremos un entorno de Linux obligatoriamente, en mi caso yo usare una instancia de Amazon Linux 2, usamos Amazon Linux 2 debido a que ya trae el agente de SSM instalado y podemos ejecutar los comandos que necesitamos conectándonos a travez de Session Manager.
Entonces creamos una instancia de cualquier tamaño, sugiero usar una micro.t2 para evitar costos y le damos un rol que nos permita conectarnos vía Session Manager.
Una vez dentro ejecutamos la siguiente
#Nos movemos hacia nuestro directorio de usuario
cd#Instalamos "python-devel" "openssl-devel" y "libffi-devel"
sudo yum install python-devel openssl-devel libffi-devel#instalamos pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
sudo python get-pip.py#Instalamos virtualenv
sudo pip install virtualenv#Creamos una carpeta nueva llamada prueba y nos movemos hacia ella
mkdir prueba
cd prueba#Creamos un entorno llamado python
virtualenv python#Nos movemos hacia el entorno
cd python#Activamos el nuevo entorno
source bin/activate#Inicializamos pip
pip install #Nos movemos hacia la carpeta de lib/python2.7/site-packages/
cd lib/python2.7/site-packages/#Procedemos a instalar paramiko y demás dependencias
#IMPORTANTE No usar sudo aquí y poner el comando completo
pip install paramiko -t .
Una vez hecho esto verificamos que tengamos los paquetes de paramiko, cryptography y .libs_cffi_backend
Si no tenemos estos archivos significa que algo salió mal en la instalación y que nos va a dar errores si lo subimos como layer, si los tenemos es que todo va de acuerdo con el plan.
Una vez hecho esto nos movemos hacia nuestro directorio de prueba y procedemos a zipear el directorio de python
cd
cd prueba
zip -r9 ./paramikolayer.zip .
Una vez obtenido nuestro archivo zip lo subimos a s3
aws s3 cp paramikolayer.zip s3://tubucket/paramikolayer.zip
Y nos dirigimos hacia nuestra consola AWS , despues a Lambda -> Layers -> Crear nueva layer
Le ponemos el nombre que quedamos, seleccionamos compatibilidad con python 2.7 y muy importante subimos nuestra carpeta zip desde s3, si lo subimos como .zip puede dar problemas.
Una vez creada nos vamos hacia Lambda -> Functions
Seleccionamos crear nueva función
Le ponemos el nombre que queramos, seleccionamos Python 2.7 como runtime y le asignamos un rol que contenga todos los permisos para accesar a EC2.
Cuando este creada hacemos click en Layers.
Damos click en Add a Layer
Seleccionamos nuestra layer y version y damos click en Add.
Importante una vez agregada la layer hacemos click en Guardar.
Ahora agregamos import paramiko a nuestro código.
Ejecutamos y Listo!.
Si no nos arroja ningún error es que la instalación de paramiko en la layer fue exitosa.
Ahora podemos proceder a crear un cliente con paramiko y tirar comandos a alguna instancia, podemos ocupar el siguiente codigo para obtener información sobre que sistema operativo usa una instancia.
import paramiko
import json
import boto3def lambda_handler(event, context):s3_client = boto3.client('s3')
#Descargamos nuestra llave pem de un bucket s3
s3_client.download_file('nombredelbucket','tullave.pem', '/tmp/keyname.pem')
pem_key = paramiko.RSAKey.from_private_key_file("/tmp/keyname.pem")
#Creamos un nuevo cliente
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Ponemos la direccion del server al que nos queremos conectar
host= "172.0.0.0"
print "Iniciando conexion hacia: " + host
#Iniciamos la conexion, en username debe de ir el nombre del usuario conn el que se quiere logear
#En este caso como estoy usando una AMI Amazon Linux el usuario es ec2-user
ssh_client.connect( hostname = host, username = "ec2-user", pkey = pem_key )#Comandos para mostrar el archivo de informacion sobre el SO
so_info_commands = ["cat /etc/os-release"]for command in so_info_commands:
print "Executing Command: {}".format(command)
stdin , stdout, stderr = ssh_client.exec_command(command)
response = stdout.readlines()
for idx, item in enumerate(response):
print("Output "+str(idx+1)+": "+item)
return
{
'message' : "Script execution completed. See Cloudwatch logs for complete output"
}
Y obtenemos lo siguiente.
Y bien así termina este artículo, con esto ahora se pueden generar futuras automatizaciones de todo tipo.
¡Dale clap si te gusto! :).
Follow me:
LinkedIn https://www.linkedin.com/in/bertin-cano/