Skip to content

Commit

Permalink
Merge pull request #7 from pablo19sc/main
Browse files Browse the repository at this point in the history
Moving to version 1.0.0
  • Loading branch information
pablo19sc authored Aug 11, 2023
2 parents d4365ce + 385df71 commit 174d414
Show file tree
Hide file tree
Showing 40 changed files with 488 additions and 868 deletions.
72 changes: 56 additions & 16 deletions .header.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# AWS Network Firewall Module

AWS Network Firewall is a stateful, managed, network firewall and intrusion detection and prevention service for Amazon Virtual Private Clouds (Amazon VPCs). This module can be used to deploy an AWS Network Firewall resource in the desired VPC, automating all the routing and logging configuration when the resource is deployed.
*NOTE*: For information regarding the 1.0 upgrade see our [upgrade guide](./docs/UPGRADE-GUIDE-1.0.md)

This module only handles the creation of the infrastructure, leaving full freedom to the user to define the firewall rules (which should be done outside the module). Same applies to IAM roles and KMS keys when you define the logging of the firewall - rememeber that it is a best practice to encryt at rest your firewall logs.
[AWS Network Firewall](https://docs.aws.amazon.com/network-firewall/latest/developerguide/what-is-aws-network-firewall.html) is a managed network security service that makes it easy to deploy threat prevention for Amazon VPCs. This module can be used to deploy an AWS Network Firewall resource in the desired VPC, automating all the routing and logging configuration when the resource is deployed.

The module only handles the creation of the infrastructure, leaving full freedom to the user when defining the firewall rules (which should be done outside the module). Same applies to IAM roles and KMS keys when you define the firewall logging - rememeber that it is a best practice to encryt at rest your firewall logs.

## Usage

To create AWS Network Firewall in your VPC, you need to provide the following information:

- `network_firewall_name`= (Required|string) Name to provide the AWS Network Firewall resource.
- `network_firewall_name` = (Required|string) Name to provide the AWS Network Firewall resource.
- `network_firewall_description` = (Required|string) A friendly description of the firewall resource.
- `network_firewall_policy`= (Required|string) ARN of the firewall policy to apply in the AWS Network Firewall resource. Check the definition of [AWS Network Firewall Policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy) and [AWS Network Firewall Rule Groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_rule_group) to see how you can create firewall policies.
- `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`.
- `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. Example:
- `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):

```hcl
vpc_subnets = {
Expand All @@ -24,7 +28,7 @@ vpc_subnets = {
```

- `number_azs` = (Required|number) Number of Availability Zones to place the AWS Network Firewall endpoints.
- `routing_configuration` = (Required|any) Configuration of the routing desired in the VPC. Depending the type of VPC, the information to provide is different. The type of VPCs supported are: `single_vpc`, `intra_vpc_inspection`, `centralized_inspection_without_egress`, and `centralized_inspection_with_egress`. **Only one key (option) can be defined**. More information about the differences between each of the VPC types (and examples) can be checked in the section below.
- `routing_configuration` = (Required|any) 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**. More information about the differences between each of the VPC types (and examples) can be checked in the section below.
- `tags`= (Optional|map(string)) List of tags to apply to the AWS Network Firewall resource.

## Routing configuration
Expand All @@ -33,7 +37,11 @@ Once the AWS Network Firewall resource is created, the routing to the firewall e

### Single VPC

The first use case is when the firewall endpoints are located in the VPC to inspect the traffic from/to workloads in that same VPC - distributed inspection model. If using this routing configuration (`single_vpc`) it is expected to place the firewall endpoints in subnets between the Internet gateway (IGW) and the public subnets (where you can place the Elastic Load Balancers and NAT gateways).
The first use case is when the firewall endpoints are located in the VPC to inspect the traffic from/to workloads in that same VPC. When using this routing configuration, it is expected to place the firewall endpoints in subnets between the Internet gateway (IGW) and the public subnets (where you can place the Elastic Load Balancers and NAT gateways). The module expects in this configuration three variables:

- `igw_route_table` = (Required|string) VPC route table ID associated to an Internet gateway. In this route table it will be created routes pointing to the Network Firewall endpoints with destination the CIDR blocks provided in the `protected_subnet_cidr_blocks` variable.
- `protected_subnet_route_tables` = (Required|map(string)) Map of the VPC subnet route tables where the resources to protect (using the Network Firewall resource) are located - expected format of the map is Availability Zone (key) --> VPC route table (value). In these route tables it will be created the default route table pointing to the Network Firewall endpoints - ensuring Availability Zone affinity.
- `protected_subnet_cidr_blocks` = (Required|map(string)) Map of IPv4 CIDR blocks indicating the subnets where the resources to protect (using the Network Firewall resource) are located - expected format of the map is Availability Zone (key) --> IPv4 CIDR block (value).

An example of the definition of this routing configuration is the following one:

Expand All @@ -57,10 +65,12 @@ routing_configuration = {

### Intra-VPC Inspection

When placing firewall endpoints to inspect traffic between workloads inside the same VPC (between your EC2 instances and the database layer, for example) you can take advantage of the VPC routing enhacement - which allows you to include more specific routing than the local one (`intra_vpc_inspection`). The module expects in this variable two variables:
When placing firewall endpoints to inspect traffic between workloads inside the same VPC (between your EC2 instances and the database layer, for example) you can take advantage of the VPC routing enhacement - which allows you to include more specific routing than the local one. The module expects in this configuration two variables:

- `number_routes` = (Required|number) Number of configured items in the `routes` variable.
- `routes` = (Required|list(map(string))) List of intra-VPC route configurations. Each item of the list expects a map of strings with two values: `source_subnet_route_tables` and `destination_subnet_cidr_blocks`. These two values indicate the route table of the source subnet and the CIDR block of the destination subnet in which the firewall endpoint is going to be placed in between (several Availability Zones can be added). Remember that only one direction is configured per item, so in most situations you will need two items per group of subnets to inspect.
- `routes` = (Required|list(map(any))) List of intra-VPC route configurations. Important to note that only one direction is configured per item in this list, so in most situations you will need two items per group of subnets to inspect. Each item expects a map of strings with two values:
- `source_subnet_route_tables` = (Required|map(string)) VPC route table of the source subnet - expected format of the map is Availability Zone (key) --> VPC route table (value)
- `destination_subnet_cidr_blocks` = (Required|map(string)). IPv4 CIDR blocks of the destination subnet - expected format of the map is Availability Zone (key) --> IPv4 CIDR block (value)

An example of the definition of this routing configuration is the following one.

Expand Down Expand Up @@ -100,12 +110,16 @@ routing_configuration = {

### Hub and Spoke with Inspection VPC

The use case covers the creation of a centralized Inspection VPC in a Hub and Spoke architecture with AWS Transit Gateway, with the idea of managing the traffic inspection at scale. When using the key `centralized_inspection_without_egress` it is supposed that the Inspection VPC created is only used to place the AWS Transit Gateway ENIs and the firewall endpoints. An example of the definition of this routing configuration is the following one:
The use case covers the creation of a centralized Inspection VPC in a hub-and-spoke architecture with [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) and/or [AWS Cloud WAN](https://docs.aws.amazon.com/network-manager/latest/cloudwan/what-is-cloudwan.html), with the idea of managing the traffic inspection at scale. When using the key `centralized_inspection_without_egress` it is supposed that the Inspection VPC created is only used to place the Transit Gateway or Cloud WAN's core network ENIs and the firewall endpoints. In this configuration, you can configurate the following variables:

- `connectivity_subnet_route_tables` = (Optional|map(string)) Map of VPC subnet route tables where the Transit Gateway or Cloud WAN's core network ENIs are located. In these route tables a default route pointing to the Network Firewall endpoints is created - expected format of the map is Availability Zone (key) --> VPC route table (value)

An example of the definition of this routing configuration is the following one:

```hcl
routing_configuration = {
centralized_inspection_without_egress = {
tgw_subnet_route_tables = {
connectivity_subnet_route_tables = {
us-east-1a = rtb-IDa
us-east-1b = rtb-IDb
us-east-1c = rtb-IDc
Expand All @@ -116,12 +130,18 @@ routing_configuration = {

### Hub and Spoke with Inspection VPC (with egress traffic)

The use case covers the creation of a centralized Inspection VPC in a Hub and Spoke architecture with AWS Transit Gateway, with the idea of managing the traffic inspection at scale. When using the key `centralized_inspection_with_egress` it is supposed that the Inspection VPC also has access to the Internet, to centralize inspection and egress traffic at the same time. An example of the definition of this routing configuration is the following one:
The use case covers the creation of a centralized Inspection VPC in a hub-and-spoke architecture with [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) or [AWS Cloud WAN](https://docs.aws.amazon.com/network-manager/latest/cloudwan/what-is-cloudwan.html), with the idea of managing the traffic inspection at scale. When using the key `centralized_inspection_with_egress` it is supposed that the Inspection VPC also has access to the Internet, to centralize inspection and egress traffic at the same time. In this configuration, you can configurate the following variables:

- `connectivity_subnet_route_tables` = (Optional|map(string)) Map of VPC subnet route tables where the Transit Gateway or Cloud WAN's core network ENIs are located. In these route tables a default route pointing to the Network Firewall endpoints is created - expected format of the map is Availability Zone (key) --> VPC route table (value)
- `public_subnet_route_tables` = (Required|map(string)) Map of VPC public subnet route tables. In these route tables, routes are created pointing to the Network Firewall endpoints with destination the CIDR blocks defined in the `network_cidr_blocks` variable. The expected format of the map is Availability Zone (key) --> VPC route table (value)
- `network_cidr_blocks` = (Required|list(string)) List of IPv4 CIDR blocks defining the AWS network.

An example of the definition of this routing configuration is the following one:

```hcl
routing_configuration = {
centralized_inspection_with_egress = {
tgw_subnet_route_tables = {
connectivity_subnet_route_tables = {
us-east-1a = rtb-IDa
us-east-1b = rtb-IDb
us-east-1c = rtb-IDc
Expand All @@ -138,14 +158,24 @@ routing_configuration = {

## Logging

You can enable AWS Network Firewall logging for the stateful engine. You can record the flow logs and/or alert logs, with only one destination per log type:
You can enable AWS Network Firewall logging for the [stateful engine](https://docs.aws.amazon.com/network-firewall/latest/developerguide/firewall-rules-engines.html). You can record the flow logs and/or alert logs, with only one destination per log type:

* Amazon S3 bucket.
* Amazon CloudWatch log group.
* Amazon Kinesis Data Firehose stream.
* [Amazon S3](https://aws.amazon.com/s3/) bucket.
* [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) log group.
* [Amazon Kinesis Data Firehose](https://aws.amazon.com/kinesis/data-firehose/) stream.

For more information about the logging in AWS Network Firewall, check the [AWS Network Firewall documentation](https://docs.aws.amazon.com/network-firewall/latest/developerguide/firewall-logging.html).

Regarding the format of the variable, you can define either `flow_log` or `alert_log` configurations; with only 1 destination in each one of them. As mentioned above, 3 different destinations can be configured:

- `s3_bucket` = (Optional|map(string)) Configuration of an S3 bucket as logging destination. Two attributes are expected:
- `bucketName` = (Required|string) Name of the S3 bucket to deliver the logs.
- `logPrefix` = (Optional|string) Path inside the S3 bucket.
- `cloudwatch_logs` = (Optional|map(string)) Configuration of a CloudWatch log group as logging destination. Only the attribute `logGroupName` (Required|string) is expected.
- `kinesis_firehose` = (Optional|map(string)) Configuration of a Kinesis Data Firehose stream as logging desintation. Only the attribute `deliveryStreamName` (Required|string) is expected.

Example definition of each type:

```hcl
logging_configuration = {
flow_log = {
Expand All @@ -154,13 +184,23 @@ logging_configuration = {
logPrefix = "/logs"
}
}
}
logging_configuration = {
alert_log = {
cloudwatch_logs = {
logGroupName = "my-log-group"
}
}
}
logging_configuration = {
alert_log = {
kinesis_firehose = {
deliveryStreamName = "my-stream"
}
}
}
```

## References
Expand Down
Loading

0 comments on commit 174d414

Please sign in to comment.