From 1681fa0a9c900d068f23e0fc3bca589fe5009e56 Mon Sep 17 00:00:00 2001 From: "Marlon (Esolitos) Saglia" Date: Sat, 9 Mar 2024 05:41:54 +0100 Subject: [PATCH] feat: add logging options (#26) * feat: add logging options * feat: automatically create cloudwatch log group if required * feat: improve name and allow selecting retention period * chore: make Run: make init make readme make github/init * fix: do not applly logging option when not enabled * Apply suggestions from code review by @gowiem Co-authored-by: Matt Gowie * chore: force document updates as in main * chore: make readme * chore: make github/init * fix: missed in merge Co-authored-by: Matt Gowie * chore: make readme --------- Co-authored-by: Matt Gowie --- .github/renovate.json | 7 +++--- .github/workflows/release-branch.yml | 1 + .github/workflows/release-published.yml | 2 +- README.md | 6 +++++ docs/terraform.md | 6 +++++ main.tf | 28 +++++++++++++++++++++++ variables.tf | 30 +++++++++++++++++++++++++ 7 files changed, 76 insertions(+), 4 deletions(-) diff --git a/.github/renovate.json b/.github/renovate.json index b61ed24..909df09 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,13 +1,14 @@ { "extends": [ "config:base", - ":preserveSemverRanges" + ":preserveSemverRanges", + ":rebaseStalePrs" ], - "baseBranches": ["main", "master", "/^release\\/v\\d{1,2}$/"], + "baseBranches": ["main"], "labels": ["auto-update"], "dependencyDashboardAutoclose": true, "enabledManagers": ["terraform"], "terraform": { - "ignorePaths": ["**/context.tf", "examples/**"] + "ignorePaths": ["**/context.tf"] } } diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml index 3f8fe62..b30901e 100644 --- a/.github/workflows/release-branch.yml +++ b/.github/workflows/release-branch.yml @@ -10,6 +10,7 @@ on: - 'docs/**' - 'examples/**' - 'test/**' + - 'README.*' permissions: contents: write diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml index f86352b..b31232b 100644 --- a/.github/workflows/release-published.yml +++ b/.github/workflows/release-published.yml @@ -11,4 +11,4 @@ permissions: jobs: terraform-module: - uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release.yml@main + uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release-published.yml@main diff --git a/README.md b/README.md index 0cce5ce..6a78711 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Available targets: | Name | Source | Version | |------|--------|---------| +| [logs](#module\_logs) | cloudposse/cloudwatch-logs/aws | 0.6.8 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -163,9 +164,12 @@ Available targets: | [transit\_gateway\_routes](#input\_transit\_gateway\_routes) | A map of transit gateway routes to create on the given TGW route table (via `transit_gateway_route_table_id`) for the created VPN Attachment. Use the key in the map to describe the route. |
map(object({
blackhole = optional(bool, false)
destination_cidr_block = string
}))
| `{}` | no | | [vpc\_id](#input\_vpc\_id) | The ID of the VPC to which the Virtual Private Gateway will be attached | `string` | `null` | no | | [vpn\_connection\_local\_ipv4\_network\_cidr](#input\_vpn\_connection\_local\_ipv4\_network\_cidr) | The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection. | `string` | `"0.0.0.0/0"` | no | +| [vpn\_connection\_log\_retention\_in\_days](#input\_vpn\_connection\_log\_retention\_in\_days) | Specifies the number of days you want to retain log events. | `number` | `30` | no | | [vpn\_connection\_remote\_ipv4\_network\_cidr](#input\_vpn\_connection\_remote\_ipv4\_network\_cidr) | The IPv4 CIDR on the AWS side of the VPN connection. | `string` | `"0.0.0.0/0"` | no | | [vpn\_connection\_static\_routes\_destinations](#input\_vpn\_connection\_static\_routes\_destinations) | List of CIDR blocks to be used as destination for static routes. Routes to destinations will be propagated to the route tables defined in `route_table_ids` | `list(string)` | `[]` | no | | [vpn\_connection\_static\_routes\_only](#input\_vpn\_connection\_static\_routes\_only) | If set to `true`, the VPN connection will use static routes exclusively. Static routes must be used for devices that don't support BGP | `bool` | `false` | no | +| [vpn\_connection\_tunnel1\_cloudwatch\_log\_enabled](#input\_vpn\_connection\_tunnel1\_cloudwatch\_log\_enabled) | Enable or disable VPN tunnel logging feature for the tunnel | `bool` | `false` | no | +| [vpn\_connection\_tunnel1\_cloudwatch\_log\_output\_format](#input\_vpn\_connection\_tunnel1\_cloudwatch\_log\_output\_format) | Set log format for the tunnel. Default format is json. Possible values are: json and text | `string` | `"json"` | no | | [vpn\_connection\_tunnel1\_dpd\_timeout\_action](#input\_vpn\_connection\_tunnel1\_dpd\_timeout\_action) | The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart. | `string` | `"clear"` | no | | [vpn\_connection\_tunnel1\_ike\_versions](#input\_vpn\_connection\_tunnel1\_ike\_versions) | The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel1\_inside\_cidr](#input\_vpn\_connection\_tunnel1\_inside\_cidr) | The CIDR block of the inside IP addresses for the first VPN tunnel | `string` | `null` | no | @@ -177,6 +181,8 @@ Available targets: | [vpn\_connection\_tunnel1\_phase2\_integrity\_algorithms](#input\_vpn\_connection\_tunnel1\_phase2\_integrity\_algorithms) | One or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel1\_preshared\_key](#input\_vpn\_connection\_tunnel1\_preshared\_key) | The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero. Allowed characters are alphanumeric characters, periods(.) and underscores(\_) | `string` | `null` | no | | [vpn\_connection\_tunnel1\_startup\_action](#input\_vpn\_connection\_tunnel1\_startup\_action) | The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. | `string` | `"add"` | no | +| [vpn\_connection\_tunnel2\_cloudwatch\_log\_enabled](#input\_vpn\_connection\_tunnel2\_cloudwatch\_log\_enabled) | Enable or disable VPN tunnel logging feature for the tunnel | `bool` | `false` | no | +| [vpn\_connection\_tunnel2\_cloudwatch\_log\_output\_format](#input\_vpn\_connection\_tunnel2\_cloudwatch\_log\_output\_format) | Set log format for the tunnel. Default format is json. Possible values are: json and text | `string` | `"json"` | no | | [vpn\_connection\_tunnel2\_dpd\_timeout\_action](#input\_vpn\_connection\_tunnel2\_dpd\_timeout\_action) | The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart. | `string` | `"clear"` | no | | [vpn\_connection\_tunnel2\_ike\_versions](#input\_vpn\_connection\_tunnel2\_ike\_versions) | The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel2\_inside\_cidr](#input\_vpn\_connection\_tunnel2\_inside\_cidr) | The CIDR block of the inside IP addresses for the second VPN tunnel | `string` | `null` | no | diff --git a/docs/terraform.md b/docs/terraform.md index a5c1645..ad6a8ec 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -16,6 +16,7 @@ | Name | Source | Version | |------|--------|---------| +| [logs](#module\_logs) | cloudposse/cloudwatch-logs/aws | 0.6.8 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -63,9 +64,12 @@ | [transit\_gateway\_routes](#input\_transit\_gateway\_routes) | A map of transit gateway routes to create on the given TGW route table (via `transit_gateway_route_table_id`) for the created VPN Attachment. Use the key in the map to describe the route. |
map(object({
blackhole = optional(bool, false)
destination_cidr_block = string
}))
| `{}` | no | | [vpc\_id](#input\_vpc\_id) | The ID of the VPC to which the Virtual Private Gateway will be attached | `string` | `null` | no | | [vpn\_connection\_local\_ipv4\_network\_cidr](#input\_vpn\_connection\_local\_ipv4\_network\_cidr) | The IPv4 CIDR on the customer gateway (on-premises) side of the VPN connection. | `string` | `"0.0.0.0/0"` | no | +| [vpn\_connection\_log\_retention\_in\_days](#input\_vpn\_connection\_log\_retention\_in\_days) | Specifies the number of days you want to retain log events. | `number` | `30` | no | | [vpn\_connection\_remote\_ipv4\_network\_cidr](#input\_vpn\_connection\_remote\_ipv4\_network\_cidr) | The IPv4 CIDR on the AWS side of the VPN connection. | `string` | `"0.0.0.0/0"` | no | | [vpn\_connection\_static\_routes\_destinations](#input\_vpn\_connection\_static\_routes\_destinations) | List of CIDR blocks to be used as destination for static routes. Routes to destinations will be propagated to the route tables defined in `route_table_ids` | `list(string)` | `[]` | no | | [vpn\_connection\_static\_routes\_only](#input\_vpn\_connection\_static\_routes\_only) | If set to `true`, the VPN connection will use static routes exclusively. Static routes must be used for devices that don't support BGP | `bool` | `false` | no | +| [vpn\_connection\_tunnel1\_cloudwatch\_log\_enabled](#input\_vpn\_connection\_tunnel1\_cloudwatch\_log\_enabled) | Enable or disable VPN tunnel logging feature for the tunnel | `bool` | `false` | no | +| [vpn\_connection\_tunnel1\_cloudwatch\_log\_output\_format](#input\_vpn\_connection\_tunnel1\_cloudwatch\_log\_output\_format) | Set log format for the tunnel. Default format is json. Possible values are: json and text | `string` | `"json"` | no | | [vpn\_connection\_tunnel1\_dpd\_timeout\_action](#input\_vpn\_connection\_tunnel1\_dpd\_timeout\_action) | The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart. | `string` | `"clear"` | no | | [vpn\_connection\_tunnel1\_ike\_versions](#input\_vpn\_connection\_tunnel1\_ike\_versions) | The IKE versions that are permitted for the first VPN tunnel. Valid values are ikev1 \| ikev2. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel1\_inside\_cidr](#input\_vpn\_connection\_tunnel1\_inside\_cidr) | The CIDR block of the inside IP addresses for the first VPN tunnel | `string` | `null` | no | @@ -77,6 +81,8 @@ | [vpn\_connection\_tunnel1\_phase2\_integrity\_algorithms](#input\_vpn\_connection\_tunnel1\_phase2\_integrity\_algorithms) | One or more integrity algorithms that are permitted for the first VPN tunnel for phase 2 IKE negotiations. Valid values are SHA1 \| SHA2-256 \| SHA2-384 \| SHA2-512. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel1\_preshared\_key](#input\_vpn\_connection\_tunnel1\_preshared\_key) | The preshared key of the first VPN tunnel. The preshared key must be between 8 and 64 characters in length and cannot start with zero. Allowed characters are alphanumeric characters, periods(.) and underscores(\_) | `string` | `null` | no | | [vpn\_connection\_tunnel1\_startup\_action](#input\_vpn\_connection\_tunnel1\_startup\_action) | The action to take when the establishing the tunnel for the first VPN connection. By default, your customer gateway device must initiate the IKE negotiation and bring up the tunnel. Specify start for AWS to initiate the IKE negotiation. Valid values are add \| start. | `string` | `"add"` | no | +| [vpn\_connection\_tunnel2\_cloudwatch\_log\_enabled](#input\_vpn\_connection\_tunnel2\_cloudwatch\_log\_enabled) | Enable or disable VPN tunnel logging feature for the tunnel | `bool` | `false` | no | +| [vpn\_connection\_tunnel2\_cloudwatch\_log\_output\_format](#input\_vpn\_connection\_tunnel2\_cloudwatch\_log\_output\_format) | Set log format for the tunnel. Default format is json. Possible values are: json and text | `string` | `"json"` | no | | [vpn\_connection\_tunnel2\_dpd\_timeout\_action](#input\_vpn\_connection\_tunnel2\_dpd\_timeout\_action) | The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear \| none \| restart. | `string` | `"clear"` | no | | [vpn\_connection\_tunnel2\_ike\_versions](#input\_vpn\_connection\_tunnel2\_ike\_versions) | The IKE versions that are permitted for the second VPN tunnel. Valid values are ikev1 \| ikev2. | `list(string)` | `[]` | no | | [vpn\_connection\_tunnel2\_inside\_cidr](#input\_vpn\_connection\_tunnel2\_inside\_cidr) | The CIDR block of the inside IP addresses for the second VPN tunnel | `string` | `null` | no | diff --git a/main.tf b/main.tf index 5d9b7da..06b9abe 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,7 @@ locals { enabled = module.this.enabled + logs_enabled = local.enabled && (var.vpn_connection_tunnel1_cloudwatch_log_enabled || var.vpn_connection_tunnel2_cloudwatch_log_enabled) transit_gateway_enabled = local.enabled && var.transit_gateway_enabled transit_gateway_attachment_id = join("", aws_vpn_connection.default[*].transit_gateway_attachment_id) @@ -26,6 +27,17 @@ resource "aws_customer_gateway" "default" { tags = module.this.tags } +module "logs" { + source = "cloudposse/cloudwatch-logs/aws" + version = "0.6.8" + enabled = local.logs_enabled + iam_role_enabled = false + retention_in_days = var.vpn_connection_log_retention_in_days + + context = module.this.context +} + + # https://www.terraform.io/docs/providers/aws/r/vpn_connection.html resource "aws_vpn_connection" "default" { count = local.enabled ? 1 : 0 @@ -50,6 +62,14 @@ resource "aws_vpn_connection" "default" { tunnel1_phase1_integrity_algorithms = var.vpn_connection_tunnel1_phase1_integrity_algorithms tunnel1_phase2_integrity_algorithms = var.vpn_connection_tunnel1_phase2_integrity_algorithms + tunnel1_log_options { + cloudwatch_log_options { + log_enabled = var.vpn_connection_tunnel1_cloudwatch_log_enabled + log_group_arn = var.vpn_connection_tunnel1_cloudwatch_log_enabled ? module.logs.log_group_arn : null + log_output_format = var.vpn_connection_tunnel1_cloudwatch_log_enabled ? var.vpn_connection_tunnel1_cloudwatch_log_output_format : null + } + } + tunnel2_dpd_timeout_action = var.vpn_connection_tunnel2_dpd_timeout_action tunnel2_ike_versions = var.vpn_connection_tunnel2_ike_versions tunnel2_inside_cidr = var.vpn_connection_tunnel2_inside_cidr @@ -63,6 +83,14 @@ resource "aws_vpn_connection" "default" { tunnel2_phase1_integrity_algorithms = var.vpn_connection_tunnel2_phase1_integrity_algorithms tunnel2_phase2_integrity_algorithms = var.vpn_connection_tunnel2_phase2_integrity_algorithms + tunnel2_log_options { + cloudwatch_log_options { + log_enabled = var.vpn_connection_tunnel2_cloudwatch_log_enabled + log_group_arn = var.vpn_connection_tunnel2_cloudwatch_log_enabled ? module.logs.log_group_arn : null + log_output_format = var.vpn_connection_tunnel2_cloudwatch_log_enabled ? var.vpn_connection_tunnel2_cloudwatch_log_output_format : null + } + } + tags = module.this.tags } diff --git a/variables.tf b/variables.tf index c5c3ca1..2060e31 100644 --- a/variables.tf +++ b/variables.tf @@ -50,6 +50,12 @@ variable "vpn_connection_remote_ipv4_network_cidr" { default = "0.0.0.0/0" } +variable "vpn_connection_log_retention_in_days" { + type = number + description = "Specifies the number of days you want to retain log events." + default = 30 +} + variable "vpn_connection_tunnel1_dpd_timeout_action" { type = string description = "The action to take after DPD timeout occurs for the first VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear | none | restart." @@ -116,6 +122,18 @@ variable "vpn_connection_tunnel1_startup_action" { default = "add" } +variable "vpn_connection_tunnel1_cloudwatch_log_enabled" { + type = bool + description = "Enable or disable VPN tunnel logging feature for the tunnel" + default = false +} + +variable "vpn_connection_tunnel1_cloudwatch_log_output_format" { + type = string + description = "Set log format for the tunnel. Default format is json. Possible values are: json and text" + default = "json" +} + variable "vpn_connection_tunnel2_dpd_timeout_action" { type = string description = "The action to take after DPD timeout occurs for the second VPN tunnel. Specify restart to restart the IKE initiation. Specify clear to end the IKE session. Valid values are clear | none | restart." @@ -182,6 +200,18 @@ variable "vpn_connection_tunnel2_startup_action" { default = "add" } +variable "vpn_connection_tunnel2_cloudwatch_log_enabled" { + type = bool + description = "Enable or disable VPN tunnel logging feature for the tunnel" + default = false +} + +variable "vpn_connection_tunnel2_cloudwatch_log_output_format" { + type = string + description = "Set log format for the tunnel. Default format is json. Possible values are: json and text" + default = "json" +} + variable "existing_transit_gateway_id" { type = string default = ""