Parcheado del sistema operativo con una función Lambda

Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Share on telegram
Share on email

En el artículo Parcheado automático de instancias EC2 con CloudWatch y Lambda explicaba cómo parchear una instancia EC2 Linux Centos con CloudWatch y Lamba. Utilizaba CloudWatch para crear un flujo de trabajo en orden que paraba la instancia, creaba un snapshot del disco de sistema operativo, arrancaba la instancia llamando a una función Lambda y ejecutaba el comando yum update  llamando a la API de Sistems Manager.

Es decir, creaba un flujo de trabajo llamando a todas esas funciones por separado.

Lo que voy a hacer ahora es una única función Lambda que parchea el sistema operativo pasándole como parámetro únicamente el Hostname, que es un tag que he añadido a las instancias EC2, a los volúmenes y a los snapshots.

De esta manera, puedo relacionar a qué servidor está asignado cada volumen por su hostname en ambas «tablas».

Lenovo IdeaPad 5 - Ordenador Portátil 15.6" FullHD (AMD Ryzen 5 5500U, 16GB RAM, 512GB...
  • Pantalla de 15.6" FullHD (1920x1080) 300nits
  • Procesador AMD Ryzen 5 5500U (6C/12T, 2.1 GHz/4.04GHz, 8 MB)
  • Memoria RAM de 16GB

Mejor os dejo el código fuente de la función Lambda que hace todo lo que he explicado anteriormente:

Rebajas
Samsung LF27T352FHRXEN - Monitor Plano de 27", Full HD (1080p, Panel IPS), Freesync, HDMI,...
  • Monitor 27 pulgadas con panel IPS y ángulo de visión de 178º para una calidad de visionado superior e imágenes cristalinas
  • Pantalla sin marcos en tres bordes, que facilita el montaje de varios monitores
  • AMD Freesync y Game mode, experiencia gaming inmersiva

El único parámetro que le tenemos que pasar a la función es su hostname.

import json

import boto3


import time

def GetInstanceID(Hostname):
ec2 = boto3.client(‘ec2′, region_name=’eu-west-1’)
filters = [
{‘Name’: ‘tag:Hostname’,
‘Values’: [Hostname]}
]
instance_ids = []
reservations = ec2.describe_instances(Filters=filters)[‘Reservations’]

for reservation in reservations:
instances = reservation[‘Instances’]
for instance in instances:
instance_ids.append(instance[‘InstanceId’])

return instance_ids

def GetRootVolID(Hostname):
volid = »
Hostnametag = »
Filesystem = »
ec2 = boto3.resource(‘ec2′, region_name=’eu-west-1’)

for vol in ec2.volumes.all():
for tag in vol.tags:
if tag[‘Key’] == ‘Hostname’:
Hostnametag = tag[‘Value’]
if tag[‘Key’] == ‘Filesystem’:
Filesystem = tag[‘Value’]
if Filesystem == ‘root’ and Hostnametag == Hostname:
volid = vol.id
return volid

def GetInstanceState(InstanceID):
ec2 = boto3.resource(‘ec2’)
instance = ec2.Instance(InstanceID)
return instance.state[‘Name’]

def lambda_handler(event, context):
ec2 = boto3.client(‘ec2′, region_name=’eu-west-1’)
Hostname=event[‘Hostname’]
RootVolID = GetRootVolID(Hostname)
InstanceID=GetInstanceID(Hostname)
#InstanceState = GetInstanceState(InstanceID[0])
#print «Estado de la instancia: » + str(InstanceState)

#Stop EC2 instance
print «Parando instancia: » + str(InstanceID)
ec2.stop_instances(InstanceIds=InstanceID)
while GetInstanceState(InstanceID[0]) != «stopped»:
time.sleep(10)

# Create Snapshot
print «Creando snapshot del disco: » + RootVolID
snapshotDescription = Hostname + » – Snapshot – » + RootVolID
#ec2.create_snapshot( VolumeId=RootVolID, Description=snapshotDescription,)
ec2.create_snapshot(
VolumeId=RootVolID,
TagSpecifications=[
{
‘ResourceType’: ‘snapshot’,
‘Tags’: [
{
‘Key’ : ‘Hostname’,
‘Value’: Hostname
}
],
}
],
Description=snapshotDescription)

time.sleep(10)

#Start EC2 instance
print «Arrancando instancia: » + str(InstanceID)
ec2.start_instances(InstanceIds=InstanceID)
while GetInstanceState(InstanceID[0]) != «running»:
time.sleep(10)

print «Actualizando el servidor: » + Hostname
# Dejamos 20 segundo a que termine de arrancar el servidor
time.sleep(20)
# Update Linux
ssm = boto3.client(‘ssm’)
command = ‘yum update -y; reboot’
ssm.send_command(
InstanceIds=InstanceID,
DocumentName=’AWS-RunShellScript’,
Parameters={
‘commands’: [command]
}
)

A la función Lambda le he de ampliar el tiempo de duración para que no se corte toda la secuencia.

Una vez ejecutada la función, vemos que ha tardado dos minutos:

¿Te ha gustado? Compártelo

Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Share on telegram
Share on email
About Author

Contenido Relacionado

Artículos Recientes

Deja un comentario