Рубрики
Без рубрики

Respaldando tus funciones rambda

Uno de los desafíos Que encontré no resuelto es cómo respaldar las funciones, capas y configuraciones … Tagged с AWS, Lambda, Python.

Uno de los desafíos que encontré no resuelto es cómo respaldar las funciones, capas y configuraciones de las funciones lambda que iba desarrollando. Меня Пьюс и Стьюацион Десплгар Ла -Мисма Фунцион и Отро -Амбиенте, О ТАЛ ВЕЗ МИГРАРИЯ АКЛЕДЕРИНДОРЫ О КАМБИАРЕ ДЕРЕДОРЕ де -Клауд. O Smailymente Prepararme para una pérdida total de dato.

Como Podría obtener una copia de mis funciones de forma sencilla?

Investigando la sdk de aws para python descubrí boto3 que se encarga de ejecutar los comandos de api de cada uno de los servicios. Uno de estos comando puede traer una dista de las funciones y una dista de las capas creadas bajo la cuenta que que realiza la petición.

Repositorio

La función es bien sencilla además se puede infular como función lambda, si no quieres leer la explicación puedes clonar remematamente el Repositorio.

TL; DR:

Ensamblador/Backup_lambda

Respaldo de Funciones rambda aws

Инструкции

  1. Deconir (El Bucket Debe Estar Creado)
  2. Defineir (u Otra subcarpeta)
  3. Llamar a Backup_capas (папка) o Backup_funciones (папка)

La Guia de Uso Está Acá

Pasos Previos

Antes que todo, para poder inprevator y ejecutar se requiere tener conocimiento en las funciones lambda y en el sistema de permisologías de aws llamado iam (управление идентичностью и доступом) que upermitrá a la función ejecutar la llamada a lambda y la escritura en el bucket s3.

ROL IAM

El Rol Debe Contar Con Permisos de Lectura y Escritura en S3, Agregar Estos Permisisos Si es Que no Están.

S3BucketReadWriteBucket

Relación de Consianza con Lambda

En el rol iam, aseguremos que la política permite a lambda asumir el rol, эстфир.

{ 
 "Version": "2012-10-17",
     "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
         "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
   ]
}

Функциональный директор (Python)

Las Librerías Watingses Son Boto3 (Para Interactuar con al api de aws) y Запросы Para Realizar la descarga del código .zip Entregado Por Aws. Nota que si la función se está desplegando en aws lambda Запросы на импорт requiere una capa adicional de función. Эсто Ло Откровенный финал, Аси Паксисия.

import boto3
import json
import shutil
import os
from requests import session


lam = boto3.client('lambda')
s3 = boto3.resource('s3')
s3bucket = "TU_BUCKET_PERSONAL"

S3Bucket Представление El Bucket Donde Se Almacenarán Los Respaldos, Debes Crearlo PreviaMente y Actualizar la переменная.

boto3.client ('лямбда') y boto3.resource ('s3') Сын Los Clientes Para Realizar Lmamadas A Lambda y S3 Costraivamente, Todo A Través de Boto3 (El Sdk de Aws Para Python)

DocumentAcion boto3: Лямбда

DocumentAcion Boto3: S3

Obtener el Listado de Funciones

def backup_funciones(base_path):

    response = lam.list_functions()
    funciones = response['Functions'] #Todas las funciones

    print("Encontramos {} funciones".format(len (funciones)))

El Distado de Funciones se octiene llamando a list_functions () Y Guardamos el Listado, Indicando en el log la cantidad de funciones.

Python3 Lambda2s3.py Encontramos 35 Funciones

ХОРОШО.

¿Y el código?

Para Cada función iteramos el Detalle, que nos permite obtener lo Realtmente

    for fn in funciones:
        layers = 0
        if hasattr(fn, 'Layers'):
            layers = len(fn['Layers'])
        print("Procesando [{}] : {}\nRuntime: {}\n Descripcion:{}\n Tamaño: {}\n Capas:{}\n".format(
            fn['FunctionArn'],
            fn['FunctionName'],
            fn['Runtime'],
            fn['Description'], 
            fn['CodeSize'], 
            layers))
        full_fn = lam.get_function(
            FunctionName=fn['FunctionName']
        ) #el detalle de la funcion incluyendo el código fuente
        if hasattr(full_fn['Configuration'], 'Tags'):
            full_fn['Configuration']['Tags'] = full_fn['Tags']
        config_json = json.dumps(full_fn['Configuration']) # un json con con la configuración de la función.

full_fn. get_function (FunctionName = fn [‘functionName’]) oTiene El Detalle The La La Función. Una Vez Recibida la Respueta, full_fn ['code'] ['location'] Contiene la url prefirmada (y de que expira a los 15 minutos).

Респольдандо

        config_filename = fn['FunctionName']+".json"
        code_filename = fn['FunctionName']+".zip"
        with open(base_path+config_filename, "w") as config:
            config.write(config_json) # Si es lambda se guardará en /tmp/ si no en /archivos/ (debe existir la subcarpeta)


        #acá la magia para obtener la descarga desde la URL pre-firmada
        #usamos la librería requests que realiza la http request con sesiones...
        with session() as d:
            peticion = d.get(full_fn['Code']['Location'], stream=True)
            out_file = open(base_path+code_filename, 'wb')
            out_file.write(peticion.content)
            out_file.close()

        print("Codigo Fuente:", code_filename)

Depanamos el Nombre del Archivo configuración (время выполнения, Capas, Timeout, ARN и т. Д.) Nombredelafuncion.json y el código lo almacenamos поступка Nombredelafuncion.zip Анкет Ambos almacenados en la carpeta base_path

En el ambiente del intreendor lambda, el único lugar con permisos de escritura es la carpeta /tmp/ Анкет Entness, Ese Caso de estar desplegando en lambda, nuestro debe ser base_path = '/tmp'/ Анкет

Como Mencionamos, full_fn ['code'] ['location'] Almacena la url prefirmada. ESTA URL NO ES DESCARGABLE CON UN GET CLásico. La url prefirmada es redireccionada una una verificación antes de entregar el contenido.

Visualicemos la url código del primer rumer resultado:

full_fn.get_function (functionName = fn [‘functionName’]) print (full_fn [‘code’] [‘location’]) возвращаться

Результат:

Este Archivo se puede descargar en un navegador o utilizando curl.

Респольдандо Эль Кодиго

ESTO Entoncers Lo Realizamos Con Session () DE запросов, Quien Setrese una sesión para todos los siguientes peticiones (Get o post), El Contenido se almacena en Эль -Архиво де Кодиго.

        with session() as d:
            peticion = d.get(full_fn['Code']['Location'], stream=True)
            out_file = open(base_path+code_filename, 'wb')
            out_file.write(peticion.content)
            out_file.close()

Y este archivo también se respalda en la carpeta base_path

Llevando los archivos a s3

En términos prácticos, si estamos respaldando de forma, местный парар -парар, парар, а, cerrar el día. Cada Vez que Queramos respaldar ejecutamos Python3 Lambda2s3.py y en unos segundos tendríamos todas nuestras funciones en una carpetita de nuestro computador. Y si Queremos Guardarlo en S3:

        #Utilizamos el Bucket de destino para guardar el código y el archivo de configuración. 
        #Elegí guardarlo en subcarpetas separados por runtime, pero es a elección de cada uno :)
        s3.Bucket(s3bucket).upload_file(base_path+config_filename,
                                        fn['Runtime']+'/' + config_filename)
        with open(base_path+code_filename, 'rb') as data:
            #upload_fileobj permite la subida de archivos binarios (ojo de debe abrirse como 'rb': read and binary)
            s3.Bucket(s3bucket).upload_fileobj(
                data, fn['Runtime']+'/' + code_filename)

        print("\nArchivo de Configuracion:", config_filename)
        print("Subido a:", s3bucket+'/' +
              fn['Runtime']+'/' + config_filename, "\n")
        print("Archivo de Codigo Fuente:", code_filename)
        print("Subido a:", s3bucket+'/' +
              fn['Runtime']+'/' + code_filename, "\n")

Ambos Archivos Son Subidos utilizando upload_file y upload_fileobj Este último para Archivos Binarios (Para Eso El Archivo Debe Ser Leído Binario: RB)

CADA Función Almacernará en la subcarpeta asociada al Runtime (Java, Python, Node и т. Д.), Por Ejemplo Este Caso mis Funciones Quedan en las siguientes carpetas.

Opcional Respaldando Las Capas

Las Capas de Las Funciones Son Las Librerías Que Hace Uso y Que Нет Están en ambiente del tiempo de ejecución. POR EJEMPLO De Hecho esta misma función requiere hacer uso de Запросы que no está en lambda y se debe agregar como capa.

Las Capas de Las Funcions No SE Editan Normalmente y Son Reonestubluybles. Sin embargo si se requiere ressaldar las capas, dentro del mismo Repositorio está creada la función Backup_capas Анкет

Esta función utiliza la misma estructura Que Backup_funciones Pero Realiza la llamada a List_layers y get_layer_version_by_arn

HoTiene La Lista de Capas:

    response = lam.list_layers()
    layers = response['Layers']

oTiene el El Detalle de Cada Capa:

   for layer in response['Layers']:
        print("\nProcesando [", layer['LayerName'], ":", layer['LayerArn'], "]\n", 100*"*", "\n")
        print("Version:", layer['LatestMatchingVersion']['Version'])
        print("Runtimes:", repr(layer['LatestMatchingVersion']['CompatibleRuntimes']))
        full_layer = lam.get_layer_version_by_arn(
            Arn=layer['LatestMatchingVersion']['LayerVersionArn']
        )

El url para descargar el paquete de la capa viene en full_layer ['content'] ['location'] y se descarga de la misma forma.

Como Sabemos en ambiente lambda la única carpeta con permisisos decritura es/tmp/enscies es base_path Анкет Ahora Bien, para no preocuparse nunca más con ese tema podemos aplicar un pequeño truco.

Lidiando con/tmp/

Идеально Es que la carpeta sea ‘/tmp/’ sólo si estamos en lambda, en caso contrario podría ser subcarpeta ‘./archivos/’ (U OTRA A Elección).

Si Estamos en Lambda, Hay Ciertas переменные de enterorno Que están defindas, por ejemplo:

print (os.environ.get (‘aws_excution_env’)) Aws_lambda_python3.6

Podemos usar esto para detectar si estamos ejecutando la función en ambiente lambda, si es así la carpeta de trabajo debe ser ‘/tmp/’ y luego llamamos a Backup_funciones Анкет

def lambda_handler(event, context):
    #una técnica para detectar el ambiente de ejecución: si está seteado AWS_EXECUTION_ENV siginfica que estoy en lambda.
    if os.environ.get('AWS_EXECUTION_ENV') is not None:
        isLambda = 1
    else:
        isLambda = 0

    base_path = './archivos/'
    #si estoy en lambda cambio el base_path al /tmp/ (el único lugar con permisos de escritura del contenedor)
    #el límite de /tmp/ son 500 MB ojo!
    if isLambda == 1:
        print("Runtime API:", os.environ['AWS_EXECUTION_ENV'])
        base_path = '/tmp/'

    backup_funciones(base_path)

CREAR LA FUNCION

Podemos Crear La Funcion er La Consola O A Través de la Consola (Sitio Web)

AWS Consola

AWS CLI

rm function.zip zip function.zip *.py AWS Lambda Create-Function-Function-Name Respalda-Funciones \ -zip-file fileb://function.zip-handler lambda2s3.lambda_handler-runtime python3.6 \ –роль TU_ROL_DE_EJECUCION \ -Описание “respalda todas las funciones en un bucket s3” \ -Попубликация-Timeout 900 \ -Layers “ARN: AWS: Lambda: US-WEST-2: 823794707078: слой: Python36-Requests-BS4-LXML: 2”

Nota: la Funcion requiere para ejecutarse el módulo Запросы Que Originalmente no Está prevente en el ambiente python de lambda. Este Módulo (Entre Otros) lo provee la capa ARN: AWS: LAMBDA: US-WEST-2: 823794707078: СЛОЙ: Python36-Requests-BS4-LXML: 2 Анкет Esta Capa Tiene Permisos para ser utilizada en cualquier función.

Si Estás Interesado en Cómo Generar Tus Propias Capas Pre-Compiladas Para El Ambiente Python de Lambda, Te Recomiendo esta guía (en Inglés) que utilicé para crear la capa.

Создание нового слоя AWS Lambda для библиотеки Python Pandas | от Quy Tang | Середина

Quy Tang ・ 9 декабря 2018 г. ・ 5 минут читайте среду

Opcional Programación Automática

Una de las gracias de ontar con la función en ambiente lambda es que puedes программа Su ejecución cada cierto tiempo.

Lo primero es generar un trigger basado en cloudwatch события

Y seleccionamos Nueva Programación utilizando una Экспресс Крона (Sí, Cron)

De esta forma queda configurada la ejecución todos los días domingo (UTC)

Вывод

Finalmente Realizar El Respaldo Es Bien Sencillo y нет Тома Мучо Типо, рекурсус. Сияние la función se quisiera mejorar podría pensar en:

  • Ejecutar la descarga del archivo .zip Y Subida A S3 EN UN SOLO MOVIMINTO, ASí NO NOS PROOCUPAMOS DEL Límite DE 500 MB DE ESPACIO EN/TMP/
  • Utilizar El Curl Del Ambiente En Vez de запросы, Aunque Si Hacemo Eso Perdemos El Control de la función dejando esta parte en manos del etnorno.
  • La Traducción al Inglés se viene pronto 😎

Оригинал: “https://dev.to/ensamblador/respaldando-tus-funciones-lambda-3ema”