Cross-Account Log Streaming
Prerequisites
- AWS accounts with appropriate permissions
- Terraform >= 1.0
- Cross-account IAM roles configured
Step 1: Create Destination in Central Account
In your central logging account:
# Central logging account
module "central_logs" {
source = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
version = "1.3.0"
log_group_name = "/central/aggregated"
retention_in_days = 365
kms_key_arn = module.logging_kms.key_arn
}
resource "aws_cloudwatch_log_destination" "central" {
name = "central-log-destination"
role_arn = aws_iam_role.logs_destination.arn
target_arn = aws_kinesis_stream.logs.arn
}
resource "aws_cloudwatch_log_destination_policy" "central" {
destination_name = aws_cloudwatch_log_destination.central.name
access_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = var.source_account_ids
}
Action = "logs:PutSubscriptionFilter"
Resource = aws_cloudwatch_log_destination.central.arn
}
]
})
}
Step 2: Create Log Group in Source Account
In each source account:
# Source account
module "app_logs" {
source = "registry.patterneddesigns.ca/essentials/cloudwatch-logs/aws"
version = "1.3.0"
log_group_name = "/app/my-service"
retention_in_days = 30
}
resource "aws_cloudwatch_log_subscription_filter" "central" {
name = "stream-to-central"
log_group_name = module.app_logs.log_group_name
filter_pattern = ""
destination_arn = "arn:aws:logs:${var.region}:${var.central_account_id}:destination:central-log-destination"
distribution = "ByLogStream"
}
Step 3: Process Logs with Kinesis
# Central account - Kinesis stream and Lambda processor
resource "aws_kinesis_stream" "logs" {
name = "central-logs"
shard_count = 2
retention_period = 24
}
resource "aws_lambda_function" "log_processor" {
function_name = "log-processor"
runtime = "python3.12"
handler = "main.handler"
# ... additional configuration
}
resource "aws_lambda_event_source_mapping" "kinesis" {
event_source_arn = aws_kinesis_stream.logs.arn
function_name = aws_lambda_function.log_processor.arn
starting_position = "LATEST"
}
Step 4: Verify Streaming
Check that logs are flowing to the central account:
# In source account - generate test log
aws logs put-log-events \
--log-group-name "/app/my-service" \
--log-stream-name "test-stream" \
--log-events timestamp=$(date +%s000),message="Test log message"
# In central account - verify log arrival
aws logs filter-log-events \
--log-group-name "/central/aggregated" \
--filter-pattern "Test log message"