Skip to content

Forward AWS Logs via Lambda Shipper with Terraform

Overview

Our latest AWS integration provides the easiest way to connect with Coralogix. By using a predefined Lambda function, you can seamlessly send AWS logs and events to your Coralogix subscription for detailed analysis, monitoring, and troubleshooting.

This integration guide walks you through completing the predefined Lambda function template using Terraform. You’ll need to provide specific configuration parameters based on the service you want to connect. A reference list for these parameters is provided below.

Requirements

NameVersion
Terraform>= 1.7.0
AWS>= 2.23

Providers

NameVersion
AWS>= 4.15.1
Random>= 3.1.0

Modules

NameVersion
terraform-aws-modules/lambda/aws>= 3.3.1

Universal configuration

You need to use an existing Coralogix Send-Your-Data API key to make the connection. Also, make sure your integration is region-specific. You should always deploy the AWS Lambda function in the same AWS region as your resource (e.g. the S3 bucket).

Using a single S3 bucket for multiple integrations

If you're deploying multiple integrations through the same S3 bucket, you'll need to specify parameters for each integration separately using integration_info.

!!! note\n If you already have a Lambda function with an S3 trigger set up, this Terraform deployment will remove the trigger. This applies to the following integration types within the same S3 bucket: S3, CloudTrail, VpcFlow, S3Csv, and CloudFront. To prevent this issue, you can explore alternative deployment methods: - Deploy the integration using CF Quick Create or SAR, as explained in this document. - Migrate your existing integrations to Terraform and use the integration_info variable.
NameDescriptionTypeDefaultRequired
coralogix_regionThe Coralogix location region, available options: [EU1, EU2, AP1, AP2, AP3, US1, US2, Custom]stringn/ayes
custom_domainIf using a custom domain name for your private cluster, Coralogix will send telemetry from the specified address (e.g. custom.coralogix.com). There is no need to add ingress. to the domain.stringn/ano
integration_typeThe AWS service to integrate with Coralogix. Possible values: S3, CloudTrail, VpcFlow, CloudWatch, S3Csv, SNS, SQS, Kinesis, CloudFront, MSK, Kafka, EcrScan.stringS3yes
api_keyThe Coralogix Send Your Data - API key validates your authenticity. This value can be a direct Coralogix API key or an AWS secret manager ARN containing the API key.stringn/ayes
store_api_key_in_secrets_managerEnable this to store your API key securely. Otherwise, it will remain exposed in plain text as an environment variable in the Lambda function console.booltrueno
application_nameThe name of your application. For a dynamic value, use $.my_log.field. This option is not supported since version 1.1.0 for the source codestringn\ayes
subsystem_nameThe name of your subsystem. For a dynamic value, use $.my_log.field for CloudWatch log group leave empty. This option is not supported since version 1.1.0 for the source codestringn\ayes

S3, CloudTrail, Vpc Flow, S3Csv configuration

NameDescriptionTypeDefaultRequired
s3_bucket_nameComma separated list of the names for the S3 bucket to watch.stringn/ayes
s3_key_prefixThe S3 path prefix to watch.stringn/ano
s3_key_suffixThe S3 path suffix to watch.stringn/ano
s3_bucket_kms_arnThe AWS ARN of the KMS key used to encrypt/decrypt objects in the specified S3 bucket. If provided, the Lambda policy will include permissions to decrypt using this key.stringn/ano
csv_delimiterA single character to be used as a delimiter when ingesting a CSV file with a header line. This value is applicable when the S3Csv integration type is selected, for example, “,” or ” “.stringn/ano
custom_csv_headerList seperated by cs delimiter of a new headers for your csv, the variable must be with the same delimiter as the cs_delimiter. For example, if the cs_delimiter is \";\", then the variable vakue should be name;country;age, resulting in the following new headers in Corlaogix: name, country, agestringn/ano
newline_patternA regular expression to detect a new log line for multiline logs, e.g., \n(?=\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3}).stringn/ano
integration_infoA map of integration information. Use this to deploy multiple integrations using the same s3 bucket. See the integration parameters.mappingn/ano

Additional parameters for integration_info

NameDescriptionTypeDefaultRequired
integration_typeThe AWS service to integrate with Coralogix. Possible values: S3, CloudTrail, VpcFlow, S3Csv, CloudFront.stringn/ayes
api_keyThe Coralogix Send Your Data - API key validates your authenticity. This value can be a direct Coralogix API key or an AWS secret mManager ARN containing the API key.stringn/ayes
store_api_key_in_secrets_managerEnable this to store your API key securely. Otherwise, it will remain exposed in plain text as an environment variable in the Lambda function console.booltrueno
application_nameThe name of your application. For dynamic values, refer to Metadatastringn\ayes
subsystem_nameThe name of your subsystem. For dynamic values, refer to Metadatastringn\ayes
lambda_log_retentionThe CloudWatch log retention period (in days) for logs generated by the Lambda function.number5no
lambda_nameName of the Lambda function that you want to create.stringn/ano
s3_key_prefixThe S3 path prefix to watch.stringn/ano
s3_key_suffixThe S3 path suffix to watch.stringn/a`no
newline_patternA regular expression to detect a new log line for multiline logs, e.g., \n(?=\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3}).stringn/ano

CloudWatch configuration

NameDescriptionTypeDefaultRequired
log_groupsA comma-separated list of CloudWatch log group names to monitor. For example, (log-group1, log-group2, log-group3).list(string)n/ayes
log_group_prefixlist of strings of log group prefixes. The code will use these prefixes to create permissions for the Lambda instead of creating for each log group permission it will use the prefix with a wild card to give the Lambda access for all of the log groups that start with these prefix. This parameter doesn't replace the log_groups parameter. For more information, refer to the Note below.list(string)n/ano

!!! note\n The log_group variable will get a list of log groups and then add them to the Lambda as triggers, each log group will also add permission to the Lambda, in some cases when there are a lot of log groups this will cause an error because the code tries to create too many permissions for the Lambda (AWS have a limitation for the number of permission that you can have for a Lambda), and this is why we have the log_group_prefix parameter, this parameter will add only permission to the Lambda using a wildcard( * ). for example, in case I have the log groups: log1,log2,log3 instead that the code will create for each of the log group permission to trigger the shipper Lambda then you can set log_group_prefix = ["log"], and then it will create only 1 permission for all of the log groups to trigger the shipper Lambda, but you will still need to set log_groups = ["log1","log2","log3"]. When using this parameter, you will not be able to see the log groups as triggers for the Lambda. If you need to add multiple log groups to the Lambda function using regex, refer to our Lambda manager

SNS configuration

NameDescriptionTypeDefaultRequired
sns_topic_nameThe SNS topic containing the SNS subscription. You need this only when using the SNS integration.stringn/ayes
sns_topic_filterMap of filters to add to the SNS topic Lambda subscription.map(any)n/ano
sns_topic_filter_policy_scopeThe scope of the filter policy for the SNS topic Lambda subscription, could be MessageAttributes or MessageBodystringn/ano

SQS configuration

NameDescriptionTypeDefaultRequired
sqs_nameThe name of the SQS queue to which you want to subscribe for retrieving messages.stringn/ayes

Kinesis configuration

NameDescriptionTypeDefaultRequired
kinesis_stream_nameThe name of the Kinesis stream to which you want to subscribe for retrieving messages.stringn/ayes

MSK configuration

NameDescriptionTypeDefaultRequired
msk_cluster_arnThe ARN of the MSK cluster to subscribe to retrieving messages.stringn/ayes
msk_topic_nameList of The Kafka topic names used to store records in your Kafka cluster [\"topic-name1\" ,\"topic-name2\"].list of stringsn/ayes

Kafka configuration

NameDescriptionTypeDefaultRequired
kafka_brokersComma-delimited list of Kafka broker to connect to.stringn/ayes
kafka_topicThe Kafka topic to subscribe to.stringn/ayes
kafka_subnets_idsList of Kafka subnets to use when connecting to Kafka.listn/ayes
kafka_security_groupsList of Kafka security groups to use when connecting to Kafka.listn/ayes

Generic configuration (optional)

NameDescriptionTypeDefaultRequired
custom_metadataCustom metadata to be added to the log message in the comma-separated format. Options are: key1=value1,key2=value2stringn/ano
add_metadataCustom metadata to be added to the log message in the comma-separated format. The S3 options are: bucket_name,key_name. For CloudWatch stream_name, loggroup_name. For Kafka/MSK, use topic_namestringn/ano
lambda_nameThe name the Lambda function to create.stringn/ano
blocking_patternA regular expression to identify lines excluded from being sent to Coralogix. For example, use MainActivity.java:\d{3} to match log lines with MainActivity followed by exactly three digits.stringn/ano
sampling_rateA message rate, such as 1 out of every N logs. For example, if your value is 10, a message will be sent for every 10th log.number1no
notification_emailA failure notification to be sent to the email address.stringn/ano
custom_s3_bucketThe name of an existing S3 bucket in your region, in which the Lambda zip code will be uploaded to.stringn/ano
govcloud_deploymentEnable if you deploy the integration in govcloudboolfalseno

Custom S3 bucket

Use the custom_s3_bucket variable only when deploying the integration in an AWS region where CX does not provide a public bucket (e.g., GovCloud). When using this variable, you must create an S3 bucket in the desired region for the integration. After that, pass the bucket name as custom_s3_bucket. The module will download the integration file to your local workspace, upload it to the custom_s3_bucket, and then remove the file from your local workspace once the process is complete.

When using this variable you will need to create an S3 bucket in the region where you want to run the integration. Then, pass this bucket name as custom_s3_bucket. The module will download the integration file to your local workspace, and then upload these files to the custom_s3_bucket. At the end, remove the file from your local workspace once the process is complete.

Lambda configuration (optional)

NameDescriptionTypeDefaultRequired
memory_sizeThe memory size limit for the Lambda function in megabytes.number1024no
timeoutThe timeout limit for the Lambda function in seconds.number300no
tagsThe tag map to all resources.map(string)n/ano
lambda_log_retentionThe CloudWatch log retention period (in days) for logs generated by the Lambda function.number5no
log_levelThe log level for the Lambda function. Possible values: INFO, WARN, ERROR, DEBUG.stringINFOno
cpu_archLambda function CPU architecture: arm64 or x86_64.stringarm64no
runtimeLambda function runtime. For example, 'provided.al2023', 'provided.al2'.stringprovided.al2023no
reserved_concurrent_executionsThe number of concurrent executions reserved for the function. Leave empty to let Lambda use unreserved account concurrency.numbern/ano
execution_role_nameThe ARN of a user defined role be used as the execution role for the Lambda function.stringn/ano
lambda_assume_role_arnA role that the Lambda will assume. Leave empty to use the default permissions. Note that if this parameter is used, all S3 and ECR API calls from the Lambda will be made with the permissions of the assumed role.stringn/ano
source_code_versionThe version of the source code that the Lambda will use. Must be in x.x.x format. The oldest supported version is 1.0.8. For more information about each version changes, see Changelog. By default, the Lambda will use the latest version.stringn/ano

Metadata

The metadata features decribed below are only available in coralogix-aws-shipper v1.1.0 and later. The add_metadata parameter allows you to add metadata to the log message. The metadata is added to the log message as a JSON object. The metadata is specific to the integration type. For example, for S3, the metadata is s3.object.key and s3.bucket. For CloudWatch, the metadata is cw.log.group and cw.log.stream. See the table below for full metadata list.
Integration TypeMetadata KeyDescription
S3s3.bucketThe name of the S3 bucket
S3s3.object.keyThe key/path of the S3 object
CloudWatchcw.log.groupThe name of the CloudWatch log group
CloudWatchcw.log.streamThe name of the CloudWatch log stream
Cloudwatchcw.ownerThe owner of the log group
Kafkakafka.topicThe name of the Kafka topic
MSKkafka.topicThe name of the Kafka topic
Kinesiskinesis.event.idThe Kinesis event ID
Kinesiskinesis.event.nameThe Kinesis event name
kinesiskinesis.event.sourceThe Kinesis event source
kinesiskinesis.event.source_arnThe Kinesis event source ARN
Sqssqs.event.sourceThe SQS event source/queue
Sqssqs.event.idThe SQS event ID
Ecrecr.scan.idThe EXR scan ID
Ecrecr.scan.sourceThe ECR scan source

!!! note\n The metadata is not added by default. You must specify the metadata keys in the add_metadata parameter. For example, to add the bucket name and key name to the log message, set the add_metadata parameter to s3.object.key,s3.bucket. Some metadata keys will overlap as some integrations share the same metadata. For example, both Kafka and MSK have the same metadata key kafka.topic or both Kinesis and Cloudwatch metadata will be added in cases where a Cloudwatch log stream is being ingested from a Kinesis stream.

Dynamic subsystem or application name

As of v1.1.0 for the source code, you can use dynamic values for the application and subsystem name parameters based on the internal metadata defined above. To do accomplish this, use the following syntax:

{{ metadata.key | r'regex' }}
For example, to use the bucket name as the subsystem name, set the subsystem_name parameter to:
{{ s3.bucket }}
If to use the log group name as the application name, set the application_name parameter to:
{{ cw.log.group }}
To use a part of the metadata value, use a regular expression to extract the desired part. For example, if we have an s3.object.key value of AWSLogs/112322232/ELB1/elb.log and we want to extract the last part of the key as the subsystem name, we would set the subsystem_name parameter to:
{{ s3.object.key | r'AWSLogs\\/.+\\/(.*)$' }}
This would result in a SubsystemName value of elb.log as this is the part of the regex captured by the group (.*).

!!! important\n - The regex must be a valid regex pattern. - The regex must define a capture group for part of the string you want to use as the value - The metadata key must exist in the list defined above and be a part of the integration type that is deployed.

Dynamic values are only supported for the application_name and subsystem_name parameters, the custom_metadata parameter is not supported.

To use a json key value as the application name, set the application_name parameter to:

{{ $.json_key_path }}
If you are sending this json log to the shipper:
"json_log" : {
  {
    "application_key": "application_value"
  }
}
Set the application_name parameter to:
{{ $.json_log.application_key }}
Then, the application name value will be application_value.

VPC configuration (optional)

NameDescriptionTypeDefaultRequired
vpc_subnet_idsThe ID of the subnet where the integration will be deployed.list(string)n/ano
security_group_idsThe ID of the security group where the integration will be deployed.list(string)n/ano
security_create_endpointSet to true if you store your ApiKey in a secret (you can have only one of this endpoints per region)boolfalseno

DLQ

A Dead Letter Queue (DLQ) is a queue where messages are sent if they cannot be processed by the Lambda function. This is useful for debugging and monitoring.

To enable the DLQ, provide the required parameters listed below.
ParameterDescriptionDefault ValueRequired
enable_dlqEnable the Dead Letter Queue for the Lambda function.falseyes
dlq_s3_bucketAn S3 bucket used to store all failure events that have exhausted retries.yes
dlq_retry_limitThe number of times a failed event to be retried before being saved in S33yes
dlq_retry_delayThe delay in seconds between retries of failed events900yes

AWS PrivateLink

If you want to bypass using the public internet, you can use AWS PrivateLink to facilitate secure connections between your VPCs and AWS services. This option is available under VPC Configuration. For additional instructions on AWS PrivateLink, follow our dedicated tutorial.

As of Lambda source code version v1.3.0 and Terraform module version v2.6.0, the Coralogix AWS Shipper supports streaming Cloudwatch metrics to Coralogix via Firehose over a PrivateLink.

This workflow is designed for scenarios where you need to stream metrics from a CloudWatch metrics stream to Coralogix via a PrivateLink endpoint.

Why to use this workflow

AWS Firehose does not support PrivateLink endpoints as a destination because Firehose cannot be connected to a VPC, which is required to reach a PrivateLink endpoint. To overcome this limitation, the Coralogix AWS Shipper acts as a transform function. It is attached to a Firehose instance that receives metrics from the CloudWatch metrics stream and forwards them to Coralogix over a PrivateLink.

When to use this workflow

This workflow is designed to bypass the limitations of using Firehose with the Coralogix PrivateLink endpoint. If PrivateLink is not required, we recommend using the default Firehose integration for CloudWatch Stream Metrics, available here.

How does it work?

Cloudwatch stream via PrivateLink Workflow

To enable CloudWatch metrics streaming via Firehose (PrivateLink), you must provide the necessary parameters listed below.
ParameterDescriptionDefault ValueRequired
telemetry_modeSpecify the telemetry collection modes, supported values (metrics, logs). Note that this value must be set to metrics for the Cloudwatch metric stream workflowlogs.✔️
api_keyThe Coralogix Send Your Data - API key validates your authenticity. This value can be a direct Coralogix API key or an AWS secret manager ARN containing the API key.stringn/a
application_nameThe name of the application for which the integration is configured. Metadata specifies dynamic value retrieval options.stringn\a
subsystem_nameThe name of your subsystem. For a dynamic value, refer to the Metadata section. For CloudWatch, leave this field empty to use the log group name.stringn\a
coralogix_regionThe Coralogix location region, possible options are [EU1, EU2, AP1, AP2, AP3, US1, US2, Custom]stringn/a
s3_bucket_nameThe S3 bucket to be used to store records that have failed processing.✔️
subnet_idsThe ID of the subnet for the integration deployment.list(string)n/a
security_group_idsThe ID of the security group for the integration deployment.list(string)n/a
include_metric_stream_filterList of inclusive metric filters. If you specify this parameter, the stream sends only the conditional metric names from the specified metric namespaces. Leave empty to send all metricsllist(object({namespace=string, metric_names=list(string)})n/a

The include_metric_stream_filter example:

module "coralogix_aws_shipper" "coralogix_firehose_metrics_private_link" {
  source = "coralogix/aws-shipper/coralogix"
  telemetry_mode = "metrics"
  api_key = <your private key>
  application_name = "application_name"
  subsystem_name = "subsystem_name"
  coralogix_region = <coralogix region>
  s3_bucket_name = <s3 bucket name>
  subnet_ids = <subnet ids>
  security_group_ids = <security group ids>

  include_metric_stream_filter = [
    {
      namespace    = "AWS/EC2"
      metric_names = ["CPUUtilization", "NetworkOut"]
    },
    {
      namespace    = "AWS/S3"
      metric_names = ["BucketSizeBytes"]
    },
  ]
}

Outputs

NameDescription
lambda_function_arnThe ARN of the Lambda function.
lambda_function_nameThe name of the Lambda function.
lambda_role_arnThe ARN of the IAM role created for the Lambda function.
lambda_role_nameThe name of the IAM role created for the Lambda function.