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».

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

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

SUSCRÍBETE A PUERTO53

Recibe un email periódico con los artículos más interesantes de Puerto53.com

Antes de suscribirte lee los términos y condiciones. Gracias.

Contenido Relacionado

Artículos Recientes

Deja un comentario

About Author