Lamvery
=======

|Build Status| |Coverage| |Version| |Downloads|

Function based deploy and management tool for AWS Lambda.

Requirements
============

-  Python2.7
-  pip

Recommends
==========

-  **virtualenv**
    **Automatically collect the lightweighted and compiled libraries in
   the virtualenv environment.**

Installation
============

.. code:: sh

    pip install lamvery

Setup
=====

At first,

.. code:: sh

    lamvery init

| And edit your ``.lamvery.yml`` like this.
| The configuration is written in YAML syntax with ``jinja2`` template.
| And environment variables stored ``env`` variable.

.. code:: yml

    profile: default
    region: us-east-1
    configuration:
      name: lamvery-test
      runtime: python2.7
      role: {{ env['AWS_LAMBDA_ROLE'] }}
      handler: lambda_function.lambda_handler
      description: This is sample lambda function.
      timeout: 10
      memory_size: 128
    events:
      - rule: foo
        description: bar
        schedule: 'rate(5 minutes)'
        targets:
        - id: test-target-id
          input:
            this:
            - is: a
            - sample: input
    secret:
      key_id: {{ env['AWS_KMS_KEY_ID'] }}
      cipher_texts:
        foo: CiC4xW9lg7HaxaueeN+d9yJMyY1uw1i7tYVvQz9I8+e2UBKVAQEBAgB4uMVvZYOx2sWrnnjfnfciTMmNbsNYu7WFb0M/SPPntlAAAABsMGoGCSqGSIb3DQEHBqBdMFsCAQAwVgYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAwN5YM9tDwY/TItbG8CARCAKW1+6MfloCrykA+gT1roV1IoZPt3dsfoJQEJNWPQ83/Cj1b7Om22Pboz
    exclude:
    - ^\.lamvery\.yml$

Commands
========

archive
~~~~~~~

-  Archive your code and libraries to ``<your-function-name>.zip``
-  Store secret informations to the archive

.. code:: sh

    lamvery archive

deploy
~~~~~~

-  Archive and deploy your code and libraries
-  Store secret informations to the archive
-  Update configuration of the function
-  Set alias to a version of the function

.. code:: sh

    lamvery deploy

set-alias
~~~~~~~~~

-  Set alias to a version of the function

.. code:: sh

    lamvery set-alias -a <alias> -v <alias-version>

encrypt
~~~~~~~

-  Encrypt a text value using KMS

.. code:: sh

    lamvery encrypt -n <secret-name> <secret-value> [-s]

decrypt
~~~~~~~

-  Decrypt the secret value using KMS

.. code:: sh

    lamvery decrypt -n <secret-name>

events
~~~~~~

-  Apply CloudWatch Events settings

.. code:: sh

    lamvery events [-k]

invoke
~~~~~~

-  Invoke the function and output logs to stdout

.. code:: sh

    lamvery invoke [-a <alias>] [-v <version>] '{"foo": "bar"}'

or

.. code:: sh

    lamvery invoke [-a <alias>] [-v <version>] path/to/input.json

Options
-------

-  | ``-a`` or ``--alias``
   | This option needed by ``deploy`` and ``set-alias`` and ``invoke``
   commands.
   | Alias for a version of the function.

-  | ``-c`` or ``--conf-file``
   | This option needed by all commands.
   | Specify the configuration file.
   | default: ``.lamvery.yml``

-  | ``-d`` or ``--dry-run``
   | This option needed by ``deploy`` and ``alias`` commands.
   | Output the difference of configuration and the alias without
   updating.

-  | ``-l`` or ``--no-libs``
   | This option only needed by ``deploy`` command.
   | Archiving without all libraries.

-  | ``-n`` or ``--secret-name``
   | This option needed by ``encrypt`` and ``decrypt`` commands.
   | The name of the secret value.

-  | ``-p`` or ``--publish``
   | This option only needed by ``deploy`` command. Publish the version
   as an atomic operation.

-  | ``-k`` or ``--keep-empty-events``
   | This option only needed by ``events`` command. Keep the empty
   CloudWatch Event Rule that does not have CloudWatch Event Target.

-  | ``-s`` or ``--store``
   | This option only needed by ``encrypt`` command.
   | Store encripted value to configuration file (default:
   ``.lamvery.yml``).
   | This option is required ``-n`` or ``--secret-name`` option.

-  | ``-v`` or ``--version``
   | This option needed by ``set-alias`` and ``invoke`` commands.
   | Version of the function.

Configuration file (.lamvery.yml)
=================================

profile
~~~~~~~

The name of a profile to use. If not given, this depends on ``boto3``.

region
~~~~~~

| The region name of your environment.
| If you doesn't set this option, this depends on ``boto3``.

configuration
~~~~~~~~~~~~~

-  | name
   | The name of your function.

-  | runtime
   | The runtime environment for the Lambda function you are uploading.
   | Currently, ``lamvery`` supports ``python2.7`` and ``nodejs``.

-  | role
   | The Amazon Resource Name (ARN) of the IAM role for your function.

-  | handler
   | The function within your code that Lambda calls to begin execution.

-  description The description of your function.

-  | timeout
   | The function execution time(seconds) at which Lambda should
   terminate the function.

-  | memory\_size
   | The amount of memory for your function environment.

-  | alias
   | The default alias when not given ``-a`` or ``--alias`` argument.

secret
~~~~~~

-  | key\_id
   | The ID of your encryption key on KMS.

-  | cipher\_texts
   | The name and cipher texts for passing to lambda function.

events
~~~~~~

-  | rule
   | The name of CloudWatch Event Rule.

-  | description
   | The description of CloudWatch Event Rule.

-  | schedule
   | The schedule expression of CloudWatch Event Rule.

-  | disabled
   | When this setting is true, change the state of CloudWatch Event
   Rule to ``DISABLED``.
   | default: ``false``

-  targets
   The targets of CloudWatch Event Rule.
-  id
    The unique target assignment ID.
-  input
    Arguments passed to the target.
-  | input\_path
   |  The value of the JSONPath that is used for extracting part of the
   matched event when passing it to the target.
   |  *``input`` and ``input_path`` are mutually-exclusive and optional
   parameters of a target.*

exclude
~~~~~~~

Exclude files or directories using regular expression.

Using confidential information in lambda function
=================================================

1. Create key on KMS
^^^^^^^^^^^^^^^^^^^^

| See:
https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html
#### 2. Create IAM role for lambda function
| Policy example:

.. code:: json

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "kms:Decrypt"
                ],
                "Resource": [
                    "arn:aws:kms:us-east-1:<your-account-number>:key/<your-key-id>"
                ]
            }
        ]
    }

3. Set the key-id to your configuration file.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Configuration example:

.. code:: yml

      profile: default
      region: us-east-1
      configuration:
        name: sample_lambda_function
        runtime: python2.7
        role: arn:aws:iam::000000000000:role/lambda_basic_execution
        handler: lambda_function.lambda_handler
        description: This is sample lambda function.
        timeout: 10
        memory_size: 128
      secret:
        key_id: xxxx-yyyy-zzzz # <-here!
        cipher_texts: {}

4. Encrypt and store the confidential information to your configuration file.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Command example:

.. code:: sh

    lamvery encrypt -s -n foo "This is a secret"

5. Write your function.
^^^^^^^^^^^^^^^^^^^^^^^

Code example:

.. code:: py

      import lamvery

      def lambda_handler(event, context):
          print(lamvery.secret.get('foo'))

6. Deploy your function
^^^^^^^^^^^^^^^^^^^^^^^

Command example:

.. code:: sh

    lamvery deploy

7. Invoke your function
^^^^^^^^^^^^^^^^^^^^^^^

Command example:

.. code:: sh

    lamvery invoke {}

Result example:

::

    START RequestId: 13829c9c-9f13-11e5-921b-6f048cff3c2d Version: $LATEST
    This is a secret
    END RequestId: 13829c9c-9f13-11e5-921b-6f048cff3c2d

Development
-----------

-  Source hosted at `GitHub <https://github.com/marcy-terui/lamvery>`__
-  Report issues/questions/feature requests on `GitHub
   Issues <https://github.com/marcy-terui/lamvery/issues>`__

Pull requests are very welcome! Make sure your patches are well tested.
Ideally create a topic branch for every separate change you make. For
example:

1. Fork the repo
2. Create your feature branch (``git checkout -b my-new-feature``)
3. Commit your changes (``git commit -am 'Added some feature'``)
4. Push to the branch (``git push origin my-new-feature``)
5. Create new Pull Request

Authors
-------

Created and maintained by `Masashi
Terui <https://github.com/marcy-terui>`__ (marcy9114@gmail.com)

License
-------

MIT License (see
`LICENSE <https://github.com/marcy-terui/lamvery/blob/master/LICENSE>`__)

.. |Build Status| image:: https://img.shields.io/travis/marcy-terui/lamvery/master.svg
   :target: http://travis-ci.org/marcy-terui/lamvery
.. |Coverage| image:: https://img.shields.io/coveralls/marcy-terui/lamvery.svg
   :target: https://coveralls.io/github/marcy-terui/lamvery
.. |Version| image:: https://img.shields.io/pypi/v/lamvery.svg
   :target: https://pypi.python.org/pypi/lamvery
.. |Downloads| image:: https://img.shields.io/pypi/dm/lamvery.svg
   :target: https://pypi.python.org/pypi/lamvery/
