Terraform configuring cloudwatch log subscription delivery to lambda?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
To send CloudWatch Logs events to Lambda with Terraform, you need more than just the log group and the function. The essential wiring is a log subscription filter plus explicit permission allowing CloudWatch Logs to invoke the Lambda function. Most failed setups come from missing that permission or from creating the resources in the wrong dependency order.
The Required Pieces
A working setup typically needs:
- an existing CloudWatch log group
- a Lambda function
- '
aws_lambda_permissionallowinglogs.amazonaws.comto invoke the function' - '
aws_cloudwatch_log_subscription_filterconnecting the log group to the function'
The subscription filter is the delivery rule, but it will not work unless Lambda permits that source principal to call it.
Define the Lambda Function and Log Group
A minimal example starts with the function and the log group.
In real code the function may already exist, but the subscription logic is the same.
Grant CloudWatch Logs Permission to Invoke Lambda
This resource is easy to miss and is often the real fix.
The source_arn restriction is important. It scopes the permission to that log group instead of allowing arbitrary log groups to invoke the function.
Create the Subscription Filter
Now connect the log group to Lambda.
An empty filter_pattern means all log events are forwarded. If you want only matching events, use a specific CloudWatch Logs filter pattern.
The explicit depends_on is helpful because the subscription can fail if Terraform tries to create it before the invoke permission exists.
Be Careful with Existing Log Groups
Sometimes the log group already exists because another service created it automatically. In that case you may want to reference it with a data source or import it into state rather than trying to recreate it.
The important idea is that the subscription filter attaches to the real log group name currently in AWS. Terraform resource ownership is a separate concern from the AWS wiring requirement.
Test the Whole Flow, Not Just Terraform Apply
A successful terraform apply does not prove that events are actually reaching the function. After deployment, generate a test log event and check Lambda logs or metrics.
Operationally, verify:
- the subscription filter exists on the intended log group
- Lambda invocation metrics increase
- the Lambda handler can decode CloudWatch Logs payloads
That last point matters because CloudWatch Logs delivers a compressed, encoded event wrapper, not plain log lines.
Common Pitfalls
- Creating the subscription filter without first granting Lambda permission to
logs.amazonaws.com. - Using the wrong
source_arnand accidentally preventing the log group from invoking the function. - Assuming
terraform applysuccess means the Lambda is processing events correctly. - Forgetting that CloudWatch Logs payloads arrive wrapped and encoded rather than as raw text lines.
- Trying to manage an already existing log group as a new Terraform resource without importing or referencing it properly.
Summary
- The key Terraform resources are the log group, Lambda function, invoke permission, and subscription filter.
- '
aws_lambda_permissionis required so CloudWatch Logs can invoke the function.' - The subscription filter connects the log group to the Lambda destination.
- Add a dependency so Terraform does not create the subscription before permission exists.
- Validate the end-to-end event flow after apply instead of stopping at infrastructure creation.
Related reading
- Terraform cycle with AWS and Kubernetes provider
- Terraform error - RDS Cluster FinalSnapshotIdentifier is required when a final snapshot is required
- Terraform Error creating IAM Role. MalformedPolicyDocument Has prohibited field Resource
- Terraform Fargate task definition requesting execution role
- Terraform, getting output from null_resource, local-exec and the AWS CLI
- Terraform How to migrate state between projects?
- Terraform kubernetes_config_map --from-env-file
- Terraform lookup AWS region

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.