Untitled

오늘은 IaC 구현이다.

# main

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}

provider "aws" {
  region = "ap-northeast-2"
} 
# budgets

resource "aws_budgets_budget" "FinalProject_team9" {
  name              = "FinalProject_team9_budget"
  budget_type       = "COST"
  limit_amount      = "0"
  limit_unit        = "USD"
  time_period_end   = "2023-06-30_00:00"
  time_period_start = "2023-06-01_00:00"
  time_unit         = "MONTHLY"

  cost_filter {
    name = "Service"
    values = [
      "Amazon Elastic Compute Cloud - Compute",
    ]
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"
    subscriber_email_addresses = ["<subscriber_emai>"]
  }
}
# CloudWatch log group

resource "aws_cloudwatch_log_group" "securityhub_logs" {
    name = "securityhub_logs"

}
# EventBridge

resource "aws_cloudwatch_event_rule" "securityhub_cloudwatch_log" {
    name            = "securityhub_cloudwatch_log"
    event_pattern   = jsonencode({
        "source" : ["aws.securityhub"], "detail": { "findings": { "ProductName": [{ "exists": true }], "Severity": { "Label": ["CRITICAL", "HIGH", "MEDIUM"]} } }
    })
}

resource "aws_cloudwatch_event_target" "securityhub_logs" {
    rule = aws_cloudwatch_event_rule.securityhub_cloudwatch_log.name
    arn  = aws_cloudwatch_log_group.securityhub_logs.arn
}
# Guardduty

resource "aws_guardduty_detector" "team9_guardduty" {
    enable = true

        datasources {
        s3_logs {
            enable = true
        }
        kubernetes {
            audit_logs {
                enable = false
            }
        }
        malware_protection {
            scan_ec2_instance_with_findings {
                ebs_volumes {
                enable = false
                }
            }
        }
    }
}
# Inspector

resource "aws_inspector2_enabler" "team9_inspector" {
  account_ids    = ["123456789123"]
  resource_types = ["ECR", "LAMBDA"]
}
# Securityhub

resource "aws_securityhub_account" "team9_securityhub" {}
# Lambda

resource "aws_iam_role" "iam_for_SlackEmail_lambda" {
    name               = "iam_for_SlackEmail_lambda"
    assume_role_policy = data.aws_iam_policy_document.SlackEmail_lambda_role.json
}

data "aws_iam_policy_document" "SlackEmail_lambda_role" {
    statement {
        effect = "Allow"

        principals {
            type        = "Service"
            identifiers = ["lambda.amazonaws.com"]
        }

        actions = ["sts:AssumeRole"]
    }
}

resource "aws_iam_role_policy_attachment" "iam_for_SlackEmail_lambda_attachments" {
    role       = aws_iam_role.iam_for_SlackEmail_lambda.name

    policy_arn = "arn:aws:iam::aws:policy/CloudWatchFullAccess"
}

resource "aws_iam_role_policy_attachment" "iam_for_SlackEmail_lambda_attachments_2" {
    role       = aws_iam_role.iam_for_SlackEmail_lambda.name

    policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}

resource "aws_iam_role_policy_attachment" "iam_for_SlackEmail_lambda_attachments_3" {
    role       = aws_iam_role.iam_for_SlackEmail_lambda.name

    policy_arn = "arn:aws:iam::aws:policy/CloudWatchEventsFullAccess"
}

resource "aws_iam_policy" "lambda_send_email_policy" {
  name        = "lambda_send_email_policy"
  description = "Policy for Lambda to send emails"
  policy      = data.aws_iam_policy_document.AllowLambdaToSendEmail.json
}

resource "aws_iam_role_policy_attachment" "iam_for_SlackEmail_lambda_attachments_4" {
    role       = aws_iam_role.iam_for_SlackEmail_lambda.name
    policy_arn = aws_iam_policy.lambda_send_email_policy.arn
}

data "aws_iam_policy_document" "AllowLambdaToSendEmail" {
  statement {
    effect = "Allow"
    actions = [
      "ses:SendEmail",
      "ses:SendRawEmail",
    ]
    resources = ["*"]
  }
  
  statement {
    effect = "Allow"
    actions = [
      "ses:SendEmail",
      "ses:SendRawEmail",
    ]
    resources = ["arn:aws:ses:ap-northeast-2:123456789123:identity/<Email>"]
  }
}

resource "aws_lambda_function" "SlackEmail_lambda" {
    filename      = "./lambda_function/SlackEmail-lambda.zip"

    function_name = "SlackEmail_lambda"

    handler       = "SlackEmail-lambda.lambda_handler"
    timeout       = "3"
    role          = aws_iam_role.iam_for_SlackEmail_lambda.arn
    runtime       = "python3.10"

    layers        = ["arn:aws:lambda:ap-northeast-2:123456789123:layer:python_request_layer:12"]

    environment {
        variables = {
            RECIPIENT_EMAIL     = "<RECIPIENT_EMAIL>"
            RECIPIENT_EMAILS    = "<RECIPIENT_EMAILS>"
            SENDER_EMAIL        = "<SENDER_EMAIL>"
            SLACK_URL           = "<SLACK_URL>"
        }
    }
}

resource "aws_lambda_permission" "logging" {
    action        = "lambda:InvokeFunction"
    function_name = aws_lambda_function.SlackEmail_lambda.function_name
    principal     = "logs.ap-northeast-2.amazonaws.com"
    source_arn    = "${aws_cloudwatch_log_group.securityhub_logs.arn}:*"
}

resource "aws_cloudwatch_log_subscription_filter" "logging" {
    depends_on      = [aws_lambda_permission.logging]
    destination_arn = aws_lambda_function.SlackEmail_lambda.arn
    filter_pattern  = ""
    log_group_name  = aws_cloudwatch_log_group.securityhub_logs.name
    name            = "logging_securityhub_logs"
}

inspector, guardduty, securityhub, eventbridge, cloudwatch log group, lamda를 terraform으로 구현했다.

먼저는 terraform module을 사용해서 해보려 했지만, 발생하는 에러가 모듈 자체에서 나는 부분들이 있어서 해결하기 힘들다 생각해 사용하지 않았다.