오늘은 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을 사용해서 해보려 했지만, 발생하는 에러가 모듈 자체에서 나는 부분들이 있어서 해결하기 힘들다 생각해 사용하지 않았다.