Skip to content

Commit

Permalink
feat: Support aws_cloudwatch_log_data_protection_policy (#70)
Browse files Browse the repository at this point in the history
Co-authored-by: magreenbaum <magreenbaum>
  • Loading branch information
magreenbaum committed Sep 9, 2024
1 parent 235046c commit 2b434f3
Show file tree
Hide file tree
Showing 16 changed files with 506 additions and 0 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,36 @@ module "cis_alarms" {

AWS CloudTrail normally publishes logs into AWS CloudWatch Logs. This module creates log metric filters together with metric alarms according to [CIS AWS Foundations Benchmark v1.4.0 (05-28-2021)](https://www.cisecurity.org/benchmark/amazon_web_services/). Read more about [CIS AWS Foundations Controls](https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html).

### Log Group Data Protection Policy

```hcl
module "log_group_data_protection" {
source = "terraform-aws-modules/cloudwatch/aws//modules/log-data-protection-policy"
version = "~> 4.0"
log_group_name = "my-log-group"
create_log_data_protection_policy = true
log_data_protection_policy_name = "RedactAddress"
data_identifiers = ["arn:aws:dataprotection::aws:data-identifier/Address"]
findings_destination_cloudwatch_log_group = "audit-log-group"
}
```

### Log Subscription Filter

```hcl
module "log_subscription_filter" {
source = "terraform-aws-modules/cloudwatch/aws//modules/log-subscription-filter"
name = "my-filter"
destination_arn = "arn:aws:firehose:eu-west-1:835367859852:deliverystream/cw-logs"
filter_pattern = "%test%"
log_group_name = "my-log-group"
role_arn = "arn:aws:iam::835367859852:role/cw-logs-to-firehose"
}
```

### Metric Stream

```hcl
Expand Down Expand Up @@ -234,6 +264,8 @@ module "log_account_policy" {
- [Cloudwatch query definition](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/query-definition)
- [Cloudwatch Metric Stream](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/metric-stream)
- [Cloudwatch Composite Alarm](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/composite-alarm)
- [Cloudwatch log subscription filter](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/log-subscription-filter)
- [Cloudwatch log data protection policy](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/log-group-with-data-protection-policy)
- [Cloudwatch Log Account Policy](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/log-account-policy)

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Expand Down
39 changes: 39 additions & 0 deletions examples/log-group-with-data-protection-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Complete Cloudwatch log group and data protection policy

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0 |

## Providers

No providers.

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_audit_destination_group"></a> [audit\_destination\_group](#module\_audit\_destination\_group) | ../../modules/log-group | n/a |
| <a name="module_custom_data_protection_policy_log_group"></a> [custom\_data\_protection\_policy\_log\_group](#module\_custom\_data\_protection\_policy\_log\_group) | ../../modules/log-group | n/a |
| <a name="module_custom_log_data_protection_policy"></a> [custom\_log\_data\_protection\_policy](#module\_custom\_log\_data\_protection\_policy) | ../../modules/log-data-protection-policy | n/a |
| <a name="module_log_data_protection_policy"></a> [log\_data\_protection\_policy](#module\_log\_data\_protection\_policy) | ../../modules/log-data-protection-policy | n/a |
| <a name="module_log_group"></a> [log\_group](#module\_log\_group) | ../../modules/log-group | n/a |

## Resources

No resources.

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_cloudwatch_log_group_arn"></a> [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | ARN of Cloudwatch log group |
| <a name="output_cloudwatch_log_group_name"></a> [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of Cloudwatch log group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
84 changes: 84 additions & 0 deletions examples/log-group-with-data-protection-policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
provider "aws" {
region = "eu-west-1"
}

module "log_group" {
source = "../../modules/log-group"

name_prefix = "my-log-group-"
retention_in_days = 7
}

module "custom_data_protection_policy_log_group" {
source = "../../modules/log-group"

name_prefix = "my-custom-policy-log-group-"
retention_in_days = 7
}


module "audit_destination_group" {
source = "../../modules/log-group"

name_prefix = "audit-destination-log-group-"
retention_in_days = 7
}

module "log_data_protection_policy" {
source = "../../modules/log-data-protection-policy"

log_group_name = module.log_group.cloudwatch_log_group_name
create_log_data_protection_policy = true
log_data_protection_policy_name = "RedactAddress"

data_identifiers = ["arn:aws:dataprotection::aws:data-identifier/Address"]
findings_destination_cloudwatch_log_group = module.audit_destination_group.cloudwatch_log_group_name
}

module "custom_log_data_protection_policy" {
source = "../../modules/log-data-protection-policy"

log_group_name = module.custom_data_protection_policy_log_group.cloudwatch_log_group_name

# custom data identifier not yet supported by the data source for aws_cloudwatch_log_data_protection_policy within the module
# specify your own json policy document if this is needed
# https://github.com/hashicorp/terraform-provider-aws/issues/35682
policy_document = jsonencode({
Name = "RedactCustomerId"
Version = "2021-06-01"

Configuration = {
CustomDataIdentifier = [
{
Name = "CustomerId",
Regex = "CustomerId-\\d{5}"
}
]
}

Statement = [
{
Sid = "Audit"
DataIdentifier = ["CustomerId"]
Operation = {
Audit = {
FindingsDestination = {
CloudWatchLogs = {
LogGroup = module.audit_destination_group.cloudwatch_log_group_name
}
}
}
}
},
{
Sid = "Redact"
DataIdentifier = ["CustomerId"]
Operation = {
Deidentify = {
MaskConfig = {}
}
}
}
]
})
}
9 changes: 9 additions & 0 deletions examples/log-group-with-data-protection-policy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "cloudwatch_log_group_name" {
description = "Name of Cloudwatch log group"
value = module.log_group.cloudwatch_log_group_name
}

output "cloudwatch_log_group_arn" {
description = "ARN of Cloudwatch log group"
value = module.log_group.cloudwatch_log_group_arn
}
Empty file.
10 changes: 10 additions & 0 deletions examples/log-group-with-data-protection-policy/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
50 changes: 50 additions & 0 deletions modules/log-data-protection-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# log-data-protection-policy

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_cloudwatch_log_data_protection_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_data_protection_policy) | resource |
| [aws_cloudwatch_log_data_protection_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudwatch_log_data_protection_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_audit_statement_sid"></a> [audit\_statement\_sid](#input\_audit\_statement\_sid) | Name of the audit statement. | `string` | `"audit-policy"` | no |
| <a name="input_create"></a> [create](#input\_create) | Whether to create the cloudwatch log data protection policy. | `bool` | `true` | no |
| <a name="input_create_log_data_protection_policy"></a> [create\_log\_data\_protection\_policy](#input\_create\_log\_data\_protection\_policy) | Whether to create the cloudwatch log data protection policy. | `bool` | `false` | no |
| <a name="input_data_identifiers"></a> [data\_identifiers](#input\_data\_identifiers) | Set of at least 1 sensitive data identifiers that you want to mask. | `list(string)` | `null` | no |
| <a name="input_deidentify_statement_sid"></a> [deidentify\_statement\_sid](#input\_deidentify\_statement\_sid) | Name of the deidentify statement. | `string` | `"redact-policy"` | no |
| <a name="input_findings_destination_cloudwatch_log_group"></a> [findings\_destination\_cloudwatch\_log\_group](#input\_findings\_destination\_cloudwatch\_log\_group) | Configures CloudWatch Logs as a findings destination. | `string` | `null` | no |
| <a name="input_findings_destination_firehose_delivery_stream"></a> [findings\_destination\_firehose\_delivery\_stream](#input\_findings\_destination\_firehose\_delivery\_stream) | Configures Kinesis Firehose as a findings destination. | `string` | `null` | no |
| <a name="input_findings_destination_s3_bucket"></a> [findings\_destination\_s3\_bucket](#input\_findings\_destination\_s3\_bucket) | Configures S3 as a findings destination. | `string` | `null` | no |
| <a name="input_log_data_protection_description"></a> [log\_data\_protection\_description](#input\_log\_data\_protection\_description) | The description of the data protection policy document. | `string` | `null` | no |
| <a name="input_log_data_protection_policy_name"></a> [log\_data\_protection\_policy\_name](#input\_log\_data\_protection\_policy\_name) | The name of the data protection policy document. | `string` | `null` | no |
| <a name="input_log_group_name"></a> [log\_group\_name](#input\_log\_group\_name) | The name of the log group under which the log stream is to be created. | `string` | `null` | no |
| <a name="input_policy_document"></a> [policy\_document](#input\_policy\_document) | Specifies the data protection policy in JSON. | `string` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | Name of Cloudwatch log group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
60 changes: 60 additions & 0 deletions modules/log-data-protection-policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
resource "aws_cloudwatch_log_data_protection_policy" "this" {
count = var.create ? 1 : 0

log_group_name = var.log_group_name
policy_document = var.create_log_data_protection_policy ? data.aws_cloudwatch_log_data_protection_policy_document.this[0].json : var.policy_document
}

data "aws_cloudwatch_log_data_protection_policy_document" "this" {
count = var.create && var.create_log_data_protection_policy ? 1 : 0

name = var.log_data_protection_policy_name
description = var.log_data_protection_description

statement {
sid = var.audit_statement_sid
data_identifiers = var.data_identifiers

operation {
audit {
findings_destination {

dynamic "cloudwatch_logs" {
for_each = var.findings_destination_cloudwatch_log_group != null ? [true] : []

content {
log_group = var.findings_destination_cloudwatch_log_group
}
}

dynamic "firehose" {
for_each = var.findings_destination_firehose_delivery_stream != null ? [true] : []

content {
delivery_stream = var.findings_destination_firehose_delivery_stream
}
}

dynamic "s3" {
for_each = var.findings_destination_s3_bucket != null ? [true] : []

content {
bucket = var.findings_destination_s3_bucket
}
}
}
}
}
}

statement {
sid = var.deidentify_statement_sid
data_identifiers = var.data_identifiers

operation {
deidentify {
mask_config {}
}
}
}
}
4 changes: 4 additions & 0 deletions modules/log-data-protection-policy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "log_group_name" {
description = "Name of Cloudwatch log group"
value = var.log_group_name
}
71 changes: 71 additions & 0 deletions modules/log-data-protection-policy/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
variable "create" {
description = "Whether to create the cloudwatch log data protection policy."
type = bool
default = true
}

variable "create_log_data_protection_policy" {
description = "Whether to create the cloudwatch log data protection policy."
type = bool
default = false
}

variable "log_group_name" {
description = "The name of the log group under which the log stream is to be created."
type = string
default = null
}

variable "policy_document" {
description = "Specifies the data protection policy in JSON."
type = string
default = null
}

variable "log_data_protection_policy_name" {
description = "The name of the data protection policy document."
type = string
default = null
}

variable "log_data_protection_description" {
description = "The description of the data protection policy document."
type = string
default = null
}

variable "audit_statement_sid" {
description = "Name of the audit statement."
type = string
default = "audit-policy"
}

variable "deidentify_statement_sid" {
description = "Name of the deidentify statement."
type = string
default = "redact-policy"
}

variable "data_identifiers" {
description = "Set of at least 1 sensitive data identifiers that you want to mask."
type = list(string)
default = null
}

variable "findings_destination_cloudwatch_log_group" {
description = "Configures CloudWatch Logs as a findings destination."
type = string
default = null
}

variable "findings_destination_firehose_delivery_stream" {
description = "Configures Kinesis Firehose as a findings destination."
type = string
default = null
}

variable "findings_destination_s3_bucket" {
description = "Configures S3 as a findings destination."
type = string
default = null
}
10 changes: 10 additions & 0 deletions modules/log-data-protection-policy/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
Loading

0 comments on commit 2b434f3

Please sign in to comment.