initial commit
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* # SecretRotationReminder
|
||||
* Deploy lambda function which takes secret rotation event from secretsmanager
|
||||
* and send reminders to users using SNS.
|
||||
* This function can be used by any number of secrets
|
||||
* Secret ARN is obtained from the secretsmanager event
|
||||
*
|
||||
* This function overrides the blueprint function from AWS. Instead of rotating the secret value,
|
||||
* it sends a reminder to user who will manually rotate the secret.
|
||||
*/
|
||||
|
||||
resource "aws_sns_topic" "reminder" {
|
||||
name = "${var.prefix}-SecretRotationReminder"
|
||||
kms_master_key_id = var.sns-cmk-arn
|
||||
}
|
||||
|
||||
resource "aws_sns_topic_subscription" "reminder" {
|
||||
for_each = toset(var.rotation-reminder-recipients)
|
||||
topic_arn = aws_sns_topic.reminder.arn
|
||||
protocol = "email"
|
||||
endpoint = each.value
|
||||
}
|
||||
|
||||
data "archive_file" "payload" {
|
||||
type = "zip"
|
||||
source_file = "${path.module}/rotation_reminder.py"
|
||||
output_path = "payload.zip"
|
||||
}
|
||||
|
||||
data "aws_subnet" "this" {
|
||||
id = var.lambda-subnet-ids[0]
|
||||
}
|
||||
|
||||
resource "aws_security_group" "rotation-reminder" {
|
||||
name = "${var.prefix}-SecretRotationReminder"
|
||||
description = "Allow access to VPC endpoint"
|
||||
vpc_id = data.aws_subnet.this.vpc_id
|
||||
|
||||
egress {
|
||||
description = "Access to VPC endpoints"
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lambda_function" "rotation-reminder" {
|
||||
function_name = "${var.prefix}-SecretRotationReminder"
|
||||
description = "Sends secret rotation reminder"
|
||||
role = aws_iam_role.lambda.arn
|
||||
handler = "rotation_reminder.lambda_handler"
|
||||
filename = data.archive_file.payload.output_path
|
||||
source_code_hash = data.archive_file.payload.output_base64sha256
|
||||
runtime = "python3.13"
|
||||
timeout = 180
|
||||
vpc_config {
|
||||
subnet_ids = var.lambda-subnet-ids
|
||||
security_group_ids = [aws_security_group.rotation-reminder.id]
|
||||
}
|
||||
|
||||
environment {
|
||||
variables = {
|
||||
SNS_TOPIC_ARN = aws_sns_topic.reminder.arn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lambda_permission" "rotation-reminder" {
|
||||
statement_id = "SecretRotationReminderPermission"
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = aws_lambda_function.rotation-reminder.function_name
|
||||
principal = "secretsmanager.amazonaws.com"
|
||||
# this function should be allowed to send reminders for all secrets # source_arn = module.mock-secret.secret_arn
|
||||
}
|
||||
|
||||
|
||||
resource "aws_cloudwatch_log_group" "rotation-reminder" {
|
||||
name = "/aws/lambda/whk1-bea-icc-obk-SecretRotationReminder"
|
||||
retention_in_days = 400 # intentionally set to longer than 1 year as rotation may happen yearly
|
||||
kms_key_id = var.logs-cmk-arn
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "lambda" {
|
||||
name = "${var.prefix}-SecretRotationReminderFunctionRole"
|
||||
assume_role_policy = data.aws_iam_policy_document.assume_role.json
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "lambda" {
|
||||
for_each = { for k, v in [
|
||||
"arn:aws:iam::aws:policy/AWSLambdaExecute",
|
||||
aws_iam_policy.lambda.arn
|
||||
] : k => v }
|
||||
role = aws_iam_role.lambda.name
|
||||
policy_arn = each.value
|
||||
}
|
||||
|
||||
resource "aws_iam_policy" "lambda" {
|
||||
name_prefix = "SecretRotationPolicy"
|
||||
policy = jsonencode(
|
||||
{
|
||||
"Version" : "2012-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "AllowAccessToSecretSnsVpc",
|
||||
"Effect" : "Allow",
|
||||
"Action" : [
|
||||
"SNS:Publish",
|
||||
"secretsmanager:DescribeSecret",
|
||||
"secretsmanager:ListSecretVersionIds",
|
||||
"secretsmanager:UpdateSecretVersionStage",
|
||||
"secretsmanager:GetSecretValue",
|
||||
"secretsmanager:PutSecretValue",
|
||||
"ec2:CreateNetworkInterface",
|
||||
"ec2:DescribeNetworkInterfaces",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DeleteNetworkInterface",
|
||||
"ec2:AssignPrivateIpAddresses",
|
||||
"ec2:UnassignPrivateIpAddresses",
|
||||
"ec2:DescribeSecurityGroups",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DescribeVpcs",
|
||||
"ec2:GetSecurityGroupsForVpc"
|
||||
],
|
||||
"Resource" : "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "assume_role" {
|
||||
statement {
|
||||
effect = "Allow"
|
||||
|
||||
principals {
|
||||
type = "Service"
|
||||
identifiers = ["lambda.amazonaws.com"]
|
||||
}
|
||||
|
||||
actions = ["sts:AssumeRole"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user