Skip to content

Commit

Permalink
bugfix: fix flow logs and tgw attachment (#94)
Browse files Browse the repository at this point in the history
* bugfix: fix flow logs and tgw attachment
BREAKING CHANGE: flow logs and tgw attachment were not working properly
- Fixed tgw attachments from creating multiple attachments
- Updated the `flow_logs` module to create multiple flow logs based on the inputs as lists
- Updated the `flow_logs` module ID variables to be plural

* corrected pluralization

* updated pluralize of all flow_log ids

* correcting list of resources in the modules

* okay now to just a normal list

* getting all of the ids from the for_each resource

* another attempt

* going back to values

* corrected conditional logic

* corrects the for_each calculated value

* corrected index

* converted for_each to count in flow_logs

* back to the normal var.vpc_ids

* changed output key and added new outputs

* fixing the name of flow_logs

* chore: terraform fmt and terraform-docs

---------

Co-authored-by: zachreborn <[email protected]>
  • Loading branch information
zachreborn and zachreborn authored Dec 3, 2024
1 parent eaa4246 commit b73470d
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 65 deletions.
52 changes: 29 additions & 23 deletions modules/aws/flow_logs/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- Blank module readme template: Do a search and replace with your text editor for the following: `module_name`, `module_description` -->
<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->
<a name="readme-top"></a>

<a name="readme-top"></a>

<!-- PROJECT SHIELDS -->
<!--
Expand All @@ -11,14 +11,14 @@
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->

[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![LinkedIn][linkedin-shield]][linkedin-url]


<!-- PROJECT LOGO -->
<br />
<div align="center">
Expand All @@ -28,7 +28,7 @@

<h3 align="center">Flow Logs Module</h3>
<p align="center">
This module sets up each componenet required to capture Flow Logs with the parameters specified. By default this module will be set up to work without any changes to variables other than the flow log capture source. The result of this module creates a unique cloudwatch log group with a prefix of 'flow_logs', an IAM policy and IAM role which can be used with ENI flow logs to deliver logs to that cloudwatch log group. One of flow_eni_id, flow_subnet_id, flow_transit_gateway_id, flow_transit_gateway_attachment_id, or flow_vpc_id must be provided.
This module sets up each componenet required to capture Flow Logs with the parameters specified. By default this module will be set up to work without any changes to variables other than the flow log capture source. The result of this module creates a unique cloudwatch log group with a prefix of 'flow_logs', an IAM policy and IAM role which can be used with ENI flow logs to deliver logs to that cloudwatch log group. One of flow_eni_ids, flow_subnet_ids, flow_transit_gateway_ids, flow_transit_gateway_attachment_ids, or flow_vpc_ids must be provided.
<br />
<a href="https://github.com/zachreborn/terraform-modules"><strong>Explore the docs »</strong></a>
<br />
Expand All @@ -41,7 +41,6 @@
</p>
</div>


<!-- TABLE OF CONTENTS -->
<details>
<summary>Table of Contents</summary>
Expand All @@ -59,22 +58,26 @@
</ol>
</details>


<!-- USAGE EXAMPLES -->

## Usage

### Simple Example

This simple example creates a flow log for a VPC. The flow logs are delivered to a CloudWatch Logs log group.

```
module "flow_logs" {
source = "github.com/zachreborn/terraform-modules//modules/aws/flow_logs"
flow_vpc_id = module.vpc.id
flow_vpc_ids = module.vpc.id
}
```

### VPC Example

This example configures Flow Logs to capture all traffic in a VPC. The flow logs are delivered to a CloudWatch Logs log group.

```
module "vpc_flow_logs" {
source = "github.com/zachreborn/terraform-modules//modules/aws/flow_logs"
Expand All @@ -91,13 +94,15 @@ module "vpc_flow_logs" {
flow_log_format = var.flow_log_format
flow_max_aggregation_interval = var.flow_max_aggregation_interval
flow_traffic_type = var.flow_traffic_type
flow_vpc_id = aws_vpc.vpc.id
flow_vpc_ids = aws_vpc.vpc.id
tags = var.tags
}
```

### Transit Gateway Example

This example configures Flow Logs to capture all traffic in a Transit Gateway. The flow logs are delivered to a CloudWatch Logs log group.

```
module "vpc_flow_logs" {
source = "github.com/zachreborn/terraform-modules//modules/aws/flow_logs"
Expand All @@ -114,14 +119,16 @@ module "vpc_flow_logs" {
flow_log_format = var.flow_log_format
flow_max_aggregation_interval = var.flow_max_aggregation_interval
flow_traffic_type = var.flow_traffic_type
flow_transit_gateway_id = aws_ec2_transit_gateway.transit_gateway.id
flow_transit_gateway_ids = aws_ec2_transit_gateway.transit_gateway.id
tags = var.tags
}
```

### Transit Gateway Attachment Example

This example configures Flow Logs to capture all traffic in a Transit Gateway Attachment. The flow logs are delivered to a CloudWatch Logs log group.

```
module "vpc_flow_logs" {
source = "github.com/zachreborn/terraform-modules//modules/aws/flow_logs"
Expand All @@ -138,7 +145,7 @@ module "vpc_flow_logs" {
flow_log_format = var.flow_log_format
flow_max_aggregation_interval = var.flow_max_aggregation_interval
flow_traffic_type = var.flow_traffic_type
flow_transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.this.id
flow_transit_gateway_attachment_ids = aws_ec2_transit_gateway_vpc_attachment.this.id
tags = var.tags
}
```
Expand Down Expand Up @@ -172,7 +179,7 @@ No modules.
| Name | Type |
|------|------|
| [aws_cloudwatch_log_group.log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_flow_log.vpc_flow](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_flow_log.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_iam_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.role_attach](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
Expand All @@ -188,15 +195,15 @@ No modules.
| <a name="input_cloudwatch_name_prefix"></a> [cloudwatch\_name\_prefix](#input\_cloudwatch\_name\_prefix) | (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. | `string` | `"flow_logs_"` | no |
| <a name="input_cloudwatch_retention_in_days"></a> [cloudwatch\_retention\_in\_days](#input\_cloudwatch\_retention\_in\_days) | (Optional) Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653, and 0. If you select 0, the events in the log group are always retained and never expire. | `number` | `90` | no |
| <a name="input_flow_deliver_cross_account_role"></a> [flow\_deliver\_cross\_account\_role](#input\_flow\_deliver\_cross\_account\_role) | (Optional) The ARN of the IAM role that posts logs to CloudWatch Logs in a different account. | `string` | `null` | no |
| <a name="input_flow_eni_id"></a> [flow\_eni\_id](#input\_flow\_eni\_id) | (Optional) Elastic Network Interface ID to attach the flow logs to. | `string` | `null` | no |
| <a name="input_flow_eni_ids"></a> [flow\_eni\_ids](#input\_flow\_eni\_ids) | (Optional) List of Elastic Network Interface IDs to attach the flow logs to. | `list(string)` | `null` | no |
| <a name="input_flow_log_destination_type"></a> [flow\_log\_destination\_type](#input\_flow\_log\_destination\_type) | (Optional) The type of the logging destination. Valid values: cloud-watch-logs, s3. Default: cloud-watch-logs. | `string` | `"cloud-watch-logs"` | no |
| <a name="input_flow_log_format"></a> [flow\_log\_format](#input\_flow\_log\_format) | (Optional) The fields to include in the flow log record, in the order in which they should appear. For more information, see Flow Log Records. Default: fields are in the order that they are described in the Flow Log Records section. | `string` | `null` | no |
| <a name="input_flow_max_aggregation_interval"></a> [flow\_max\_aggregation\_interval](#input\_flow\_max\_aggregation\_interval) | (Optional) The maximum interval of time during which a flow of packets is captured and aggregated into a flow log record. Valid Values: 60 seconds (1 minute) or 600 seconds (10 minutes). Default: 600. | `number` | `60` | no |
| <a name="input_flow_subnet_id"></a> [flow\_subnet\_id](#input\_flow\_subnet\_id) | (Optional) Subnet ID to attach the flow logs to. | `string` | `null` | no |
| <a name="input_flow_subnet_ids"></a> [flow\_subnet\_ids](#input\_flow\_subnet\_ids) | (Optional) List of Subnet IDs to attach the flow logs to. | `list(string)` | `null` | no |
| <a name="input_flow_traffic_type"></a> [flow\_traffic\_type](#input\_flow\_traffic\_type) | (Optional) The type of traffic to capture. Valid values: ACCEPT,REJECT, ALL. | `string` | `"ALL"` | no |
| <a name="input_flow_transit_gateway_attachment_id"></a> [flow\_transit\_gateway\_attachment\_id](#input\_flow\_transit\_gateway\_attachment\_id) | (Optional) The ID of the transit gateway attachment to attach the flow logs to. | `string` | `null` | no |
| <a name="input_flow_transit_gateway_id"></a> [flow\_transit\_gateway\_id](#input\_flow\_transit\_gateway\_id) | (Optional) The ID of the transit gateway to attach the flow logs to. | `string` | `null` | no |
| <a name="input_flow_vpc_id"></a> [flow\_vpc\_id](#input\_flow\_vpc\_id) | (Optional) VPC ID to attach to. | `string` | `null` | no |
| <a name="input_flow_transit_gateway_attachment_ids"></a> [flow\_transit\_gateway\_attachment\_ids](#input\_flow\_transit\_gateway\_attachment\_ids) | (Optional) List of IDs of the transit gateway attachments to attach the flow logs to. | `list(string)` | `null` | no |
| <a name="input_flow_transit_gateway_ids"></a> [flow\_transit\_gateway\_ids](#input\_flow\_transit\_gateway\_ids) | (Optional) List of IDs of the transit gateways to attach the flow logs to. | `list(string)` | `null` | no |
| <a name="input_flow_vpc_ids"></a> [flow\_vpc\_ids](#input\_flow\_vpc\_ids) | (Optional) List of VPC IDs to attach the flow logs to. | `list(string)` | `null` | no |
| <a name="input_iam_policy_description"></a> [iam\_policy\_description](#input\_iam\_policy\_description) | (Optional, Forces new resource) Description of the IAM policy. | `string` | `"Used with flow logs to send packet capture logs to a CloudWatch log group."` | no |
| <a name="input_iam_policy_name_prefix"></a> [iam\_policy\_name\_prefix](#input\_iam\_policy\_name\_prefix) | (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with name. | `string` | `"flow_log_policy_"` | no |
| <a name="input_iam_policy_path"></a> [iam\_policy\_path](#input\_iam\_policy\_path) | (Optional, default '/') Path in which to create the policy. See IAM Identifiers for more information. | `string` | `"/"` | no |
Expand All @@ -223,15 +230,15 @@ No modules.
<!-- END_TF_DOCS -->

<!-- LICENSE -->

## License

Distributed under the MIT License. See `LICENSE.txt` for more information.

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- CONTACT -->

## Contact

Zachary Hill - [![LinkedIn][linkedin-shield]][linkedin-url] - [email protected]
Expand All @@ -240,19 +247,18 @@ Project Link: [https://github.com/zachreborn/terraform-modules](https://github.c

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- ACKNOWLEDGMENTS -->

## Acknowledgments

* [Zachary Hill](https://zacharyhill.co)
* [Jake Jones](https://github.com/jakeasarus)
- [Zachary Hill](https://zacharyhill.co)
- [Jake Jones](https://github.com/jakeasarus)

<p align="right">(<a href="#readme-top">back to top</a>)</p>


<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->

[contributors-shield]: https://img.shields.io/github/contributors/zachreborn/terraform-modules.svg?style=for-the-badge
[contributors-url]: https://github.com/zachreborn/terraform-modules/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/zachreborn/terraform-modules.svg?style=for-the-badge
Expand All @@ -267,4 +273,4 @@ Project Link: [https://github.com/zachreborn/terraform-modules](https://github.c
[linkedin-url]: https://www.linkedin.com/in/zachary-hill-5524257a/
[product-screenshot]: /images/screenshot.webp
[Terraform.io]: https://img.shields.io/badge/Terraform-7B42BC?style=for-the-badge&logo=terraform
[Terraform-url]: https://terraform.io
[Terraform-url]: https://terraform.io
31 changes: 22 additions & 9 deletions modules/aws/flow_logs/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ terraform {
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

###########################
# Locals
###########################
locals {

flow_logs_source = coalesce(
var.flow_eni_ids,
var.flow_subnet_ids,
var.flow_transit_gateway_ids,
var.flow_transit_gateway_attachment_ids,
var.flow_vpc_ids
)
}

###########################
# KMS Encryption Key
###########################
Expand Down Expand Up @@ -122,23 +136,22 @@ resource "aws_iam_role_policy_attachment" "role_attach" {
policy_arn = aws_iam_policy.policy.arn
}


###########################
# Flow Log
###########################

resource "aws_flow_log" "vpc_flow" {
resource "aws_flow_log" "this" {
count = length(local.flow_logs_source)
deliver_cross_account_role = var.flow_deliver_cross_account_role
eni_id = var.flow_eni_id
eni_id = var.flow_eni_ids != null ? local.flow_logs_source[count.index] : null
iam_role_arn = aws_iam_role.role.arn
log_destination_type = var.flow_log_destination_type
log_destination = aws_cloudwatch_log_group.log_group.arn
log_format = var.flow_log_format
max_aggregation_interval = var.flow_max_aggregation_interval
subnet_id = var.flow_subnet_id
subnet_id = var.flow_subnet_ids != null ? local.flow_logs_source[count.index] : null
tags = var.tags
transit_gateway_id = var.flow_transit_gateway_id
transit_gateway_attachment_id = var.flow_transit_gateway_attachment_id
transit_gateway_id = var.flow_transit_gateway_ids != null ? local.flow_logs_source[count.index] : null
transit_gateway_attachment_id = var.flow_transit_gateway_attachment_ids != null ? local.flow_logs_source[count.index] : null
traffic_type = var.flow_traffic_type
vpc_id = var.flow_vpc_id
}
vpc_id = var.flow_vpc_ids != null ? local.flow_logs_source[count.index] : null
}
30 changes: 15 additions & 15 deletions modules/aws/flow_logs/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ variable "flow_deliver_cross_account_role" {
default = null
}

variable "flow_eni_id" {
type = string
description = "(Optional) Elastic Network Interface ID to attach the flow logs to."
variable "flow_eni_ids" {
type = list(string)
description = "(Optional) List of Elastic Network Interface IDs to attach the flow logs to."
default = null
}

Expand All @@ -168,9 +168,9 @@ variable "flow_max_aggregation_interval" {
default = 60
}

variable "flow_subnet_id" {
type = string
description = "(Optional) Subnet ID to attach the flow logs to."
variable "flow_subnet_ids" {
type = list(string)
description = "(Optional) List of Subnet IDs to attach the flow logs to."
default = null
}

Expand All @@ -180,21 +180,21 @@ variable "flow_traffic_type" {
default = "ALL"
}

variable "flow_transit_gateway_id" {
type = string
description = "(Optional) The ID of the transit gateway to attach the flow logs to."
variable "flow_transit_gateway_ids" {
type = list(string)
description = "(Optional) List of IDs of the transit gateways to attach the flow logs to."
default = null
}

variable "flow_transit_gateway_attachment_id" {
type = string
description = "(Optional) The ID of the transit gateway attachment to attach the flow logs to."
variable "flow_transit_gateway_attachment_ids" {
type = list(string)
description = "(Optional) List of IDs of the transit gateway attachments to attach the flow logs to."
default = null
}

variable "flow_vpc_id" {
type = string
description = "(Optional) VPC ID to attach to."
variable "flow_vpc_ids" {
type = list(string)
description = "(Optional) List of VPC IDs to attach the flow logs to."
default = null
}

Expand Down
1 change: 1 addition & 0 deletions modules/aws/transit_gateway/attachment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ _For more examples, please refer to the [Documentation](https://github.com/zachr
|------|-------------|
| <a name="output_ids"></a> [ids](#output\_ids) | Map of VPC IDs and their transit gateway attachment IDs. |
| <a name="output_ids_list"></a> [ids\_list](#output\_ids\_list) | List of transit gateway attachment IDs |
| <a name="output_info"></a> [info](#output\_info) | A map with information about the transit gateway attachment. |
| <a name="output_vpc_owner_id"></a> [vpc\_owner\_id](#output\_vpc\_owner\_id) | Map of VPC IDs and their owner IDs |
<!-- END_TF_DOCS -->

Expand Down
30 changes: 15 additions & 15 deletions modules/aws/transit_gateway/attachment/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ resource "aws_ec2_transit_gateway_vpc_attachment" "this" {
module "vpc_flow_logs" {
source = "../../flow_logs"

for_each = var.enable_flow_logs ? var.vpc_ids : {}
cloudwatch_name_prefix = var.cloudwatch_name_prefix
cloudwatch_retention_in_days = var.cloudwatch_retention_in_days
iam_policy_name_prefix = var.iam_policy_name_prefix
iam_policy_path = var.iam_policy_path
iam_role_description = var.iam_role_description
iam_role_name_prefix = var.iam_role_name_prefix
key_name_prefix = var.key_name_prefix
flow_deliver_cross_account_role = var.flow_deliver_cross_account_role
flow_log_destination_type = var.flow_log_destination_type
flow_log_format = var.flow_log_format
flow_max_aggregation_interval = var.flow_max_aggregation_interval
flow_traffic_type = var.flow_traffic_type
flow_transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.this[each.key].id
tags = var.tags
count = var.enable_flow_logs ? 1 : 0
cloudwatch_name_prefix = var.cloudwatch_name_prefix
cloudwatch_retention_in_days = var.cloudwatch_retention_in_days
iam_policy_name_prefix = var.iam_policy_name_prefix
iam_policy_path = var.iam_policy_path
iam_role_description = var.iam_role_description
iam_role_name_prefix = var.iam_role_name_prefix
key_name_prefix = var.key_name_prefix
flow_deliver_cross_account_role = var.flow_deliver_cross_account_role
flow_log_destination_type = var.flow_log_destination_type
flow_log_format = var.flow_log_format
flow_max_aggregation_interval = var.flow_max_aggregation_interval
flow_traffic_type = var.flow_traffic_type
flow_transit_gateway_attachment_ids = [for attachment, value in aws_ec2_transit_gateway_vpc_attachment.this : value.id]
tags = var.tags
}
Loading

0 comments on commit b73470d

Please sign in to comment.