Tck::Lambdas

Tck::Lambdas es una gema que facilita la utilización de una AWS Lambda en el contexto de un proyecto Ruby introduciendo en el mismo tareas de Rake que realizan las órdenes AWS que debemos ejecutar habitualmente desde la línea de comandos.

Por ejemplo, si tenemos una función lambda llamada shine y queremos subir una mejora en su código tendríamos que, por un lado generar el zip con dicha mejora, y por otro actualizar el mismo en AWS Lambda (con la función aws lambda update-function-code o a través de su consola web).

Si hemos instalado la gema Tck::Lambdas en nuestro proyecto y hemos indicado que utilizamos la lambda shine (bundle exec tck-lambdas use shine), lanzaríamos la siguiente orden para crear el zip:

$ rake lambdas:shine:create_zip

Y esta para subir dicho zip a AWS Lambda (para "desplegar" la mejora):

$ rake lambdas:shine:upload_zip

Si sólo tenemos esa lambda en el proyecto, creando el alias necesario en nuestro Rakefile (task deploy_lambda: "lambdas:shine:upload_zip") podríamos lanzar simplemente:

$ rake deploy_lambda

Comandos de tck-lambdas

Si lanzamos su ayuda nos cuenta lo siguiente:

$ tck-lambdas help
Commands:
  tck-lambdas all             # List all AWS Lambdas currently available in tck-lambdas.
  tck-lambdas help [COMMAND]  # Describe available commands or one specific command
  tck-lambdas roles           # List current AWS IAM roles (running 'aws iam list-roles [...]').
  tck-lambdas use NAME        # Use the AWS Lambda function known as NAME at The Cocktail.
  tck-lambdas used            # List functions currently used by this project.

GOTCHA: Tenemos también el indocumentado comando tck-lambdas list, que es un alias de tck-lambdas used, NO de tck-lambdas all :)

Caso de Uso: lambda contact_form

Vamos a meter un formulario de contacto en nuestro proyecto Amazing y queremos usar la lambda contact_form. Instalamos la gema Tck::Lambdas y le indicamos que nuestro proyecto hace uso de la lambda llamada contact_form:

$ echo "gem 'tck-lambdas'" >> Gemfile      # Metemos la gema en nuestro Gemfile...
$ bundle                                   #  - la instalamos...
$ cp Rakefile Rakefile.orig                #  - nos guardamos nuestro Rakefile...
$ tck-lambdas use contact_form             #  - y usamos la lambda:
/usr/lib/ruby/gems/[...]/lib/tck/lambdas/contact_form
      create  Rakefile
      create  Gemfile.example
      create  .lambdas.yml
      create  lib/tasks/lambdas.rake
      create  lib/tck/lambdas/aws_function.rb
      create  lambdas/test.rb
      create  lambdas/contact_form
      create  lambdas/contact_form/source/conf.js
      create  lambdas/contact_form/source/contact_form.js
      create  lambdas/contact_form/source/utils.js
      create  lambdas/contact_form/test/failed/domain_empty.json
      create  lambdas/contact_form/test/failed/domain_not_found.json
      create  lambdas/contact_form/test/failed/email_empty.json
      create  lambdas/contact_form/test/failed/email_format.json
      create  lambdas/contact_form/test/failed/message_empty.json
      create  lambdas/contact_form/test/succeeded/basic.json
      create  lambdas/contact_form/test/succeeded/with_cc.json
$

Tal y como nos avisa ha creado, entre otras cosas, el fichero .lambdas.yml con la configuración para nuestra función lambda con el siguiente contenido:

contact_form:
  function-name: project_name_contact_form
  handler: project_name_contact_form.handler
  timeout: 30
  memory-size: 128
  runtime: nodejs4.3
  role: lambda_contact_form_role
  description: Project-Name instance of the Tck's contact_form lambda

Todos los valores por defecto deberían ser válidos excepto el nombre de la función (function-name), su manejador (handler), y su rol (role).

En el nombre de la función y su manejador tenemos que sustituir project_name por el nombre de nuestro proyecto (quedándonos con amazing_contact_form y amazing_contact_form.handler respectivamente).

El rol tenemos que sustituirlo por el ARN completo de un rol que tenga permisos para ejecutar los servicios que necesite nuestra lambda. El comando tck-lambdas roles nos devuelve los ARN de los distintos roles que tenemos a nuestra disposición en AWS Lambda.

Con dichos cambios en nuestro .lambdas.yml ejecutamos la siguiente tarea de rake:

$ rake lambdas:contact_form:create_lambda

Dicha orden nos creará, además de la función lambda necesaria para el entorno de producción, otra con el mismo nombre terminada en _test para la ejecución de sus tests (en nuestro ejemplo si lanzamos aws lambda list-functions deberíamos tener dos nuevas funciones llamadas amazing_contact_form y amazing_contact_form_test).

Por lo tanto, si todo ha ido bien deberíamos poder lanzar los tests de nuestra lambda con éxito:

$ rake lambdas:contact_form:test

Modificando una lambda

El código de la lambda lo tenemos dentro de lambdas/contact_form/source y para añadir una mejora al mismo debemos seguir los siguientes pasos de cara a desplegarla:

  1. Escribir la mejora
  2. Crear el zip: rake lambdas:contact_form:create_zip
  3. Subir el nuevo zip a la lambda de tests: rake lambdas:contact_form:upload_test
  4. Lanzar los tests: rake lambdas:contact_form:test (...volviendo al primer paso hasta que pasen)
  5. Actualizar la lambda de producción: rake lambdas:contact_form:upload_zip

Los pasos 2, 3 y 4 son implementados por la tarea :build_lambda, lo que nos permite reducir los pasos necesarios a 3:

  1. Escribir la mejora
  2. Lanzar el build: rake lambdas:contact_form:build_lambda (...hasta que pasen los tests)
  3. Actualizar la lambda de producción: rake lambdas:contact_form:upload_zip

Installation

Add this line to your application's Gemfile:

gem 'tck-lambdas'

And then execute:

$ bundle

Or install it yourself as:

$ gem install tck-lambdas

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/the-cocktail/tck-lambdas. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.