Skip to content

Commit

Permalink
Merge pull request #10 from alexknez/f-encryption
Browse files Browse the repository at this point in the history
Add encryption configuration
  • Loading branch information
pablo19sc authored Feb 12, 2024
2 parents 174d414 + eaf8b55 commit 786dc7c
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 64 deletions.
1 change: 1 addition & 0 deletions .header.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ To create AWS Network Firewall in your VPC, you need to provide the following in
- `network_firewall_delete_protection` = (Optional|bool) A boolean flag indicating whether it is possible to delete the firewall. Defaults to `false`.
- `network_firewall_policy_change_protection` = (Optional|bool) To indicate whether it is possible to change the associated firewall policy after creation. Defaults to `false`.
- `network_firewall_subnet_change_protection` = (Optional|bool) To indicate whether it is possible to change the associated subnet(s) after creation. Defaults to `false`.
- `network_firewall_encryption_key_arn` = (Optional|string) ARN of Customer managed KMS key for data encryption. By default, AWS managed key will be used.
- `vpc_id` = (Required|string) ID of the VPC where the AWS Network Firewall resource should be placed.
- `vpc_subnets` = (Required|map(string)) Map of subnet IDs to place the Network Firewall endpoints. The expected format of the map is the Availability Zone as key, and the ID of the subnet as value. Example (supposing us-east-1 as AWS Region):

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ To create AWS Network Firewall in your VPC, you need to provide the following in
- `network_firewall_delete_protection` = (Optional|bool) A boolean flag indicating whether it is possible to delete the firewall. Defaults to `false`.
- `network_firewall_policy_change_protection` = (Optional|bool) To indicate whether it is possible to change the associated firewall policy after creation. Defaults to `false`.
- `network_firewall_subnet_change_protection` = (Optional|bool) To indicate whether it is possible to change the associated subnet(s) after creation. Defaults to `false`.
- `network_firewall_encryption_key_arn` = (Optional|string) ARN of Customer managed KMS key for data encryption. By default, AWS managed key will be used.
- `vpc_id` = (Required|string) ID of the VPC where the AWS Network Firewall resource should be placed.
- `vpc_subnets` = (Required|map(string)) Map of subnet IDs to place the Network Firewall endpoints. The expected format of the map is the Availability Zone as key, and the ID of the subnet as value. Example (supposing us-east-1 as AWS Region):

Expand Down Expand Up @@ -254,6 +255,7 @@ logging_configuration = {
| <a name="input_vpc_subnets"></a> [vpc\_subnets](#input\_vpc\_subnets) | Map of subnet IDs to place the Network Firewall endpoints. The expected format of the map is the Availability Zone as key, and the ID of the subnet as value.<br>Example (supposing us-east-1 as AWS Region):<pre>vpc_subnets = {<br> us-east-1a = subnet-IDa<br> us-east-1b = subnet-IDb<br> us-east-1c = subnet-IDc<br>}</pre> | `map(string)` | n/a | yes |
| <a name="input_logging_configuration"></a> [logging\_configuration](#input\_logging\_configuration) | Configuration of the logging desired for the Network Firewall. You can configure at most 2 destinations for your logs, 1 for FLOW logs and 1 for ALERT logs.<br>More information about the format of the variable (and examples) can be found in the README.<pre></pre> | `any` | `{}` | no |
| <a name="input_network_firewall_delete_protection"></a> [network\_firewall\_delete\_protection](#input\_network\_firewall\_delete\_protection) | A boolean flag indicating whether it is possible to delete the firewall. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_network_firewall_encryption_key_arn"></a> [network\_firewall\_encryption\_key\_arn](#input\_network\_firewall\_encryption\_key\_arn) | Customer managed KMS Key ARN for encryption at rest. | `string` | `null` | no |
| <a name="input_network_firewall_policy_change_protection"></a> [network\_firewall\_policy\_change\_protection](#input\_network\_firewall\_policy\_change\_protection) | A boolean flag indicating whether it is possible to change the associated firewall policy. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_network_firewall_subnet_change_protection"></a> [network\_firewall\_subnet\_change\_protection](#input\_network\_firewall\_subnet\_change\_protection) | A boolean flag indicating whether it is possible to change the associated subnet(s). Defaults to `false`. | `bool` | `false` | no |
| <a name="input_routing_configuration"></a> [routing\_configuration](#input\_routing\_configuration) | Configuration of the routing desired in the VPC. Depending the VPC type, the information to provide is different. The configuration types supported are: `single_vpc`, `intra_vpc_inspection`, `centralized_inspection_without_egress`, and `centralized_inspection_with_egress`. **Only one key (option) can be defined**<br>More information about the differences between each the routing configurations (and examples) can be checked in the README.<pre></pre> | `any` | `{}` | no |
Expand Down
4 changes: 3 additions & 1 deletion examples/single_vpc_logging/.header.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ This example builds AWS Network Firewall in a single VPC to inspect any ingress/
* Outside of the Network Firewall module:
* Firewall policies - in `policy.tf`
* Amazon VPC with 3 subnet types (firewall, protected, and private)
* Created by the Network Firewall mdodule:
* KMS Key for CloudWatch log groups encryption
* KMS key for Network Firewall data encryption
* Created by the Network Firewall module:
* AWS Network Firewall resource.
* Routing to the firewall endpoints - to inspect traffic between the Internet gateway and the protected subnets.
* Logging configuration.
Expand Down
10 changes: 7 additions & 3 deletions examples/single_vpc_logging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ This example builds AWS Network Firewall in a single VPC to inspect any ingress/
* Outside of the Network Firewall module:
* Firewall policies - in `policy.tf`
* Amazon VPC with 3 subnet types (firewall, protected, and private)
* Created by the Network Firewall mdodule:
* KMS Key for CloudWatch log groups encryption
* KMS key for Network Firewall data encryption
* Created by the Network Firewall module:
* AWS Network Firewall resource.
* Routing to the firewall endpoints - to inspect traffic between the Internet gateway and the protected subnets.
* Logging configuration.
Expand Down Expand Up @@ -46,15 +48,16 @@ The AWS Region used in the example is **us-east-2 (Ohio)**.

| Name | Source | Version |
|------|--------|---------|
| <a name="module_network_firewall"></a> [network\_firewall](#module\_network\_firewall) | aws-ia/networkfirewall/aws | 1.0.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | aws-ia/vpc/aws | = 4.3.0 |
| <a name="module_network_firewall"></a> [network\_firewall](#module\_network\_firewall) | ../../ | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | aws-ia/vpc/aws | = 4.4.1 |

## Resources

| Name | Type |
|------|------|
| [aws_cloudwatch_log_group.alert_lg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_cloudwatch_log_group.flow_lg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_kms_key.encryption_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_kms_key.log_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_networkfirewall_firewall_policy.anfw_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy) | resource |
| [aws_networkfirewall_rule_group.allow_domains](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_rule_group) | resource |
Expand All @@ -63,6 +66,7 @@ The AWS Region used in the example is **us-east-2 (Ohio)**.
| [aws_route_table.igw_route_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table_association.igw_route_table_assoc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.policy_encryption_key_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.policy_kms_logs_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs
Expand Down
122 changes: 122 additions & 0 deletions examples/single_vpc_logging/kms_keys.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# DATA SOURCE: AWS CALLER IDENTITY - Used to get the Account ID
data "aws_caller_identity" "current" {}

# KMS Key for CloudWatch Log Groups
resource "aws_kms_key" "log_key" {
description = "KMS Logs Key"
deletion_window_in_days = 7
enable_key_rotation = true
policy = data.aws_iam_policy_document.policy_kms_logs_document.json

tags = {
Name = "kms-key-${var.identifier}"
}
}

# KMS Policy - it allows the use of the Key by the CloudWatch log groups created in this sample
data "aws_iam_policy_document" "policy_kms_logs_document" {
statement {
sid = "Enable IAM User Permissions"
actions = ["kms:*"]
resources = ["arn:aws:kms:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
}

statement {
sid = "Enable KMS to be used by CloudWatch Logs"
actions = [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
]
resources = ["arn:aws:kms:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]

principals {
type = "Service"
identifiers = ["logs.${var.aws_region}.amazonaws.com"]
}

condition {
test = "ArnLike"
variable = "kms:EncryptionContext:aws:logs:arn"
values = ["arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]
}
}
}

# Encryption KMS Key
resource "aws_kms_key" "encryption_key" {
description = "KMS Encryption Key"
deletion_window_in_days = 7
enable_key_rotation = true
policy = data.aws_iam_policy_document.policy_encryption_key_document.json

tags = {
Name = "kms-key-${var.identifier}"
}
}

# KMS Policy - it allows the use of the KMS Key by the root account and key creator
data "aws_iam_policy_document" "policy_encryption_key_document" {
statement {
sid = "Enable IAM User Permissions"
actions = ["kms:*"]
resources = ["arn:aws:kms:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
}

statement {
sid = "Allow access for Key Administrators"
actions = [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
]

resources = ["*"]
principals {
type = "AWS"
identifiers = [data.aws_caller_identity.current.arn]
}
}

statement {
sid = "Allow attachment of persistent resources"
actions = [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
]
resources = ["*"]
principals {
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
type = "AWS"
}
condition {
test = "Bool"
values = ["true"]
variable = "kms:GrantIsForAWSResource"
}
}
}
66 changes: 6 additions & 60 deletions examples/single_vpc_logging/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

# AWS Network Firewall
module "network_firewall" {
source = "aws-ia/networkfirewall/aws"
version = "1.0.0"
source = "../../"

network_firewall_name = "anfw-${var.identifier}"
network_firewall_description = "AWS Network Firewall - ${var.identifier}"
network_firewall_policy = aws_networkfirewall_firewall_policy.anfw_policy.arn
network_firewall_name = "anfw-${var.identifier}"
network_firewall_description = "AWS Network Firewall - ${var.identifier}"
network_firewall_policy = aws_networkfirewall_firewall_policy.anfw_policy.arn
network_firewall_encryption_key_arn = aws_kms_key.encryption_key.arn

vpc_id = module.vpc.vpc_attributes.id
number_azs = var.vpc.number_azs
Expand Down Expand Up @@ -40,7 +40,7 @@ module "network_firewall" {
# VPC Module - https://github.com/aws-ia/terraform-aws-vpc
module "vpc" {
source = "aws-ia/vpc/aws"
version = "= 4.3.0"
version = "= 4.4.1"

name = "single_vpc"
cidr_block = var.vpc.cidr_block
Expand Down Expand Up @@ -82,57 +82,3 @@ resource "aws_cloudwatch_log_group" "flow_lg" {
retention_in_days = 7
kms_key_id = aws_kms_key.log_key.arn
}

# DATA SOURCE: AWS CALLER IDENTITY - Used to get the Account ID
data "aws_caller_identity" "current" {}

# KMS
# KMS Key
resource "aws_kms_key" "log_key" {
description = "KMS Logs Key"
deletion_window_in_days = 7
enable_key_rotation = true
policy = data.aws_iam_policy_document.policy_kms_logs_document.json

tags = {
Name = "kms-key-${var.identifier}"
}
}

# KMS Policy - it allows the use of the Key by the CloudWatch log groups created in this sample
data "aws_iam_policy_document" "policy_kms_logs_document" {
statement {
sid = "Enable IAM User Permissions"
actions = ["kms:*"]
resources = ["arn:aws:kms:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
}

statement {
sid = "Enable KMS to be used by CloudWatch Logs"
actions = [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
]
resources = ["arn:aws:kms:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]

principals {
type = "Service"
identifiers = ["logs.${var.aws_region}.amazonaws.com"]
}

condition {
test = "ArnLike"
variable = "kms:EncryptionContext:aws:logs:arn"
values = ["arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"]
}
}
}

9 changes: 9 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ resource "aws_networkfirewall_firewall" "anfw" {
}
}

dynamic "encryption_configuration" {
for_each = var.network_firewall_encryption_key_arn == null ? [] : [1]

content {
type = "CUSTOMER_KMS"
key_id = var.network_firewall_encryption_key_arn
}
}

tags = module.tags.tags_aws
}

Expand Down
7 changes: 7 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ variable "network_firewall_subnet_change_protection" {
default = false
}

variable "network_firewall_encryption_key_arn" {
type = string
description = "Customer managed KMS Key ARN for encryption at rest."

default = null
}

variable "tags" {
description = "Tags to apply to the resources."
type = map(string)
Expand Down

0 comments on commit 786dc7c

Please sign in to comment.