# terraform-lambda

## Overview
This module provisions a Lambda function, dead-letter SNS topic, and optional trigger/execution sources. Currently, it supports the following sources:

* Cloudwatch event
* DynamoDB stream
* Kinesis stream
* S3 bucket notification
* Managed Streaming for Kafka (MSK) stream

In the case of DynamoDB, Kinesis, MSK, and S3 event mapping, the module does not manage those resources (table, stream, and bucket, respectively); rather, it accepts variables specifying existing resources.

## Usage

### Lambda Settings

This module creates a function with the name `${var.environment}-${var.lambda_name}`, meaning that `${lambda_name}` should be set to an environment-neutral name, ideally matching the name of the service or application. If needed, you may provide a custom function name by setting `${var.use_custom_function_name}` to `true` and setting `${var.custom_function_name}` to your desired function name.

All functions run in a VPC, so make sure to specify `${var.vpc_id}` and `${var.vpc_subnet_ids}` accordingly.

### Environment Variables

Environment variables are a user-provided map, and should not contain sensitive credentials in plaintext.

### Dead Letter Queues
A dead letter queue (DLQ) is provisioned and configured for use by the lambda function, and is named `${var.environment}-${var.lambda_name}-dlq`. It can be either an SQS queue or SNS topic, which is controllable by setting the `${var.dlq_type}` variable (defaults to SNS). Additionally, it is encrypted using the lambda function's KMS key; this means that consumers of this DLQ must also have IAM access to this KMS key (the `lambda_kms_policy` output provides this ARN for use elsewhere).

What happens with this DLQ (e.g. another Lambda, email alerts, etc...) is not covered by this module and should be handled elsewhere.

### Event/Trigger Sources
Each source type has a boolean variable that controls whether or not to provision resources for it, which are detailed as follows:

* cloudwatch_event_enabled
* event_source_mapping_enabled
* s3_event_enabled
* msk_event_enabled

Set the variable to `true` for the corresponding source type and specify its parameters (e.g. for S3, set the bucket and optional object key prefix/suffix) to configure that resource.

These variables are set to `false` by default.

When setting one of these variables to `true`, you may need to also set other variables before applying the terraform. For instance, when setting `msk_event_enabled` to `true` you also need to set `event_source_mapping_msk_cluster_name`, `event_source_mapping_msk_cluster_uuid`, and `msk_topics`.  You can also filter events using the `event_source_mapping_filter_criteria_pattern` variable.


When `msk_event_enabled=true`, you can also set
 - `event_source_mapping_failure_arn` variable to send failed events to SNS, S3 or SQS. This takes ARN as value.
 - `msk_use_lambda_name_as_consumer_id` variable to use your lambda name as consumer id. This helps easily identify it in AKHQ or datadog consumer ids.


### IAM
In addition to the programmatically generated policies and roles used for generic Lambda execution, you may also provide a JSON file containing additional IAM policies your Lambda requires, which will be attached to the Lambda execution role. In order to use this functionality, set the `${var.iam_policy_file_enabled}` variable to `true` and provide a policy file.

These policy files, which **must** be named `policies/${lambda_name}.json`, should be located in the same directory as the `main.tf` that defines your service. That directory structure might look like this:
```
* ows-service/
    * qa/
        * policies/
            * ows-service.json <---- this is the additional policy file for qa
        * main.tf
        * terraform.tfvars
    * prod/
        * policies/
            * ows-service.json <---- this is the additional policy file for prod
        * main.tf
        * terraform.tfvars
```

Additionally, you may attach existing IAM policies (i.e pre-existing policies defined outside of your code) by setting the `${var.iam_managed_policy_attachments}` variable to a list of ARNs of IAM policies you wish to attach to the Lambda role being created.

* `var.datadog_enabled` controls whether or not the SecretsManager policy allowing access to Datadog API keys is attached. Default is true.

### EFS

You can attach EFS storage using the following steps:

- Set `efs_enabled` variable to `true`.
- Set `efs_access_point_arn` to ARN of the EFS access point.
- Set `efs_local_mount_path` to where the EFS should be mounted. Should start with '/mnt/' and be exactly the same as the EFS access point path.


### Testing

To test your changes:
1. Go in to the `test` directory and add your changes in to the respective files
2. Use `awsume` and generate creds for aws dev
3. Run `terraform plan` and ensure nothing is out of place and then run `terraform apply`
4. Once the apply is successful, be sure to run `terraform destroy` to tear all the test infraustructure.

If you went through all the steps with no errors then your changes are good to go!
