diff --git a/infrastructure/terraform/modules/lambda/README.md b/infrastructure/terraform/modules/lambda/README.md index 72d7673c..d84520a7 100644 --- a/infrastructure/terraform/modules/lambda/README.md +++ b/infrastructure/terraform/modules/lambda/README.md @@ -31,6 +31,7 @@ output "processor_lambda_error_rate_alarm_arn" { | Name | Description | Type | Default | Required | | ---- | ----------- | ---- | ------- | :------: | | [application\_log\_level](#input\_application\_log\_level) | The detail level of the logs the application sends to CloudWatch | `string` | `"INFO"` | no | +| [architecture](#input\_architecture) | The architecture of the Lambda function (e.g., x86\_64 or arm64 Graviton) | `string` | `"arm64"` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the tfscaffold component | `string` | n/a | yes | | [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | @@ -66,12 +67,13 @@ output "processor_lambda_error_rate_alarm_arn" { | [lambda\_error\_rate\_alarm\_config](#input\_lambda\_error\_rate\_alarm\_config) | Object of optional CloudWatch alarm settings for the Lambda error rate alarm |
object({
comparison_operator = optional(string, "GreaterThanThreshold")
evaluation_periods = optional(number, 1)
period = optional(number, 300)
threshold = optional(number, 1)
actions_enabled = optional(bool, true)
treat_missing_data = optional(string, "notBreaching")
})
| `{}` | no | | [lambda\_throttles\_alarm\_config](#input\_lambda\_throttles\_alarm\_config) | Object of optional CloudWatch alarm settings for the Lambda throttles alarm |
object({
comparison_operator = optional(string, "GreaterThanThreshold")
evaluation_periods = optional(number, 1)
period = optional(number, 300)
statistic = optional(string, "Sum")
threshold = optional(number, 0)
actions_enabled = optional(bool, true)
treat_missing_data = optional(string, "notBreaching")
})
| `{}` | no | | [layers](#input\_layers) | Lambda layer arns to include | `list(any)` | `[]` | no | -| [log\_destination\_arn](#input\_log\_destination\_arn) | Destination ARN to use for the log subscription filter | `string` | `""` | no | +| [log\_destination\_arn](#input\_log\_destination\_arn) | Destination ARN to use for the log subscription filter to send logs to Splunk | `string` | `""` | no | | [log\_level](#input\_log\_level) | The log level to be used in lambda functions within the component. Any log with a lower severity than the configured value will not be logged: https://docs.python.org/3/library/logging.html#levels | `string` | `"INFO"` | no | | [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The retention period in days for the Cloudwatch Logs events generated by the lambda function | `number` | n/a | yes | | [log\_subscription\_lambda\_create\_permission](#input\_log\_subscription\_lambda\_create\_permission) | Whether to create a permission for the log forwarder. Set to false if using a generic one. | `bool` | `true` | no | | [log\_subscription\_role\_arn](#input\_log\_subscription\_role\_arn) | The ARN of the IAM role to use for the log subscription filter | `string` | `""` | no | | [memory](#input\_memory) | The amount of memory to apply to the created Lambda | `number` | n/a | yes | +| [odin\_log\_destination\_arn](#input\_odin\_log\_destination\_arn) | Destination ARN to use for the log subscription filter to send logs to Odin | `string` | `""` | no | | [package\_type](#input\_package\_type) | Lambda package type: Zip or Image | `string` | `"Zip"` | no | | [permission\_statements](#input\_permission\_statements) | Statements giving an external source permission to invoke the Lambda function |
list(object({
action = optional(string)
principal = string
source_arn = optional(string)
source_account = optional(string)
statement_id = string
}))
| `[]` | no | | [project](#input\_project) | The name of the tfscaffold project | `string` | n/a | yes | diff --git a/infrastructure/terraform/modules/lambda/cloudwatch_log_subscription_filter_firehose_odin.tf b/infrastructure/terraform/modules/lambda/cloudwatch_log_subscription_filter_firehose_odin.tf new file mode 100644 index 00000000..6d1a30fe --- /dev/null +++ b/infrastructure/terraform/modules/lambda/cloudwatch_log_subscription_filter_firehose_odin.tf @@ -0,0 +1,8 @@ +resource "aws_cloudwatch_log_subscription_filter" "firehose_odin" { + count = var.send_to_firehose && var.odin_log_destination_arn != "" ? 1 : 0 + name = trim(replace(aws_cloudwatch_log_group.main.name, "/", "-"), "-") + log_group_name = aws_cloudwatch_log_group.main.name + filter_pattern = var.filter_pattern + destination_arn = var.odin_log_destination_arn + role_arn = var.log_subscription_role_arn +} diff --git a/infrastructure/terraform/modules/lambda/lambda_function.tf b/infrastructure/terraform/modules/lambda/lambda_function.tf index fa7ec9e1..9ec91d65 100644 --- a/infrastructure/terraform/modules/lambda/lambda_function.tf +++ b/infrastructure/terraform/modules/lambda/lambda_function.tf @@ -8,6 +8,7 @@ resource "aws_lambda_function" "main" { publish = true memory_size = var.memory timeout = var.timeout + architectures = [var.architecture] reserved_concurrent_executions = var.reserved_concurrent_executions diff --git a/infrastructure/terraform/modules/lambda/variables.tf b/infrastructure/terraform/modules/lambda/variables.tf index d7af209d..89fad354 100644 --- a/infrastructure/terraform/modules/lambda/variables.tf +++ b/infrastructure/terraform/modules/lambda/variables.tf @@ -100,6 +100,12 @@ variable "runtime" { } } +variable "architecture" { + type = string + description = "The architecture of the Lambda function (e.g., x86_64 or arm64 Graviton)" + default = "arm64" +} + variable "package_type" { type = string description = "Lambda package type: Zip or Image" @@ -390,7 +396,13 @@ variable "filter_pattern" { variable "log_destination_arn" { type = string - description = "Destination ARN to use for the log subscription filter" + description = "Destination ARN to use for the log subscription filter to send logs to Splunk" + default = "" +} + +variable "odin_log_destination_arn" { + type = string + description = "Destination ARN to use for the log subscription filter to send logs to Odin" default = "" } diff --git a/infrastructure/terraform/modules/obs-datasource/README.md b/infrastructure/terraform/modules/obs-datasource/README.md index fd7817e8..742dd077 100644 --- a/infrastructure/terraform/modules/obs-datasource/README.md +++ b/infrastructure/terraform/modules/obs-datasource/README.md @@ -5,32 +5,15 @@ ## Requirements -| Name | Version | -| ---- | ------- | -| [terraform](#requirement\_terraform) | >= 1.9.0 | +No requirements. ## Inputs -| Name | Description | Type | Default | Required | -| ---- | ----------- | ---- | ------- | :------: | -| [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | -| [component](#input\_component) | The name of the terraformscaffold component calling this module | `string` | n/a | yes | -| [default\_tags](#input\_default\_tags) | Default tag map for application to all taggable resources in the module | `map(string)` | `{}` | no | -| [environment](#input\_environment) | The name of the terraformscaffold environment the module is called for | `string` | n/a | yes | -| [log\_group\_configuration](#input\_log\_group\_configuration) | Configuration for filtering log groups in the link configuration. |
object({
filter = string
})
| `null` | no | -| [metric\_configuration](#input\_metric\_configuration) | Configuration for filtering metrics in the link configuration. |
object({
filter = string
})
| `null` | no | -| [name](#input\_name) | A unique name to distinguish this module invocation from others within the same CSI scope | `string` | n/a | yes | -| [oam\_sink\_id](#input\_oam\_sink\_id) | The ID of the Cloudwatch OAM sink in the appropriate observability account. | `string` | `""` | no | -| [observability\_account\_id](#input\_observability\_account\_id) | The Observability Account ID that needs access | `string` | n/a | yes | -| [project](#input\_project) | The name of the terraformscaffold project calling the module | `string` | n/a | yes | -| [region](#input\_region) | The AWS Region | `string` | n/a | yes | -| [resource\_types](#input\_resource\_types) | The resource types to include in the OAM link. | `list(string)` |
[
"AWS::CloudWatch::Metric",
"AWS::Logs::LogGroup"
]
| no | +No inputs. ## Outputs -| Name | Description | -| ---- | ----------- | -| [log\_subscription\_role\_arn](#output\_log\_subscription\_role\_arn) | The ARN of the log subscription IAM role. | +No outputs. diff --git a/infrastructure/terraform/modules/obs-datasource/iam_role_log_subscription_role.tf b/infrastructure/terraform/modules/obs-datasource/iam_role_log_subscription_role.tf deleted file mode 100644 index 698fa19c..00000000 --- a/infrastructure/terraform/modules/obs-datasource/iam_role_log_subscription_role.tf +++ /dev/null @@ -1,42 +0,0 @@ -resource "aws_iam_role" "log_subscription_role" { - name = "${local.csi}-log-subscription-role" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Principal = { - Service = "logs.${var.region}.amazonaws.com" - } - Action = "sts:AssumeRole" - } - ] - }) -} - -resource "aws_iam_policy" "log_subscription_policy" { - name = "${local.csi}-log-subscription-policy" - description = "Policy for log subscription to send logs to the destination" - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "logs:PutSubscriptionFilter", - "logs:DescribeLogGroups", - "logs:DescribeLogStreams", - "logs:PutLogEvents" - ] - Resource = "arn:aws:logs:${var.region}:${var.observability_account_id}:destination:nhs-notify-main-acct-firehose-logs" - } - ] - }) -} - -resource "aws_iam_role_policy_attachment" "log_subscription_policy_attachment" { - role = aws_iam_role.log_subscription_role.name - policy_arn = aws_iam_policy.log_subscription_policy.arn -} diff --git a/infrastructure/terraform/modules/obs-datasource/locals.tf b/infrastructure/terraform/modules/obs-datasource/locals.tf deleted file mode 100644 index f3bdfa03..00000000 --- a/infrastructure/terraform/modules/obs-datasource/locals.tf +++ /dev/null @@ -1,23 +0,0 @@ -locals { - module = "obs-datasource" - - csi = replace( - format( - "%s-%s-%s-%s", - var.project, - var.environment, - var.component, - var.name, - ), - "_", - "", - ) - default_tags = merge( - var.default_tags, - { - Module = local.module - Name = local.csi - }, - ) - -} diff --git a/infrastructure/terraform/modules/obs-datasource/oam_link_cross_account_obs.tf b/infrastructure/terraform/modules/obs-datasource/oam_link_cross_account_obs.tf deleted file mode 100644 index b0c062fd..00000000 --- a/infrastructure/terraform/modules/obs-datasource/oam_link_cross_account_obs.tf +++ /dev/null @@ -1,65 +0,0 @@ -resource "aws_oam_link" "cross_account_obs" { - label_template = "$AccountName" - resource_types = var.resource_types - sink_identifier = "arn:aws:oam:${var.region}:${var.observability_account_id}:sink/${var.oam_sink_id}" - tags = var.default_tags - - link_configuration { - dynamic "log_group_configuration" { - for_each = var.log_group_configuration != null ? [var.log_group_configuration] : [] - content { - filter = log_group_configuration.value.filter - } - } - - dynamic "metric_configuration" { - for_each = var.metric_configuration != null ? [var.metric_configuration] : [] - content { - filter = metric_configuration.value.filter - } - } - } -} - -data "aws_iam_policy" "cloudwatch_read_only" { - name = "CloudWatchReadOnlyAccess" -} - -data "aws_iam_policy" "cloudwatch_automatic_dashboards" { - name = "CloudWatchAutomaticDashboardsAccess" -} - -data "aws_iam_policy" "aws_xray_read_only" { - name = "AWSXrayReadOnlyAccess" -} - -data "aws_iam_policy_document" "cross_account_obs_assume_role_policy" { - statement { - effect = "Allow" - principals { - type = "AWS" - identifiers = [var.observability_account_id] - } - actions = ["sts:AssumeRole"] - } -} - -resource "aws_iam_role" "cross_account_obs_role" { - name = "CloudWatch-CrossAccountSharingRole" - assume_role_policy = data.aws_iam_policy_document.cross_account_obs_assume_role_policy.json -} - -resource "aws_iam_role_policy_attachment" "cloudwatch_read_only_attachment" { - policy_arn = data.aws_iam_policy.cloudwatch_read_only.arn - role = aws_iam_role.cross_account_obs_role.name -} - -resource "aws_iam_role_policy_attachment" "cloudwatch_automatic_dashboards_attachment" { - policy_arn = data.aws_iam_policy.cloudwatch_automatic_dashboards.arn - role = aws_iam_role.cross_account_obs_role.name -} - -resource "aws_iam_role_policy_attachment" "aws_xray_read_only_attachment" { - policy_arn = data.aws_iam_policy.aws_xray_read_only.arn - role = aws_iam_role.cross_account_obs_role.name -} diff --git a/infrastructure/terraform/modules/obs-datasource/outputs.tf b/infrastructure/terraform/modules/obs-datasource/outputs.tf deleted file mode 100644 index b82647fa..00000000 --- a/infrastructure/terraform/modules/obs-datasource/outputs.tf +++ /dev/null @@ -1,4 +0,0 @@ -output "log_subscription_role_arn" { - description = "The ARN of the log subscription IAM role." - value = aws_iam_role.log_subscription_role.arn -} diff --git a/infrastructure/terraform/modules/obs-datasource/variables.tf b/infrastructure/terraform/modules/obs-datasource/variables.tf deleted file mode 100644 index 568fdb50..00000000 --- a/infrastructure/terraform/modules/obs-datasource/variables.tf +++ /dev/null @@ -1,82 +0,0 @@ -## -# Basic inherited variables for terraformscaffold modules -## - -variable "project" { - type = string - description = "The name of the terraformscaffold project calling the module" -} - -variable "environment" { - type = string - description = "The name of the terraformscaffold environment the module is called for" -} - -variable "component" { - type = string - description = "The name of the terraformscaffold component calling this module" -} - -variable "aws_account_id" { - type = string - description = "The AWS Account ID (numeric)" -} - -## -# Variable specific to the module -## - -# We presume this will always be specified. The default of {} will cause an error if a valid map is not specified. -# If we ever want to define this but allow it to not be specified, then we must provide a default tag keypair will be applied -# as the true default. In any other case default_tags should be removed from the module. -variable "default_tags" { - type = map(string) - description = "Default tag map for application to all taggable resources in the module" - default = {} -} - -variable "region" { - type = string - description = "The AWS Region" -} - -variable "name" { - type = string - description = "A unique name to distinguish this module invocation from others within the same CSI scope" -} - -variable "oam_sink_id" { - description = "The ID of the Cloudwatch OAM sink in the appropriate observability account." - type = string - default = "" -} - -variable "observability_account_id" { - type = string - description = "The Observability Account ID that needs access" -} - -variable "log_group_configuration" { - description = "Configuration for filtering log groups in the link configuration." # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/oam_link#link_configuration-block - type = object({ - filter = string - }) - default = null -} - -variable "metric_configuration" { - description = "Configuration for filtering metrics in the link configuration." # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/oam_link#link_configuration-block - type = object({ - filter = string - }) - default = null -} - -variable "resource_types" { - type = list(string) - description = "The resource types to include in the OAM link." - default = [ - "AWS::CloudWatch::Metric", - "AWS::Logs::LogGroup" - ] -} diff --git a/infrastructure/terraform/modules/obs-datasource/versions.tf b/infrastructure/terraform/modules/obs-datasource/versions.tf deleted file mode 100644 index f8dc86e9..00000000 --- a/infrastructure/terraform/modules/obs-datasource/versions.tf +++ /dev/null @@ -1,9 +0,0 @@ - -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - } - } - required_version = ">= 1.9.0" -}