Skip to main content

NTC Log Archive

Release Notes Source Code Implementation Blueprint

Description

NTC Log Archive provides a centralized solution for storing and managing audit logs in your AWS environment. This building block automates the provisioning of an audit log account to securely store critical log data, including CloudTrail logs, GuardDuty findings, and VPC Flow Logs. By consolidating logs into a dedicated account, NTC Log Archive ensures compliance with best practices for data isolation and long-term retention.

Designed to support security and compliance frameworks, this module helps you maintain a comprehensive audit trail and enables robust monitoring and forensic analysis.

Usage

Latest Release1.2.0
# --------------------------------------------------------------------------------------------------
# ¦ LOCALS
# --------------------------------------------------------------------------------------------------
locals {
# lifecycle configuration rules to optimize storage cost of logs throughout their lifecycle
default_lifecycle_configuration_rules = [
{
id = "transition_to_glacier"
enabled = true
transition = {
days = 365
storage_class = "GLACIER"
}
},
{
id = "expire_logs"
enabled = true
expiration = {
days = 730
}
}
]

# s3 access logging bucket must be deployed first or terraform must run twice
s3_access_logging_bucket_name = "audit-access-logging-bucket"
}

# --------------------------------------------------------------------------------------------------
# ¦ NTC S3 LOG ARCHIVE
# --------------------------------------------------------------------------------------------------
module "ntc_log_archive" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-log-archive?ref=X.X.X"

# log archive buckets to store s3 access logs, cloudtrail logs, vpc flow logs, dns query logs, aws config logs and guardduty logs
log_archive_buckets = [
{
bucket_name = local.s3_access_logging_bucket_name
archive_type = "s3_access_logging"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
object_lock_enabled = false
},
{
bucket_name = "audit-cloudtrail-archive"
archive_type = "org_cloudtrail"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "org_cloudtrail/"
# object_lock_enabled = true
# object_lock_configuration = {
# retention_mode = "COMPLIANCE"
# retention_days = 365
# }
},
{
bucket_name = "audit-vpc-flow-logs-archive"
archive_type = "vpc_flow_logs"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "vpc_flow_logs/"
},
{
bucket_name = "audit-transit-gateway-logs-archive"
archive_type = "transit_gateway_flow_logs"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "transit_gateway_flow_logs/"
},
{
bucket_name = "audit-dns-query-logs-archive"
archive_type = "dns_query_logs"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "dns_query_logs/"
},
{
bucket_name = "audit-guardduty-archive"
archive_type = "guardduty"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "guardduty/"
},
{
bucket_name = "audit-config-archive"
archive_type = "aws_config"
lifecycle_configuration_rules = local.default_lifecycle_configuration_rules
config_iam_path = "/"
config_iam_role_name = "ntc-config-role"
enable_access_logging = true
access_logging_target_bucket_name = local.s3_access_logging_bucket_name
access_logging_target_prefix = "aws_config/"
}
]

# WARNING: guardduty log archive cannot be provisioned in opt-in region (e.g. zurich)
# https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_exportfindings.html#guardduty-export-findings-considerations
providers = {
aws = aws.euc1
}
}

Requirements

The following requirements are needed by this module:

  • terraform (>= 1.3.1)

  • aws (>= 4.59)

Providers

The following providers are used by this module:

  • aws (>= 4.59)

Modules

The following Modules are called:

log_archive_bucket_encryption

Source: ./modules/log_archive_encryption

Version:

log_archive_bucket_policies

Source: ./modules/log_archive_policies

Version:

log_archive_buckets

Source: ./modules/bucket

Version:

Resources

The following resources are used by this module:

Required Inputs

No required inputs.

Optional Inputs

The following input variables are optional (have default values):

kms_key_deletion_window_in_days

Description: The waiting period, specified in number of days. After the waiting period ends, AWS KMS deletes the KMS key.

Type: number

Default: 7

kms_key_enable_key_rotation

Description: Specifies whether key rotation is enabled. Defaults to true.

Type: bool

Default: true

log_archive_buckets

Description: List of S3 log archive buckets.

Type:

list(object({
bucket_name = string
archive_type = string
config_iam_path = optional(string, "/")
config_iam_role_name = optional(string, "ntc-config-role")
enable_versioning = optional(bool, true)
bucket_force_destroy = optional(bool, false)
block_public_acls = optional(bool, true)
block_public_policy = optional(bool, true)
ignore_public_acls = optional(bool, true)
restrict_public_buckets = optional(bool, true)
object_lock_enabled = optional(bool, false)
enable_bucket_ownership_controls = optional(bool, false)
expected_bucket_owner = optional(string, null)
enable_access_logging = optional(bool, false)
access_logging_target_bucket_name = optional(string, "")
access_logging_target_prefix = optional(string, "logs/")
object_ownership = optional(string, "BucketOwnerEnforced")
object_lock_configuration = optional(
object({
token = optional(string, null)
retention_mode = optional(string, "COMPLIANCE")
retention_days = optional(number, 365)
}), {}
)
lifecycle_configuration_rules = optional(
list(object({
enabled = optional(bool, true)
id = string
abort_incomplete_multipart_upload_days = optional(number, null)
filter = optional(
object({
object_size_greater_than = optional(number, null)
object_size_less_than = optional(number, null)
prefix = optional(string, null)
tag = optional(
object({
key = string
value = string
}), null
)
}), {}
)
filter_and = optional(
object({
object_size_greater_than = optional(number, null)
object_size_less_than = optional(number, null)
prefix = optional(string, null)
tags = optional(map(string), null)
}), {}
)
expiration = optional(
object({
date = optional(string, null)
days = optional(number, null)
expired_object_delete_marker = optional(bool, null)
}), {}
)
transition = optional(
object({
date = optional(string, null)
days = optional(number, null)
storage_class = optional(string, "GLACIER")
}), {}
)
noncurrent_version_expiration = optional(
object({
newer_noncurrent_versions = optional(number, null)
noncurrent_days = optional(number, null)
}), {}
)
noncurrent_version_transition = optional(
object({
newer_noncurrent_versions = optional(number, null)
noncurrent_days = optional(number, null)
storage_class = optional(string, "GLACIER")
}), {}
)
})), []
)
}))

Default: []

Outputs

The following outputs are exported:

log_archive_bucket_arns

Description: ARNs of log archive buckets.

log_archive_bucket_ids

Description: Identifiers of log archive buckets.

log_archive_kms_key_arns

Description: ARNs of kms keys used to encrypt log archive buckets.