Skip to content

Commit

Permalink
Fix Network Firewall logging configuration (#3)
Browse files Browse the repository at this point in the history
* Update Network Firewall logging configuration

* Update Network Firewall logging configuration
  • Loading branch information
aknysh authored Jan 3, 2023
1 parent c1003ec commit 67653fa
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 33 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2022 Cloud Posse, LLC
Copyright 2022-2023 Cloud Posse, LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,24 @@ module "network_firewall" {
firewall_policy_change_protection = var.firewall_policy_change_protection
subnet_change_protection = var.subnet_change_protection
logging_config = [
{
logging_config = {
flow = {
log_destination_type = "S3"
log_type = "FLOW"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/network-firewall-logs"
prefix = "/flow"
}
},
alert = {
log_destination_type = "S3"
log_type = "ALERT"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/alert"
}
}
]
}
rule_group_config = {
stateful-inspection-for-blocking-packets-from-going-to-destination = {
Expand Down Expand Up @@ -269,7 +277,7 @@ Available targets:
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,<br>set as tag values, and output by this module individually.<br>Does not affect values of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.<br>Default value: `lower`. | `string` | `null` | no |
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_logging_config"></a> [logging\_config](#input\_logging\_config) | Logging configuration | `any` | `{}` | no |
| <a name="input_logging_config"></a> [logging\_config](#input\_logging\_config) | Logging configuration | `map(any)` | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_network_firewall_description"></a> [network\_firewall\_description](#input\_network\_firewall\_description) | AWS Network Firewall description. If not provided, the Network Firewall name will be used | `string` | `null` | no |
Expand Down Expand Up @@ -391,7 +399,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.

## Copyright

Copyright © 2017-2022 [Cloud Posse, LLC](https://cpco.io/copyright)
Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright)



Expand Down
16 changes: 12 additions & 4 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,24 @@ usage: |2-
firewall_policy_change_protection = var.firewall_policy_change_protection
subnet_change_protection = var.subnet_change_protection
logging_config = [
{
logging_config = {
flow = {
log_destination_type = "S3"
log_type = "FLOW"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/network-firewall-logs"
prefix = "/flow"
}
},
alert = {
log_destination_type = "S3"
log_type = "ALERT"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/alert"
}
}
]
}
rule_group_config = {
stateful-inspection-for-blocking-packets-from-going-to-destination = {
Expand Down
2 changes: 1 addition & 1 deletion docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,<br>set as tag values, and output by this module individually.<br>Does not affect values of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.<br>Default value: `lower`. | `string` | `null` | no |
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_logging_config"></a> [logging\_config](#input\_logging\_config) | Logging configuration | `any` | `{}` | no |
| <a name="input_logging_config"></a> [logging\_config](#input\_logging\_config) | Logging configuration | `map(any)` | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_network_firewall_description"></a> [network\_firewall\_description](#input\_network\_firewall\_description) | AWS Network Firewall description. If not provided, the Network Firewall name will be used | `string` | `null` | no |
Expand Down
16 changes: 12 additions & 4 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,24 @@ module "network_firewall" {
subnet_change_protection = var.subnet_change_protection

# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_logging_configuration
logging_config = [
{
logging_config = {
flow = {
log_destination_type = "S3"
log_type = "FLOW"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/network-firewall-logs"
prefix = "/flow"
}
},
alert = {
log_destination_type = "S3"
log_type = "ALERT"
log_destination = {
bucketName = module.s3_log_storage.bucket_id
prefix = "/alert"
}
}
]
}

# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_rule_group
rule_group_config = {
Expand Down
37 changes: 21 additions & 16 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ locals {
network_firewall_policy_name = var.network_firewall_policy_name != null && var.network_firewall_policy_name != "" ? var.network_firewall_policy_name : module.this.id
rule_group_config = { for k, v in var.rule_group_config : k => v if local.enabled }
logging_config = { for k, v in var.logging_config : k => v if local.enabled }
logging_enabled = length(keys(local.logging_config)) > 0
}

# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall
Expand Down Expand Up @@ -253,26 +254,30 @@ resource "aws_networkfirewall_firewall_policy" "default" {

# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_logging_configuration
resource "aws_networkfirewall_logging_configuration" "default" {
for_each = local.logging_config
count = local.logging_enabled ? 1 : 0

firewall_arn = one(aws_networkfirewall_firewall.default.*.arn)

logging_configuration {
log_destination_config {
# The location to send logs to. Valid values: S3, CloudWatchLogs, KinesisDataFirehose
log_destination_type = each.value.log_destination_type
# The type of log to send. Valid values: ALERT or FLOW
# Alert logs report traffic that matches a StatefulRule with an action setting that sends a log message
# Flow logs are standard network traffic flow logs
log_type = each.value.log_type
log_destination = {
# For log_destination_type = "CloudWatchLogs"
logGroup = lookup(each.value.log_destination, "logGroup", null)
# For log_destination_type = "S3"
bucketName = lookup(each.value.log_destination, "bucketName", null)
prefix = lookup(each.value.log_destination, "prefix", null)
# For log_destination_type = "KinesisDataFirehose"
deliveryStream = lookup(each.value.log_destination, "deliveryStream", null)
dynamic "log_destination_config" {
for_each = local.logging_config

content {
# The location to send logs to. Valid values: S3, CloudWatchLogs, KinesisDataFirehose
log_destination_type = log_destination_config.value.log_destination_type
# The type of log to send. Valid values: ALERT or FLOW
# Alert logs report traffic that matches a StatefulRule with an action setting that sends a log message
# Flow logs are standard network traffic flow logs
log_type = log_destination_config.value.log_type
log_destination = {
# For log_destination_type = "CloudWatchLogs"
logGroup = lookup(log_destination_config.value.log_destination, "logGroup", null)
# For log_destination_type = "S3"
bucketName = lookup(log_destination_config.value.log_destination, "bucketName", null)
prefix = lookup(log_destination_config.value.log_destination, "prefix", null)
# For log_destination_type = "KinesisDataFirehose"
deliveryStream = lookup(log_destination_config.value.log_destination, "deliveryStream", null)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ variable "rule_group_config" {
}

variable "logging_config" {
type = any
type = map(any)
description = "Logging configuration"
default = {}
}

0 comments on commit 67653fa

Please sign in to comment.