diff --git a/deployment/terraform/modules/ddb/ddb.tf b/deployment/terraform/modules/ddb/ddb.tf index cea510fa..8b1fc238 100755 --- a/deployment/terraform/modules/ddb/ddb.tf +++ b/deployment/terraform/modules/ddb/ddb.tf @@ -1,11 +1,345 @@ -resource "aws_cloudformation_stack" "hammer_ddb" { - name = "hammer-ddb-creation" +resource "aws_dynamodb_table" "credentials" { - tags = "${var.tags}" + name = "${var.resources-prefix}credentials" + read_capacity = 25 + write_capacity = 2 + hash_key = "service" - parameters { - ResourcesPrefix = "${var.resources-prefix}" + attribute { + name = "service" + type = "S" } - template_url = "https://${var.s3bucket}.s3.amazonaws.com/${aws_s3_bucket_object.ddb-cfn.id}" -} \ No newline at end of file + server_side_encryption { + enabled = true + } +} + +resource "aws_dynamodb_table" "cloudtrails" { + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}cloudtrails" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "insecure-sg-dynamodb-table" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}security-groups-unrestricted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-public-bucket-acl" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}s3-public-bucket-acl" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-public-bucket-policy" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}s3-public-bucket-policy" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "iam-user-keys-rotation" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}iam-user-keys-rotation" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "iam-user-keys-inactive" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}iam-user-keys-inactive" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ebs-volumes-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}ebs-volumes-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ebs-snapshots-public" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}ebs-snapshots-public" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "rds-public-snapshots" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}rds-public-snapshots" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "sqs-public-access" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}sqs-public-access" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}s3-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "rds-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}rds-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ec2-public-ami" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}ec2-public-ami" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "api-requests" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}api-requests" + read_capacity = 20 + write_capacity = 4 + hash_key = "request_id" + + attribute { + name = "request_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ecs-privileged-access" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}ecs-privileged-access" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ecs-logging" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resources-prefix}ecs-logging" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} diff --git a/deployment/terraform/modules/identification-nested/identification_nested_template.tf b/deployment/terraform/modules/identification-nested/identification_nested_template.tf new file mode 100644 index 00000000..44a09c40 --- /dev/null +++ b/deployment/terraform/modules/identification-nested/identification_nested_template.tf @@ -0,0 +1,198 @@ +resource "aws_lambda_function" "lambda-initiate" { + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-initiate" + ] + function_name = "${var.InitiateLambdaName}" + + s3_bucket = "${var.SourceS3Bucket}" + s3_key = "${var.SourceIdentification}" + + description = "${var.InitiateLambdaDescription}" + role = "${var.IdentificationIAMRole}" + handler = "${var.InitiateLambdaHandler}" + runtime = "python3.6" + timeout = "300" + memory_size = "128" + + environment { + variables = { + SNS_ARN = "${aws_sns_topic.sns-notiify-lambda-evaluate.arn}" + } + } + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-initiate" { + name = "/aws/lambda/${var.InitiateLambdaName}" + retention_in_days = 7 +} + +resource "aws_cloudwatch_log_subscription_filter" "lambda_initiate_logfilter" { + + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-initiate" + ] + name = "${aws_cloudwatch_log_group.log-group-lambda-initiate.name}" + log_group_name = "${aws_cloudwatch_log_group.log-group-lambda-initiate.name}" + filter_pattern = "[level != START && level != END && level != DEBUG, ...]" + destination_arn = "${var.LambdaLogsForwarderArn}" +} + +resource "aws_lambda_function" "lambda-evaluate" { + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-evaluate" + ] + function_name = "${var.EvaluateLambdaName}" + + s3_bucket = "${var.SourceS3Bucket}" + s3_key = "${var.SourceIdentification}" + + description = "${var.EvaluateLambdaDescription}" + role = "${var.IdentificationIAMRole}" + handler = "${var.EvaluateLambdaHandler}" + runtime = "python3.6" + timeout = "300" + memory_size = "${var.EvaluateLambdaMemorySize}" + + vpc_config { + subnet_ids = ["${split(",", var.LambdaSubnets)}"] + security_group_ids = ["${split(",", var.LambdaSecurityGroups)}"] + } + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-evaluate" { + name = "/aws/lambda/${var.EvaluateLambdaName}" + retention_in_days = 7 +} + +resource "aws_cloudwatch_log_subscription_filter" "lambda_evaluate_logfilter" { + + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-evaluate" + ] + name = "${aws_cloudwatch_log_group.log-group-lambda-evaluate.name}" + log_group_name = "${aws_cloudwatch_log_group.log-group-lambda-evaluate.name}" + filter_pattern = "[level != START && level != END && level != DEBUG, ...]" + destination_arn = "${var.LambdaLogsForwarderArn}" +} + +resource "aws_cloudwatch_event_rule" "eventInitiateEvaluation" { + + depends_on = [ + "aws_lambda_function.lambda-initiate" + ] + + name = "${var.EventRuleName}" + description = "${var.EventRuleDescription}" + schedule_expression = "${var.IdentificationCheckRateExpression}" +} + +resource "aws_cloudwatch_event_target" "event-initiate-evaluation" { + depends_on = [ + "aws_cloudwatch_event_rule.eventInitiateEvaluation" + ] + + rule = "${aws_cloudwatch_event_rule.eventInitiateEvaluation.name}" + target_id = "lambda-initiate" + arn = "${aws_lambda_function.lambda-initiate.arn}" +} + +resource "aws_lambda_permission" "allow_cloudwatch_to_call_initiate_lambda" { + depends_on = [ + "aws_lambda_function.lambda-initiate" , "aws_cloudwatch_event_rule.eventInitiateEvaluation" + ] + + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-initiate.function_name}" + principal = "events.amazonaws.com" + source_arn = "${aws_cloudwatch_event_rule.eventInitiateEvaluation.arn}" +} + + +resource "aws_sns_topic" "sns-notiify-lambda-evaluate" { + depends_on = [ + "aws_lambda_function.lambda-evaluate" + ] + + name = "${var.SNSDisplayName}" + display_name = "${var.SNSTopicName}" +} + +resource "aws_sns_topic_subscription" "lambda" { + depends_on = [ + "aws_sns_topic.sns-notiify-lambda-evaluate" + ] + topic_arn = "${aws_sns_topic.sns-notiify-lambda-evaluate.arn}" + protocol = "lambda" + endpoint = "${aws_lambda_function.lambda-evaluate.arn}" +} + +resource "aws_lambda_permission" "with_sns" { + depends_on = [ + "aws_sns_topic_subscription.lambda" + ] + + statement_id = "AllowExecutionFromSNS" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-evaluate.function_name}" + principal = "sns.amazonaws.com" + source_arn = "${aws_sns_topic.sns-notiify-lambda-evaluate.arn}" +} + +resource "aws_cloudwatch_metric_alarm" "alarm-errors-lambda-initiate-evaluation" { + depends_on = [ + "aws_lambda_function.lambda-initiate" + ] + alarm_name = "/${aws_lambda_function.lambda-initiate.function_name}LambdaError" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = "1" + metric_name = "Errors" + namespace = "AWS/Lambda" + period = "3600" + statistic = "Maximum" + threshold = 0 + treat_missing_data = "notBreaching" + + + alarm_actions = [ + "${var.SNSIdentificationErrors}", + ] + + ok_actions = [ + "${var.SNSIdentificationErrors}", + ] + + dimensions { + FunctionName = "${aws_lambda_function.lambda-initiate.function_name}" + } +} + +resource "aws_cloudwatch_metric_alarm" "alarm-errors-lambda-evaluate-evaluation" { + depends_on = [ + "aws_lambda_function.lambda-evaluate" + ] + alarm_name = "/${aws_lambda_function.lambda-evaluate.function_name}LambdaError" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = "1" + metric_name = "Errors" + namespace = "AWS/Lambda" + period = "3600" + statistic = "Maximum" + threshold = 0 + treat_missing_data = "notBreaching" + + + alarm_actions = [ + "${var.SNSIdentificationErrors}", + ] + + ok_actions = [ + "${var.SNSIdentificationErrors}", + ] + + dimensions { + FunctionName = "${aws_lambda_function.lambda-evaluate.function_name}" + } +} \ No newline at end of file diff --git a/deployment/terraform/modules/identification-nested/input.tf b/deployment/terraform/modules/identification-nested/input.tf new file mode 100644 index 00000000..a2ce2a19 --- /dev/null +++ b/deployment/terraform/modules/identification-nested/input.tf @@ -0,0 +1,26 @@ +variable "InitiateLambdaName" {} +variable "SourceS3Bucket" {} +variable "SourceIdentification" {} +variable "InitiateLambdaDescription" {} +variable "IdentificationIAMRole" {} +variable "InitiateLambdaHandler" {} +variable "LambdaLogsForwarderArn" {} +variable "EvaluateLambdaName" {} +variable "EvaluateLambdaDescription" {} +variable "EvaluateLambdaHandler" {} +variable "EvaluateLambdaMemorySize" {} +variable "LambdaSubnets" {} +variable "LambdaSecurityGroups" {} +variable "EventRuleName" {} +variable "EventRuleDescription" {} +variable "IdentificationCheckRateExpression" {} +variable "SNSDisplayName" {} +variable "SNSTopicName" {} +variable "SNSIdentificationErrors" {} +variable "SourceLogsForwarder" {} +variable "SourceBackupDDB" {} + +variable "tags" { + type = "map" + default = {} +} \ No newline at end of file diff --git a/deployment/terraform/modules/identification/identification.tf b/deployment/terraform/modules/identification/identification.tf index e89fbf5b..5e0484a5 100755 --- a/deployment/terraform/modules/identification/identification.tf +++ b/deployment/terraform/modules/identification/identification.tf @@ -1,56 +1,571 @@ -resource "aws_cloudformation_stack" "identification" { - name = "hammer-identification-main" +data "aws_caller_identity" "current" {} +data "aws_region" "current" {} + +resource "aws_lambda_function" "lambda-logs-forwarder" { + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-forwarder" + ] + function_name = "${var.resources-prefix}logs-forwarder" + + s3_bucket = "${var.s3bucket}" + s3_key = "${aws_s3_bucket_object.logs-forwarder.id}" + + description = "Lambda function for parsing logs" + role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + handler = "logs_forwarder.lambda_handler" + runtime = "python3.6" + timeout = "300" + memory_size = "256" + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-forwarder" { + name = "/aws/lambda/${var.resources-prefix}logs-forwarder" + retention_in_days = 7 +} + +resource "aws_lambda_function" "lambda-backup-ddb" { + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-backup-ddb" + ] + function_name = "${var.resources-prefix}backup-ddb" + + s3_bucket = "${var.s3bucket}" + s3_key = "${aws_s3_bucket_object.ddb-tables-backup.id}" + + description = "Lambda function for parsing logs" + role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + handler = "ddb_tables_backup.lambda_handler" + runtime = "python3.6" + timeout = "300" + memory_size = "256" + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-backup-ddb" { + name = "/aws/lambda/${var.resources-prefix}backup-ddb" + retention_in_days = 7 +} + + +resource "aws_cloudwatch_log_subscription_filter" "subscription-filter-lambda-backup-ddb" { + + depends_on = [ + "aws_cloudwatch_log_group.log-group-lambda-backup-ddb", + "aws_lambda_permission.allow-cloudwatch-to-call-lambda-logs-forwarder", + "aws_lambda_function.lambda-logs-forwarder" + ] + name = "${aws_cloudwatch_log_group.log-group-lambda-backup-ddb.name}" + log_group_name = "${aws_cloudwatch_log_group.log-group-lambda-backup-ddb.name}" + filter_pattern = "[level != START && level != END && level != DEBUG, ...]" + destination_arn = "${aws_lambda_function.lambda-logs-forwarder.arn}" +} + +resource "aws_cloudwatch_event_rule" "event-backup-ddb" { + depends_on = [ - "aws_s3_bucket_object.identification-cfn", - "aws_s3_bucket_object.identification-nested-cfn", - "aws_s3_bucket_object.logs-forwarder", - "aws_s3_bucket_object.ddb-tables-backup", - "aws_s3_bucket_object.sg-issues-identification", - "aws_s3_bucket_object.s3-acl-issues-identification", - "aws_s3_bucket_object.s3-policy-issues-identification", - "aws_s3_bucket_object.iam-keyrotation-issues-identification", - "aws_s3_bucket_object.iam-user-inactive-keys-identification", - "aws_s3_bucket_object.cloudtrails-issues-identification", - "aws_s3_bucket_object.ebs-unencrypted-volume-identification", - "aws_s3_bucket_object.ebs-public-snapshots-identification", - "aws_s3_bucket_object.ami-public-access-issues-identification", - "aws_s3_bucket_object.sqs-public-policy-identification", - "aws_s3_bucket_object.s3-unencrypted-bucket-issues-identification", - "aws_s3_bucket_object.rds-unencrypted-instance-identification", - "aws_s3_bucket_object.ecs-privileged-access-issues-identification", - "aws_s3_bucket_object.ecs-logging-issues-identification", - "aws_s3_bucket_object.ecs-external-image-source-issues-identification" - ] - - tags = "${var.tags}" - - parameters { - SourceS3Bucket = "${var.s3bucket}" - NestedStackTemplate = "https://${var.s3bucket}.s3.amazonaws.com/${aws_s3_bucket_object.identification-nested-cfn.id}" - ResourcesPrefix = "${var.resources-prefix}" - IdentificationIAMRole = "${var.identificationIAMRole}" - IdentificationCheckRateExpression = "${var.identificationCheckRateExpression}" - LambdaSubnets = "${var.lambdaSubnets}" - LambdaSecurityGroups = "${var.lambdaSecurityGroups}" - SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}", - SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}", - SourceIdentificationSG = "${aws_s3_bucket_object.sg-issues-identification.id}" - SourceIdentificationS3ACL = "${aws_s3_bucket_object.s3-acl-issues-identification.id}" - SourceIdentificationS3Policy = "${aws_s3_bucket_object.s3-policy-issues-identification.id}" - SourceIdentificationIAMUserKeysRotation = "${aws_s3_bucket_object.iam-keyrotation-issues-identification.id}" - SourceIdentificationIAMUserInactiveKeys = "${aws_s3_bucket_object.iam-user-inactive-keys-identification.id}" - SourceIdentificationCloudTrails = "${aws_s3_bucket_object.cloudtrails-issues-identification.id}" - SourceIdentificationEBSVolumes = "${aws_s3_bucket_object.ebs-unencrypted-volume-identification.id}" - SourceIdentificationEBSSnapshots = "${aws_s3_bucket_object.ebs-public-snapshots-identification.id}" - SourceIdentificationRDSSnapshots = "${aws_s3_bucket_object.rds-public-snapshots-identification.id}" - SourceIdentificationAMIPublicAccess = "${aws_s3_bucket_object.ami-public-access-issues-identification.id}" - SourceIdentificationSQSPublicPolicy = "${aws_s3_bucket_object.sqs-public-policy-identification.id}" - SourceIdentificationS3Encryption = "${aws_s3_bucket_object.s3-unencrypted-bucket-issues-identification.id}" - SourceIdentificationRDSEncryption = "${aws_s3_bucket_object.rds-unencrypted-instance-identification.id}" - SourceIdentificationECSPrivilegedAccess = "${aws_s3_bucket_object.ecs-privileged-access-issues-identification.id}" - SourceIdentificationECSLogging = "${aws_s3_bucket_object.ecs-logging-issues-identification.id}" - SourceIdentificationECSExternalImageSource = "${aws_s3_bucket_object.ecs-external-image-source-issues-identification.id}" - } - - template_url = "https://${var.s3bucket}.s3.amazonaws.com/${aws_s3_bucket_object.identification-cfn.id}" -} \ No newline at end of file + "aws_lambda_function.lambda-backup-ddb" + ] + + name = "${var.resources-prefix}BackupDDB" + description = "Hammer ScheduledRule for DDB tables backup" + schedule_expression = "rate(1 day)" +} + +resource "aws_cloudwatch_event_target" "check-backup-ddb" { + depends_on = [ + "aws_cloudwatch_event_rule.event-backup-ddb" + ] + + rule = "${aws_cloudwatch_event_rule.event-backup-ddb.name}" + target_id = "lambda-backup-ddb" + arn = "${aws_lambda_function.lambda-backup-ddb.arn}" +} + +resource "aws_lambda_permission" "allow-cloudwatch-to-call-lambda-logs-forwarder" { + depends_on = [ + "aws_lambda_function.lambda-logs-forwarder" + ] + + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-logs-forwarder.function_name}" + principal = "logs.${data.aws_region.current.name}.amazonaws.com" + source_arn = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:*" + +} + +resource "aws_lambda_permission" "allow-cloudwatch-to-call-lambda-backup-ddb" { + depends_on = [ + "aws_lambda_function.lambda-backup-ddb", "aws_cloudwatch_event_rule.event-backup-ddb" + ] + + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-backup-ddb.function_name}" + principal = "events.amazonaws.com" + source_arn = "${aws_cloudwatch_event_rule.event-backup-ddb.arn}" + +} + + +resource "aws_sns_topic" "sns-identification-errors" { + name = "${var.resources-prefix}identification-errors" +} + +resource "aws_sns_topic_subscription" "lambda" { + depends_on = [ + "aws_sns_topic.sns-identification-errors", "aws_lambda_function.lambda-logs-forwarder" + ] + topic_arn = "${aws_sns_topic.sns-identification-errors.arn}" + protocol = "lambda" + endpoint = "${aws_lambda_function.lambda-logs-forwarder.arn}" +} + +resource "aws_lambda_permission" "with_sns" { + depends_on = [ + "aws_sns_topic.sns-identification-errors", "aws_lambda_function.lambda-logs-forwarder" + ] + + statement_id = "AllowExecutionFromSNS" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-logs-forwarder.function_name}" + principal = "sns.amazonaws.com" + source_arn = "${aws_sns_topic.sns-identification-errors.arn}" +} + +resource "aws_cloudwatch_metric_alarm" "alarm-errors-lambda-backup-ddb" { + depends_on = [ + "aws_lambda_function.lambda-backup-ddb", "aws_sns_topic.sns-identification-errors" + ] + alarm_name = "/${aws_lambda_function.lambda-backup-ddb.function_name}LambdaError" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = "1" + metric_name = "Errors" + namespace = "AWS/Lambda" + period = "3600" + statistic = "Maximum" + threshold = 0 + treat_missing_data = "notBreaching" + + + alarm_actions = [ + "${aws_sns_topic.sns-identification-errors.arn}" + ] + + ok_actions = [ + "${aws_sns_topic.sns-identification-errors.arn}" + ] + + dimensions { + FunctionName = "${aws_lambda_function.lambda-backup-ddb.arn}" + } +} + +module "hammer_id_nested_sg" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(35, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.sg-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateSecurityGroupLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify bad security groups" + InitiateLambdaHandler = "initiate_to_desc_sec_grps.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifySecurityGroupLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe security groups unrestricted access." + EvaluateLambdaHandler = "describe_sec_grps_unrestricted_access.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 512 + EventRuleName = "${var.resources-prefix}InitiateEvaluationSG" + EventRuleDescription = "Hammer ScheduledRule to initiate Security Groups evaluations" + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameSecurityGroups}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameSecurityGroups}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_cloudtrails" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(15, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.cloudtrails-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateCloudTrailsLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate identification of CloudTrail issues." + InitiateLambdaHandler = "initiate_to_desc_cloudtrails.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyCloudTrailsLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function for describe of CloudTrail issues." + EvaluateLambdaHandler = "describe_cloudtrails.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 256 + EventRuleName = "${var.resources-prefix}InitiateEvaluationCloudTrails" + EventRuleDescription = "Hammer ScheduledRule to initiate cloud trails evaluations" + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameCloudTrails}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameCloudTrails}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + + +module "hammer_id_nested_s3_acl" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.s3-acl-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateS3ACLLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public s3 buckets." + InitiateLambdaHandler = "initiate_to_desc_s3_bucket_acl.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyS3ACLLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public s3 buckets." + EvaluateLambdaHandler = "describe_s3_bucket_acl.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationS3ACL" + EventRuleDescription = "Hammer ScheduledRule to initiate S3 ACL evaluations" + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameS3ACL}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameS3ACL}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_s3_policy" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.s3-policy-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateS3PolicyLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public s3 buckets." + InitiateLambdaHandler = "initiate_to_desc_s3_bucket_policy.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyS3PolicyLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public s3 buckets." + EvaluateLambdaHandler = "describe_s3_bucket_policy.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationS3Policy" + EventRuleDescription = "Hammer ScheduledRule to initiate S3 Policy evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameS3Policy}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameS3Policy}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + + +module "hammer_id_nested_iam_user_keys_rotation" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.iam-keyrotation-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateIAMUserKeysRotationLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify IAM user keys which to be rotated." + InitiateLambdaHandler = "initiate_to_desc_iam_users_key_rotation.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyIAMUserKeysRotationLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe IAM user keys to be rotated." + EvaluateLambdaHandler = "describe_iam_key_rotation.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationIAMUserKeysRotation" + EventRuleDescription = "Hammer ScheduledRule to initiate IAM user keys rotation evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameIAMUserKeysRotation}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameIAMUserKeysRotation}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_iam_user_inactive_keys" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.iam-user-inactive-keys-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateIAMUserInactiveKeysLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify IAM user keys which last used." + InitiateLambdaHandler = "initiate_to_desc_iam_access_keys.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyIAMUserInactiveKeysLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe IAM user keys last used." + EvaluateLambdaHandler = "describe_iam_accesskey_details.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationIAMUserInactiveKeys" + EventRuleDescription = "Hammer ScheduledRule to initiate IAM user inactive keys evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameIAMUserInactiveKeys}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameIAMUserInactiveKeys}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + + +module "hammer_id_nested_unencrypted_ebs_volumes" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.ebs-unencrypted-volume-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateEBSVolumesLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify unencrypted EBS volumes." + InitiateLambdaHandler = "initiate_to_desc_ebs_unencrypted_volumes.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyEBSVolumesLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe unencrypted ebs volumes." + EvaluateLambdaHandler = "describe_ebs_unencrypted_volumes.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationEBSVolumes" + EventRuleDescription = "Hammer ScheduledRule to initiate EBS volumes evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameEBSVolumes}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameEBSVolumes}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_public_ebs_snapshots" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.ebs-public-snapshots-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateEBSSnapshotsLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public EBS snapshots." + InitiateLambdaHandler = "initiate_to_desc_ebs_public_snapshots.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyEBSSnapshotsLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public ebs snapshots." + EvaluateLambdaHandler = "describe_ebs_public_snapshots.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationEBSSnapshots" + EventRuleDescription = "Hammer ScheduledRule to initiate ebs snapshots evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameEBSSnapshots}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameEBSSnapshots}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_public_rds_snapshots" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.rds-public-snapshots-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateRDSSnapshotsLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public RDS snapshots." + InitiateLambdaHandler = "initiate_to_desc_rds_public_snapshots.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyRDSSnapshotsLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public RDS snapshots." + EvaluateLambdaHandler = "describe_rds_public_snapshots.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationRDSSnapshots" + EventRuleDescription = "Hammer ScheduledRule to initiate RDS snapshots evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameRDSSnapshots}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameRDSSnapshots}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_sqs_public_policy" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.sqs-public-policy-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateSQSPublicPolicyLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public SQS queues." + InitiateLambdaHandler = "initiate_to_desc_sqs_public_policy.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifySQSPublicPolicyLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public SQS queues." + EvaluateLambdaHandler = "describe_sqs_public_policy.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationSQSPublicPolicy" + EventRuleDescription = "Hammer ScheduledRule to initiate SQS queue evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameSQSPublicPolicy}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameSQSPublicPolicy}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_s3_encryption" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.s3-unencrypted-bucket-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateS3EncryptionLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify S3 unencrypted buckets." + InitiateLambdaHandler = "initiate_to_desc_s3_encryption.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyS3EncryptionLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe un-encrypted S3 buckets." + EvaluateLambdaHandler = "describe_s3_encryption.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationS3Encryption" + EventRuleDescription = "Hammer ScheduledRule to initiate S3 encryption evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameS3Encryption}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameS3Encryption}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_rds_encryption" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.rds-unencrypted-instance-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateRDSEncryptionLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify unencrypted RDS instances." + InitiateLambdaHandler = "initiate_to_desc_rds_instance_encryption.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyRDSEncryptionLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe un-encrypted RDS instances." + EvaluateLambdaHandler = "describe_rds_instance_encryption.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationRDSEncryption" + EventRuleDescription = "Hammer ScheduledRule to initiate RDS encryption evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameRDSEncryption}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameRDSEncryption}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_ami_public_access" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.ami-public-access-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateAMIPublicAccessLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify public AMI access issues." + InitiateLambdaHandler = "initiate_to_desc_public_ami_issues.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyAMIPublicAccessLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe public AMI issues." + EvaluateLambdaHandler = "describe_public_ami_issues.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationAmiPublicAccess" + EventRuleDescription = "Hammer ScheduledRule to initiate Ami public access evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameAMIPublicAccess}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameAMIPublicAccess}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_ecs_privileged_access" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.ecs-privileged-access-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateECSPrivilegedAccessLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify ECS privileged access issues." + InitiateLambdaHandler = "initiate_to_desc_ecs_privileged_access_issues.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyECSPrivilegedAccessLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe ECS privileged access issues." + EvaluateLambdaHandler = "describe_ecs_privileged_access_issues.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationECSPrivilegedAccess" + EventRuleDescription = "Hammer ScheduledRule to initiate ECS privileged access evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameECSPrivilegedAccess}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameECSPrivilegedAccess}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} + +module "hammer_id_nested_ecs_logging" { + + source = "../identification-nested" + tags = "${var.tags}" + IdentificationIAMRole = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.resources-prefix}${var.identificationIAMRole}" + IdentificationCheckRateExpression = "cron(10, ${var.identificationCheckRateExpression})" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}" + SourceS3Bucket = "${var.s3bucket}" + SourceIdentification = "${aws_s3_bucket_object.ecs-logging-issues-identification.id}" + InitiateLambdaName = "${var.resources-prefix}${var.initiateECSLoggingLambdaFunctionName}" + InitiateLambdaDescription = "Lambda function for initiate to identify ECS logging enabled or not." + InitiateLambdaHandler = "initiate_to_desc_ecs_logging_issues.lambda_handler" + EvaluateLambdaName = "${var.resources-prefix}${var.identifyECSLoggingLambdaFunctionName}" + EvaluateLambdaDescription = "Lambda function to describe ECS logging enabled or not." + EvaluateLambdaHandler = "describe_ecs_logging_issues.lambda_handler" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}" + LambdaLogsForwarderArn = "${aws_lambda_function.lambda-logs-forwarder.arn}" + EvaluateLambdaMemorySize = 128 + EventRuleName = "${var.resources-prefix}InitiateEvaluationECSLogging" + EventRuleDescription = "Hammer ScheduledRule to initiate ECS logging evaluations." + SNSDisplayName = "${var.resources-prefix}${var.snsDisplayNameECSLogging}" + SNSTopicName = "${var.resources-prefix}${var.snsTopicNameECSLogging}" + SNSIdentificationErrors = "${aws_sns_topic.sns-identification-errors.arn}" +} diff --git a/deployment/terraform/modules/identification/output.tf b/deployment/terraform/modules/identification/output.tf index 87c62149..7d640a68 100755 --- a/deployment/terraform/modules/identification/output.tf +++ b/deployment/terraform/modules/identification/output.tf @@ -1,3 +1,3 @@ output "lambdaLogsForwarderArn" { - value = "${lookup(aws_cloudformation_stack.identification.outputs, "LambdaLogsForwarderArn", "not_present_yet")}" + value = "${aws_lambda_function.lambda-logs-forwarder.arn}" } \ No newline at end of file diff --git a/deployment/terraform/modules/identification/variables.tf b/deployment/terraform/modules/identification/variables.tf new file mode 100644 index 00000000..1d1a09f5 --- /dev/null +++ b/deployment/terraform/modules/identification/variables.tf @@ -0,0 +1,239 @@ +variable "snsDisplayNameSecurityGroups" { + default = "describe-security-groups-sns" +} + +variable "snsTopicNameSecurityGroups" { + default = "describe-security-groups-lambda" +} + +variable "snsDisplayNameS3ACL" { + default = "describe-s3-acl-sns" +} + +variable "snsTopicNameS3ACL" { + default = "describe-s3-acl-lambda" +} + +variable "snsDisplayNameCloudTrails" { + default = "describe-cloudtrails-sns" +} + +variable "snsTopicNameCloudTrails" { + default = "describe-cloudtrails-lambda" +} + +variable "snsDisplayNameS3Policy" { + default = "describe-s3-policy-sns" +} + +variable "snsTopicNameS3Policy" { + default = "describe-s3-policy-lambda" +} + +variable "snsDisplayNameIAMUserKeysRotation" { + default = "describe-iam-key-rotation-sns" +} + +variable "snsTopicNameIAMUserKeysRotation" { + default = "describe-iam-key-rotation-lambda" +} + +variable "snsDisplayNameIAMUserInactiveKeys" { + default = "describe-iam-user-inactive-keys-sns" +} + +variable "snsTopicNameIAMUserInactiveKeys" { + default = "describe-iam-user-inactive-keys-lambda" +} + +variable "snsDisplayNameEBSVolumes" { + default = "describe-ebs-volumes-sns" +} + +variable "snsTopicNameEBSVolumes" { + default = "describe-ebs-unencrypted-volumes-lambda" +} + +variable "snsDisplayNameEBSSnapshots" { + default = "describe-ebs-snapshots-sns" +} + +variable "snsTopicNameEBSSnapshots" { + default = "describe-ebs-public-snapshots-lambda" +} + +variable "snsDisplayNameRDSSnapshots" { + default = "describe-rds-snapshots-sns" +} + +variable "snsTopicNameRDSSnapshots" { + default = "describe-rds-public-snapshots-lambda" +} + +variable "snsDisplayNameAMIPublicAccess" { + default = "describe-ami-public-access-sns" +} + +variable "snsTopicNameAMIPublicAccess" { + default = "describe-ami-public-access-lambda" +} + +variable "snsDisplayNameSQSPublicPolicy" { + default = "describe-sqs-public-policy-sns" +} + +variable "snsTopicNameSQSPublicPolicy" { + default = "describe-sqs-public-policy-lambda" +} + +variable "snsDisplayNameS3Encryption" { + default = "describe-s3-encryption-sns" +} + +variable "snsTopicNameS3Encryption" { + default = "describe-s3-encryption-lambda" +} + +variable "snsDisplayNameRDSEncryption" { + default = "describe-rds-encryption-sns" +} + +variable "snsTopicNameRDSEncryption" { + default = "describe-rds-encryption-lambda" +} + +variable "snsDisplayNameECSPrivilegedAccess" { + default = "describe-ecs-privileged-access-sns" +} + +variable "snsTopicNameECSPrivilegedAccess" { + default = "describe-ecs-privileged-access-lambda" +} + +variable "snsDisplayNameECSLogging" { + default = "describe-ecs-logging-sns" +} + +variable "snsTopicNameECSLogging" { + default = "describe-ecs-logging-lambda" +} + +variable "identifySecurityGroupLambdaFunctionName" { + default = "describe-security-groups" +} + +variable "initiateSecurityGroupLambdaFunctionName" { + default = "initiate-security-groups" +} + +variable "identifyS3ACLLambdaFunctionName" { + default = "describe-s3-acl" +} + +variable "initiateS3ACLLambdaFunctionName" { + default = "initiate-s3-acl" +} + +variable "identifyCloudTrailsLambdaFunctionName" { + default = "describe-cloudtrails" +} + +variable "initiateCloudTrailsLambdaFunctionName" { + default = "initiate-cloudtrails" +} + +variable "identifyS3PolicyLambdaFunctionName" { + default = "describe-s3-policy" +} + +variable "initiateS3PolicyLambdaFunctionName" { + default = "initiate-s3-policy" +} + +variable "identifyIAMUserKeysRotationLambdaFunctionName" { + default = "describe-iam-key-ratation" +} + +variable "initiateIAMUserKeysRotationLambdaFunctionName" { + default = "initiate-iam-key-ratation" +} + +variable "initiateAMIPublicAccessLambdaFunctionName" { + default = "initiate-ami-public-access" +} + +variable "identifyAMIPublicAccessLambdaFunctionName" { + default = "describe-ami-public-access" +} + +variable "initiateSQSPublicPolicyLambdaFunctionName" { + default = "initiate-sqs-public-policy" +} + +variable "identifySQSPublicPolicyLambdaFunctionName" { + default = "describe-sqs-public-policy" +} + +variable "initiateRDSSnapshotsLambdaFunctionName" { + default = "initiate-rds-public-snapshots" +} + +variable "identifyRDSSnapshotsLambdaFunctionName" { + default = "describe-rds-public-snapshots" +} + +variable "initiateS3EncryptionLambdaFunctionName" { + default = "initiate-s3-encryption" +} + +variable "identifyS3EncryptionLambdaFunctionName" { + default = "describe-s3-encryption" +} + +variable "initiateRDSEncryptionLambdaFunctionName" { + default = "initiate-rds-encryption" +} + +variable "identifyRDSEncryptionLambdaFunctionName" { + default = "describe-rds-encryption" +} + +variable "initiateECSPrivilegedAccessLambdaFunctionName" { + default = "initiate-ecs-privileged-access" +} + +variable "identifyECSPrivilegedAccessLambdaFunctionName" { + default = "describe-ecs-privileged-access" +} + +variable "initiateECSLoggingLambdaFunctionName" { + default = "initiate-ecs-logging" +} + +variable "identifyECSLoggingLambdaFunctionName" { + default = "describe-ecs-logging" +} + +variable "initiateEBSSnapshotsLambdaFunctionName" { + default = "initiate-ebs-public-snapshots" +} + +variable "identifyEBSSnapshotsLambdaFunctionName" { + default = "describe-ebs-public-snapshots" +} + +variable "initiateEBSVolumesLambdaFunctionName" { + default = "initiate-ebs-unencrypted-volumes" +} + +variable "identifyEBSVolumesLambdaFunctionName" { + default = "describe-ebs-unencrypted-volumes" +} + +variable "initiateIAMUserInactiveKeysLambdaFunctionName" { + default = "initiate-iam-user-inactive-keys" +} + +variable "identifyIAMUserInactiveKeysLambdaFunctionName" { + default = "describe-iam-user-inactive-keys" +} diff --git a/deployment/terraform/tf_templates/ddb/ddb_template.tf b/deployment/terraform/tf_templates/ddb/ddb_template.tf new file mode 100644 index 00000000..f50fb9bf --- /dev/null +++ b/deployment/terraform/tf_templates/ddb/ddb_template.tf @@ -0,0 +1,284 @@ +resource "aws_dynamodb_table" "credentials" { + + name = "${var.resource_prefix}credentials" + read_capacity = 25 + write_capacity = 2 + hash_key = "service" + + attribute { + name = "service" + type = "S" + } + + server_side_encryption { + enabled = true + } +} + +resource "aws_dynamodb_table" "cloudtrails" { + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}cloudtrails" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "insecure-sg-dynamodb-table" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}security-groups-unrestricted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-public-bucket-acl" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}s3-public-bucket-acl" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-public-bucket-policy" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}s3-public-bucket-policy" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "iam-user-keys-rotation" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}iam-user-keys-rotation" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "iam-user-keys-inactive" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}iam-user-keys-inactive" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ebs-volumes-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}ebs-volumes-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "rds-public-snapshots" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}rds-public-snapshots" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "sqs-public-access" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}sqs-public-access" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "s3-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}s3-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "rds-unencrypted" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}rds-unencrypted" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + +resource "aws_dynamodb_table" "ec2-public-ami" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}ec2-public-ami" + read_capacity = 20 + write_capacity = 4 + hash_key = "account_id" + range_key = "issue_id" + + attribute { + name = "account_id" + type = "S" + } + + attribute { + name = "issue_id" + type = "S" + } +} + + +resource "aws_dynamodb_table" "api-requests" { + + depends_on = ["aws_dynamodb_table.credentials" ] + + name = "${var.resource_prefix}api-requests" + read_capacity = 20 + write_capacity = 4 + hash_key = "request_id" + + attribute { + name = "issue_id" + type = "S" + } +} + diff --git a/deployment/terraform/tf_templates/ddb/input.tf b/deployment/terraform/tf_templates/ddb/input.tf new file mode 100644 index 00000000..570dd6c5 --- /dev/null +++ b/deployment/terraform/tf_templates/ddb/input.tf @@ -0,0 +1,6 @@ +variable "resources-prefix" {} + +variable "tags" { + type = "map" + default = {} +} \ No newline at end of file diff --git a/deployment/terraform/tf_templates/identification/identification_template.tf b/deployment/terraform/tf_templates/identification/identification_template.tf new file mode 100644 index 00000000..a5ad0c6d --- /dev/null +++ b/deployment/terraform/tf_templates/identification/identification_template.tf @@ -0,0 +1,198 @@ +data "aws_caller_identity" "current" {} +data "aws_region" "current" {} + +resource "aws_lambda_function" "lambda-logs-forwarder" { + depends_on = [ + aws_cloudwatch_log_group.log-group-lambda-evaluate + ] + function_name = "${var.resources-prefix}logs-forwarder" + + s3_bucket = "${var.s3bucket}" + s3_key = "${aws_s3_bucket_object.logs-forwarder.id}" + + description = "Lambda function for parsing logs" + role = "${var.identificationIAMRole}" + handler = "logs_forwarder.lambda_handler" + runtime = "python3.6" + timeout = "300" + memory_size = "256" + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-evaluate" { + name = "/aws/lambda/${var.resources-prefix}logs-forwarder" + retention_in_days = 7 +} + +resource "aws_lambda_function" "lambda-backup-ddb" { + depends_on = [ + aws_cloudwatch_log_group.log-group-lambda-backup-ddb + ] + function_name = "${var.resources-prefix}backup-ddb" + + s3_bucket = "${var.s3bucket}" + s3_key = "${aws_s3_bucket_object.logs-forwarder.id}" + + description = "Lambda function for parsing logs" + role = "${var.identificationIAMRole}" + handler = "ddb_tables_backup.lambda_handler" + runtime = "python3.6" + timeout = "300" + memory_size = "256" + +} + +resource "aws_cloudwatch_log_group" "log-group-lambda-backup-ddb" { + name = "/aws/lambda/${var.resources-prefix}backup-ddb" + retention_in_days = 7 +} + + +resource "aws_cloudwatch_log_subscription_filter" "subscription-filter-lambda-backup-ddb" { + + depends_on = [ + aws_cloudwatch_log_group.log-group-lambda-backup-ddb, aws_lambda_permission. , + aws_lambda_function.lambda-logs-forwarder + ] + log_group_name = aws_cloudwatch_log_group.log-group-lambda-evaluate.name + filter_pattern = "[level != START && level != END && level != DEBUG, ...]" + destination_arn = aws_lambda_function.lambda-logs-forwarder.arn +} + +resource "aws_cloudwatch_event_rule" "event-backup-ddb" { + + depends_on = [ + aws_lambda_function.lambda-backup-ddb, + ] + + name = "${var.resources-prefix}BackupDDB" + description = "Hammer ScheduledRule for DDB tables backup" + schedule_expression = "rate(1 day)" +} + +resource "aws_cloudwatch_event_target" "check-backup-ddb" { + depends_on = [ + aws_cloudwatch_event_rule.event-backup-ddb, + ] + + rule = "${aws_cloudwatch_event_rule.event-backup-ddb.name}" + target_id = "lambda-backup-ddb" + arn = "${aws_lambda_function.lambda-backup-ddb.arn}" +} + +resource "aws_lambda_permission" "allow-cloudwatch-to-call-lambda-logs-forwarder" { + depends_on = [ + aws_lambda_function.lambda-logs-forwarder + ] + + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-logs-forwarder.function_name}" + principal = "logs.${data.aws_region.current.name}.amazonaws.com" + source_arn = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:*" + +}aws_region + +resource "aws_lambda_permission" "allow-cloudwatch-to-call-lambda-backup-ddb" { + depends_on = [ + aws_lambda_function.lambda-backup-ddb, event-backup-ddb + ] + + statement_id = "AllowExecutionFromCloudWatch" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-backup-ddb.function_name}" + principal = "events.amazonaws.com" + source_arn = "${aws_cloudwatch_event_rule.event-backup-ddb.arn}" + +} + + +resource "aws_sns_topic" "sns-identification-errors" { + depends_on = [ + + name = "${var.resources-prefix}identification-errors" +} + +resource "aws_sns_topic_subscription" "lambda" { + depends_on = [ + aws_sns_topic.sns-identification-errors, aws_lambda_function.lambda-logs-forwarder + ] + topic_arn = "${aws_sns_topic.sns-identification-errors.arn}" + protocol = "lambda" + endpoint = "${aws_lambda_function.lambda-logs-forwarder.arn}" +} + +resource "aws_lambda_permission" "with_sns" { + depends_on = [ + aws_sns_topic.sns-identification-errors, aws_lambda_function.lambda-logs-forwarder + ] + + statement_id = "AllowExecutionFromSNS" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.lambda-logs-forwarder.function_name}" + principal = "sns.amazonaws.com" + source_arn = "${aws_sns_topic.sns-identification-errors.arn}" +} + +resource "aws_cloudwatch_metric_alarm" "alarm-errors-lambda-backup-ddb" { + depends_on = [ + aws_lambda_function.lambda-backup-ddb, aws_sns_topic.sns-identification-errors, + ] + alarm_name = "/${aws_lambda_function.lambda-backup-ddb.function_name}LambdaError" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = "1" + metric_name = "Errors" + namespace = "AWS/Lambda" + period = "3600" + statistic = "Maximum" + threshold = 0 + treat_missing_data = "notBreaching" + + + alarm_actions = [ + "aws_sns_topic.sns-identification-errors.function_name", + ] + + ok_actions = [ + "aws_sns_topic.sns-identification-errors.function_name", + ] + + dimensions { + FunctionName = "${aws_lambda_function.lambda-backup-ddb.arn}" + } +} + + + + +module "hammer_id_nested_sg" { + + depends_on + source = "identification_nested_template.tf" + tags = "${var.tags}" + parameters { + ResourcesPrefix = "${var.resources-prefix}" + IdentificationIAMRole = "${var.identificationIAMRole}" + IdentificationCheckRateExpression = "${var.identificationCheckRateExpression}" + LambdaSubnets = "${var.lambdaSubnets}" + LambdaSecurityGroups = "${var.lambdaSecurityGroups}" + SourceLogsForwarder = "${aws_s3_bucket_object.logs-forwarder.id}", + SourceBackupDDB = "${aws_s3_bucket_object.ddb-tables-backup.id}", + IdentificationLambdaSource = "${aws_s3_bucket_object.sg-issues-identification.id}" + InitiateLambdaName = ${var.initiateSecurityGroupLambdaFunctionName} + SourceS3Bucket = "${var.s3bucket}" + InitiateLambdaDescription = "Lambda function for initiate to identify bad security groups" + InitiateLambdaHandler = "initiate_to_desc_sec_grps.lambda_handler" + SourceIdentificationSG = "${aws_s3_bucket_object.sg-issues-identification.id}" + LambdaLogsForwarderArn = aws_lambda_function.lambda-logs-forwarder.arn + EvaluateLambdaName = ${var.identifySecurityGroupLambdaFunctionName} + EvaluateLambdaDescription = "Lambda function to describe security groups unrestricted access." + EvaluateLambdaHandler = "describe_sec_grps_unrestricted_access.lambda_handler" + EvaluateLambdaMemorySize = 512 + EventRuleName = ${var.resources-prefix}SourceIdentificationSG + EventRuleDescription = "Hammer ScheduledRule to initiate Security Groups evaluations" + SNSDisplayName = ${var.resources-prefix}${var.snsDisplayNameSecurityGroups} + SNSTopicName = ${var.resources-prefix}${var.snsTopicNameSecurityGroups} + SNSIdentificationErrors = aws_sns_topic.sns-identification-errors.name + } +} diff --git a/deployment/terraform/tf_templates/identification/input.tf b/deployment/terraform/tf_templates/identification/input.tf new file mode 100644 index 00000000..570dd6c5 --- /dev/null +++ b/deployment/terraform/tf_templates/identification/input.tf @@ -0,0 +1,6 @@ +variable "resources-prefix" {} + +variable "tags" { + type = "map" + default = {} +} \ No newline at end of file