Skip to content

Commit

Permalink
Merge pull request #9061 from ministryofjustice/CC-3020/aws-certifica…
Browse files Browse the repository at this point in the history
…tes-expiry-date-check

CC-3020: Lambda function for monitoring certificates.
  • Loading branch information
mmgovuk authored Dec 16, 2024
2 parents b9fbae5 + b94eb04 commit 075651a
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 4 deletions.
16 changes: 12 additions & 4 deletions terraform/environments/ccms-ebs/application_variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@
"s3_lifecycle_days_transition_current_glacier": 365,
"s3_lifecycle_days_transition_current_standard": 90,
"s3_lifecycle_days_transition_noncurrent_glacier": 365,
"s3_lifecycle_days_transition_noncurrent_standard": 90
"s3_lifecycle_days_transition_noncurrent_standard": 90,
"certificate_expiry_days": 333,
"certificate_monitor_email": "[email protected]"
},
"test": {
"short_env": "tst",
Expand Down Expand Up @@ -198,7 +200,9 @@
"s3_lifecycle_days_transition_current_glacier": 365,
"s3_lifecycle_days_transition_current_standard": 90,
"s3_lifecycle_days_transition_noncurrent_glacier": 365,
"s3_lifecycle_days_transition_noncurrent_standard": 90
"s3_lifecycle_days_transition_noncurrent_standard": 90,
"certificate_expiry_days": 45,
"certificate_monitor_email": "[email protected]"
},
"preproduction": {
"short_env": "prep",
Expand Down Expand Up @@ -296,7 +300,9 @@
"s3_lifecycle_days_transition_current_glacier": 365,
"s3_lifecycle_days_transition_current_standard": 90,
"s3_lifecycle_days_transition_noncurrent_glacier": 365,
"s3_lifecycle_days_transition_noncurrent_standard": 90
"s3_lifecycle_days_transition_noncurrent_standard": 90,
"certificate_expiry_days": 45,
"certificate_monitor_email": "[email protected]"
},
"production": {
"short_env": "prod",
Expand Down Expand Up @@ -396,7 +402,9 @@
"s3_lifecycle_days_transition_current_glacier": 365,
"s3_lifecycle_days_transition_current_standard": 90,
"s3_lifecycle_days_transition_noncurrent_glacier": 365,
"s3_lifecycle_days_transition_noncurrent_standard": 90
"s3_lifecycle_days_transition_noncurrent_standard": 90,
"certificate_expiry_days": 60,
"certificate_monitor_email": "[email protected]"
}
},
"webgate_ebs": {
Expand Down
118 changes: 118 additions & 0 deletions terraform/environments/ccms-ebs/ccms-lambda-certificate-monitor.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
resource "aws_iam_role" "lambda_certificate_monitor_role" {
name = "${local.application_name}-${local.environment}-acm_certificate_monitor_role"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
tags = merge(local.tags, {
Name = "${local.application_name}-${local.environment}-certificate-monitor"
})
}

resource "aws_iam_role_policy" "lambda_policy" {
name = "${local.application_name}-${local.environment}-acm_certificate_monitor_policy"
role = aws_iam_role.lambda_certificate_monitor_role.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
},
{
Effect = "Allow"
Action = [
"sns:Publish"
]
Resource = [aws_sns_topic.certificate_expiration_alerts.arn]
}
]
})
}

resource "aws_sns_topic" "certificate_expiration_alerts" {
name = "${local.application_name}-${local.environment}-acm-certificate-alerts"
tags = merge(local.tags, {
Name = "${local.application_name}-${local.environment}-certificate-monitor"
})
}

resource "aws_sns_topic_subscription" "email" {
topic_arn = aws_sns_topic.certificate_expiration_alerts.arn
protocol = "email"
endpoint = local.application_data.accounts[local.environment].certificate_monitor_email
}

resource "aws_lambda_function" "certificate_monitor" {
filename = "./lambda/certificate_monitor.zip"
source_code_hash = filebase64sha256("./lambda/certificate_monitor.zip")
function_name = "${local.application_name}-${local.environment}-certificate-monitor"
role = aws_iam_role.lambda_certificate_monitor_role.arn
handler = "lambda_function.lambda_handler"
runtime = "python3.13"
timeout = 30
publish = true

environment {
variables = {
EXPIRY_DAYS = local.application_data.accounts[local.environment].certificate_expiry_days
SNS_TOPIC_ARN = aws_sns_topic.certificate_expiration_alerts.arn
}
}
tags = merge(local.tags, {
Name = "${local.application_name}-${local.environment}-certificate-monitor"
})
}

resource "aws_cloudwatch_event_rule" "acm_events" {
name = "${local.application_name}-${local.environment}-acm-certificate-events"
description = "Capture ACM certificate events"

event_pattern = jsonencode({
source = ["aws.acm"]
detail-type = [
"ACM Certificate Approaching Expiration",
"ACM Certificate Expired"
]
})
tags = merge(local.tags, {
Name = "${local.application_name}-${local.environment}-certificate-monitor"
})
}

resource "aws_cloudwatch_event_target" "lambda_certificate_monitor" {
rule = aws_cloudwatch_event_rule.acm_events.name
target_id = "SendToLambda"
arn = aws_lambda_function.certificate_monitor.arn
}

resource "aws_lambda_permission" "allow_eventbridge" {
statement_id = "AllowEventBridgeInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.certificate_monitor.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.acm_events.arn
}

output "sns_topic_arn" {
description = "ARN of the SNS topic for certificate alerts"
value = aws_sns_topic.certificate_expiration_alerts.arn
}

output "lambda_function_arn" {
description = "ARN of the Lambda function"
value = aws_lambda_function.certificate_monitor.arn
}
Binary file not shown.

0 comments on commit 075651a

Please sign in to comment.