diff --git a/infrastructure/account/fhir_api_perf_alerts_slack_chatbot.tf b/infrastructure/account/fhir_api_perf_alerts_slack_chatbot.tf new file mode 100644 index 0000000000..88fe488df1 --- /dev/null +++ b/infrastructure/account/fhir_api_perf_alerts_slack_chatbot.tf @@ -0,0 +1,24 @@ +resource "aws_chatbot_slack_channel_configuration" "fhir_api_perf_alerts" { + configuration_name = "${var.environment}-fhir-api-perf-alerts-slack-channel-config" + iam_role_arn = aws_iam_role.fhir_api_perf_alerts_chatbot.arn + slack_channel_id = var.environment == "prod" ? "C0B11MJPQ6A" : "C0B1GKZ5S4R" + slack_team_id = "TJ00QR03U" + sns_topic_arns = [aws_sns_topic.fhir_api_perf_alerts.arn] +} + +resource "aws_iam_role" "fhir_api_perf_alerts_chatbot" { + name = "${var.environment}-fhir-api-perf-alerts-chatbot-channel-role" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Sid = "AssumeChatbotRole" + Principal = { + Service = "chatbot.amazonaws.com" + } + }, + ] + }) +} diff --git a/infrastructure/account/fhir_api_perf_alerts_sns_topic.tf b/infrastructure/account/fhir_api_perf_alerts_sns_topic.tf new file mode 100644 index 0000000000..00fcda4576 --- /dev/null +++ b/infrastructure/account/fhir_api_perf_alerts_sns_topic.tf @@ -0,0 +1,22 @@ +resource "aws_sns_topic" "fhir_api_perf_alerts" { + name = "${var.environment}-fhir-api-perf-alerts" + kms_master_key_id = aws_kms_key.error_alerts_sns_encryption_key.arn +} + +resource "aws_sns_topic_policy" "fhir_api_perf_alerts_topic_policy" { + arn = aws_sns_topic.fhir_api_perf_alerts.arn + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Sid = "AllowCloudWatchToPublish", + Effect = "Allow", + Principal = { + Service = "cloudwatch.amazonaws.com" + }, + Action = "SNS:Publish", + Resource = aws_sns_topic.fhir_api_perf_alerts.arn + } + ] + }) +} diff --git a/infrastructure/account/kms.tf b/infrastructure/account/kms.tf index 21e5e2a78e..563c7bdc72 100644 --- a/infrastructure/account/kms.tf +++ b/infrastructure/account/kms.tf @@ -225,3 +225,9 @@ resource "aws_kms_alias" "fhir_api_errors_sns_encryption_key" { name = "alias/${var.environment}-fhir-api-errors-imms-sns-encryption" target_key_id = aws_kms_key.error_alerts_sns_encryption_key.key_id } + +resource "aws_kms_alias" "fhir_api_perf_alerts_sns_encryption_key" { + name = "alias/${var.environment}-fhir-api-perf-alerts-imms-sns-encryption" + target_key_id = aws_kms_key.error_alerts_sns_encryption_key.key_id +} + diff --git a/infrastructure/account/shield_protection.tf b/infrastructure/account/shield_protection.tf index 0809c97d08..a7a6770830 100644 --- a/infrastructure/account/shield_protection.tf +++ b/infrastructure/account/shield_protection.tf @@ -34,6 +34,10 @@ locals { } } +# Topic to publish alerts to when alarm is triggered +data "aws_sns_topic" "fhir_api_perf_alerts" { + name = "${var.environment}-fhir-api-perf-alerts" +} # Create Metric Alarms for each of those resources resource "aws_cloudwatch_metric_alarm" "ddos_protection_regional" { @@ -41,6 +45,7 @@ resource "aws_cloudwatch_metric_alarm" "ddos_protection_regional" { alarm_name = "imms-${var.environment}-shield_ddos_${each.key}" alarm_description = "Alarm when Shield detects DDoS on ${each.key}" + alarm_actions = [data.aws_sns_topic.fhir_api_perf_alerts.arn] namespace = "AWS/DDoSProtection" metric_name = "DDoSDetected" diff --git a/infrastructure/instance/modules/lambda/lambda.tf b/infrastructure/instance/modules/lambda/lambda.tf index 9714614c04..ed95054a1e 100644 --- a/infrastructure/instance/modules/lambda/lambda.tf +++ b/infrastructure/instance/modules/lambda/lambda.tf @@ -18,24 +18,28 @@ module "lambda_function_container_image" { # A JWT encode took 7 seconds at default memory size of 128 and 0.8 seconds at 1024. # 2048 gets it down to around 0.5 but since Lambda is charged at GB * ms then it costs more for minimal benefit. - memory_size = 1024 + memory_size = var.memory_size environment_variables = var.environment_variables image_config_command = ["${var.function_name}_handler.${var.function_name}_handler"] } -resource "aws_cloudwatch_metric_alarm" "memory_alarm" { - alarm_name = "${var.short_prefix}_${var.function_name} memory alarm" - comparison_operator = "GreaterThanOrEqualToThreshold" - evaluation_periods = 1 - metric_name = aws_cloudwatch_log_metric_filter.max_memory_used_metric.metric_transformation[0].name - namespace = aws_cloudwatch_log_metric_filter.max_memory_used_metric.metric_transformation[0].namespace - period = 600 - statistic = "Maximum" - threshold = 256 - alarm_description = "This metric monitors Lambda memory usage" - insufficient_data_actions = [] +data "aws_sns_topic" "fhir_api_perf_alerts" { + name = "${var.environment}-fhir-api-perf-alerts" +} +resource "aws_cloudwatch_metric_alarm" "memory_alarm" { + alarm_name = "${var.short_prefix}_${var.function_name} memory alarm" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = 1 + metric_name = aws_cloudwatch_log_metric_filter.max_memory_used_metric.metric_transformation[0].name + namespace = aws_cloudwatch_log_metric_filter.max_memory_used_metric.metric_transformation[0].namespace + period = 600 + statistic = "Maximum" + threshold = var.memory_size * 0.85 # Alarm threshold set at 85% of memory size + alarm_description = "This metric monitors Lambda memory usage" + alarm_actions = [data.aws_sns_topic.fhir_api_perf_alerts.arn] + treat_missing_data = "notBreaching" } resource "aws_cloudwatch_log_metric_filter" "max_memory_used_metric" { diff --git a/infrastructure/instance/modules/lambda/variables.tf b/infrastructure/instance/modules/lambda/variables.tf index 60369e6b4e..c92917d241 100644 --- a/infrastructure/instance/modules/lambda/variables.tf +++ b/infrastructure/instance/modules/lambda/variables.tf @@ -41,4 +41,10 @@ variable "vpc_subnet_ids" { variable "environment" { description = "The deployment environment (e.g., dev, int, internal-qa, prod)" type = string +} + +variable "memory_size" { + description = "The memory size allocated to the lambda" + type = number + default = 1024 } \ No newline at end of file