These examples demonstrate practical, real-world usage patterns for the cloudwatch-logs module. Each example is self-contained and ready to run—simply copy the configuration, customize the values for your environment, and apply.

Getting Started

To run any example, follow these steps:

  1. Authenticate with the registry: terraform login registry.patterneddesigns.ca
  2. Initialize the working directory: terraform init
  3. Review the execution plan: terraform plan
  4. Apply the configuration: terraform apply

Usage Examples

Basic Usage

Minimal configuration for a CloudWatch Log Group

module "app_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name = "/app/my-application"
}

Custom Retention

Log group with custom retention period

module "short_term_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/app/debug"
  retention_in_days = 7
}

module "compliance_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/app/audit"
  retention_in_days = 365
}

module "permanent_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/app/critical"
  retention_in_days = 0  # Never expire
}

KMS Encrypted Logs

Log group with KMS encryption for sensitive data

# Create a KMS key for log encryption
resource "aws_kms_key" "logs" {
  description             = "KMS key for CloudWatch Logs encryption"
  deletion_window_in_days = 7
  enable_key_rotation     = true

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "Enable IAM User Permissions"
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
        }
        Action   = "kms:*"
        Resource = "*"
      },
      {
        Sid    = "Allow CloudWatch Logs"
        Effect = "Allow"
        Principal = {
          Service = "logs.${data.aws_region.current.name}.amazonaws.com"
        }
        Action = [
          "kms:Encrypt*",
          "kms:Decrypt*",
          "kms:ReEncrypt*",
          "kms:GenerateDataKey*",
          "kms:Describe*"
        ]
        Resource = "*"
        Condition = {
          ArnLike = {
            "kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"
          }
        }
      }
    ]
  })
}

resource "aws_kms_alias" "logs" {
  name          = "alias/cloudwatch-logs"
  target_key_id = aws_kms_key.logs.key_id
}

# Create encrypted log group
module "secure_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/app/secure"
  retention_in_days = 90
  kms_key_arn       = aws_kms_key.logs.arn
}

data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

Metric Filters

Log group with metric filters for monitoring

module "api_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/app/api"
  retention_in_days = 30

  metric_filters = [
    {
      name             = "error-count"
      pattern          = "ERROR"
      metric_name      = "ErrorCount"
      metric_namespace = "MyApp/API"
    },
    {
      name             = "warning-count"
      pattern          = "WARN"
      metric_name      = "WarningCount"
      metric_namespace = "MyApp/API"
    },
    {
      name             = "status-500"
      pattern          = "[ip, id, user, timestamp, request, status=5*, size]"
      metric_name      = "5xxErrors"
      metric_namespace = "MyApp/API"
    }
  ]
}

# Create alarms based on metrics
resource "aws_cloudwatch_metric_alarm" "high_errors" {
  alarm_name          = "api-high-error-rate"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "ErrorCount"
  namespace           = "MyApp/API"
  period              = 300
  statistic           = "Sum"
  threshold           = 10
  alarm_description   = "Error count exceeded threshold"

  alarm_actions = [aws_sns_topic.alerts.arn]
}

Lambda Integration

Log group for Lambda function with subscription filter

# Create log group for Lambda function
module "lambda_logs" {
  source  = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
  version = "1.3.0"

  log_group_name    = "/aws/lambda/my-processor"
  retention_in_days = 14

  metric_filters = [
    {
      name             = "cold-starts"
      pattern          = "INIT_START"
      metric_name      = "ColdStarts"
      metric_namespace = "Lambda/MyProcessor"
    },
    {
      name             = "timeouts"
      pattern          = "Task timed out"
      metric_name      = "Timeouts"
      metric_namespace = "Lambda/MyProcessor"
    }
  ]
}

# Stream logs to another Lambda for processing
resource "aws_lambda_permission" "cloudwatch" {
  statement_id  = "AllowCloudWatchLogs"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.log_processor.function_name
  principal     = "logs.amazonaws.com"
  source_arn    = "${module.lambda_logs.log_group_arn}:*"
}

resource "aws_cloudwatch_log_subscription_filter" "processor" {
  name            = "log-processor"
  log_group_name  = module.lambda_logs.log_group_name
  filter_pattern  = "ERROR"
  destination_arn = aws_lambda_function.log_processor.arn

  depends_on = [aws_lambda_permission.cloudwatch]
}