Skip to content

Lambda functions should have logging config enabled

Lambda functions without an explicit logging config fall back to unstructured text logs sent to an auto-created CloudWatch Log Group. That default makes log parsing unreliable, blocks structured JSON queries in CloudWatch Logs Insights, and gives you no control over log levels. An explicit logging_config lets you choose JSON format, filter by severity (WARN and above for system logs, for example), and route to a specific log group with its own retention policy and encryption.

Without it, debugging production issues means manually scanning raw text output, and you lose the ability to set application and system log levels independently.

Retrofit consideration

Adding a logging_config block to existing functions triggers an update-in-place, not a replacement. Changing the log_group argument redirects logs to a new destination and will break any existing metric filters or subscription filters attached to the original auto-created log group.

Implementation

Choose the approach that matches how you manage Terraform.

If you use terraform-aws-modules/lambda/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.

module "lambda" {
  source  = "terraform-aws-modules/lambda/aws"
  version = ">=8.0.0"

  create_package         = false
  function_name          = "abc123"
  handler                = "index.lambda_handler"
  local_existing_package = "lambda_function.zip"
  runtime                = "python3.12"
}

Use AWS provider resources directly. See docs for the resources involved: aws_lambda_function.

resource "aws_lambda_function" "this" {
  filename                       = "lambda_function.zip"
  function_name                  = "pofix-abc123"
  handler                        = "index.handler"
  reserved_concurrent_executions = 100
  role                           = "arn:aws:iam::123456789012:role/example-role"
  runtime                        = "python3.12"
  source_code_hash               = "base64encodedhashabcdef1234567890=="
}

What this control checks

The control checks that the aws_lambda_function resource includes a logging_config block with log_format set to either "Text" or "JSON". A function missing the block entirely fails. When log_format is "JSON", you can also set application_log_level (TRACE, DEBUG, INFO, WARN, ERROR, FATAL) and system_log_level (DEBUG, INFO, WARN) to control verbosity. The log_group argument is optional and defaults to /aws/lambda/<function_name>, but specifying it explicitly ties the function to a managed aws_cloudwatch_log_group resource where you control retention and KMS encryption.

Common pitfalls

  • JSON format required for log level filtering

    application_log_level and system_log_level are silently ignored when log_format is "Text". The AWS API accepts the configuration without error but applies no filtering. If granular log level control is the goal, log_format must be "JSON".

  • Log group must exist before function deployment

    Define the aws_cloudwatch_log_group resource in Terraform before the Lambda function that references it. Lambda doesn't auto-create arbitrary custom log groups for this setting, and a missing log group causes deployment failures at apply time. Set retention_in_days and kms_key_id on that resource and reference its name in the Lambda logging_config.

  • Execution role needs log permissions for custom log groups

    Routing to a non-default log group means the Lambda execution role needs logs:CreateLogStream and logs:PutLogEvents scoped to that specific log group ARN. The default AWSLambdaBasicExecutionRole policy only covers /aws/lambda/*, so custom log groups require an explicit IAM policy addition.

  • Terraform provider version requirement

    Check your AWS provider version before adding logging_config. Older versions don't recognize the block and fail with a schema validation error at plan time, not apply time. Pin to a version that includes the argument and verify it in the provider changelog.

Audit evidence

Auditors will look for AWS Config rule results or a scanner report confirming all Lambda functions have logging configured. In the console, each function's Configuration tab under "Monitoring and operations tools" should show a defined Log format and Log group path. CloudWatch Logs should have recent log streams for each function confirming active log delivery.

For programmatic verification, aws lambda get-function-configuration --function-name <name> should return a LoggingConfig object with LogFormat set. Where structured logging is required, LogFormat should be JSON with ApplicationLogLevel and SystemLogLevel populated.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: lambda_function_logging_config_enabled

  • Powerpipe Control: aws_compliance.control.lambda_function_logging_config_enabled

Last reviewed: 2026-03-09