Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
backend "s3" {
bucket = "cloudfence-management-state"
key = "inspector-delegation/organizations.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "s3-management-lock"
}
}
26 changes: 26 additions & 0 deletions management-team-account/inspector-delegation/organizations/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

}

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

provider "aws" {
alias = "operation"
region = "ap-northeast-2"
}

data "aws_caller_identity" "operation" {
provider = aws.operation
}

resource "aws_inspector2_delegated_admin_account" "this" {
account_id = data.aws_caller_identity.operation.account_id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
backend "s3" {
bucket = "cloudfence-operation-state"
key = "runtime-verification/eventbridge.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
encrypt = true
}
}
51 changes: 51 additions & 0 deletions operation-team-account/runtime-verification/eventbridge/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

}

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

data "terraform_remote_state" "lambda" {
backend = "s3"
config = {
bucket = "cloudfence-operation-state"
key = "runtime-verification/lambda.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
}
}

resource "aws_cloudwatch_event_rule" "inspector_event_rule" {
name = "inspector-event-rule"
description = "Event rule for AWS Inspector findings"

event_pattern = jsonencode({
source = ["aws.inspector2"],
detail-type = ["Inspector2 Finding"],
detail = {
finding = {
severity = ["HIGH", "CRITICAL"],
}
}
})
}

resource "aws_cloudwatch_event_target" "inspector_event_target" {
rule = aws_cloudwatch_event_rule.inspector_event_rule.name
arn = data.terraform_remote_state.lambda.outputs.lambda_function_arn
}

resource "aws_lambda_permission" "inspector_event_permission" {
statement_id = "AllowExecutionFromEventBridge"
action = "lambda:InvokeFunction"
function_name = data.terraform_remote_state.lambda.outputs.lambda_function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.inspector_event_rule.arn
}
9 changes: 9 additions & 0 deletions operation-team-account/runtime-verification/iam/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
backend "s3" {
bucket = "cloudfence-operation-state"
key = "runtime-verification/iam.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
encrypt = true
}
}
33 changes: 33 additions & 0 deletions operation-team-account/runtime-verification/iam/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

}

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

resource "aws_iam_role" "lambda_exec_role" {
name = "${var.project_name}-inspector-lambda-exec-role"

assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}

resource "aws_iam_role_policy_attachment" "lambda_logs" {
role = aws_iam_role.lambda_exec_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
4 changes: 4 additions & 0 deletions operation-team-account/runtime-verification/iam/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "lambda_exec_role_arn" {
description = "The ARN of the IAM role for the Lambda function"
value = aws_iam_role.lambda_exec_role.arn
}
5 changes: 5 additions & 0 deletions operation-team-account/runtime-verification/iam/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "project_name" {
description = "The name of the project"
type = string
default = "cloudfence"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
backend "s3" {
bucket = "cloudfence-operation-state"
key = "runtime-verification/inspector.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
encrypt = true
}
}
33 changes: 33 additions & 0 deletions operation-team-account/runtime-verification/inspector/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

}

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

provider "aws" {
alias = "prod"
region = "ap-northeast-2"
}

data "aws_caller_identity" "prod" {
provider = aws.prod
}

data "aws_caller_identity" "current" {}

resource "aws_inspector2_enabler" "this" {
account_ids = [data.aws_caller_identity.current.account_id]
resource_types = ["EC2"]
}

resource "aws_inspector2_delegated_admin_account" "prod_account" {
account_id = data.aws_caller_identity.prod.account_id
}
9 changes: 9 additions & 0 deletions operation-team-account/runtime-verification/lambda/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
backend "s3" {
bucket = "cloudfence-operation-state"
key = "runtime-verification/lambda.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
encrypt = true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import json
import os
import urllib.request

SLACK_WEBHOOK_URL = os.environ.get('SLACK_WEBHOOK_URL', '')

def lambda_handler(event, context):
print(json.dumps(event)) # 디버깅을 위해 전체 이벤트를 로그로 남깁니다.

# Inspector 이벤트에서 필요한 정보 추출
finding = event.get('detail', {})
title = finding.get('title', 'N/A')
severity = finding.get('severity', 'N/A')

resources = finding.get('resources', [{}])
resource_id = resources[0].get('id', 'N/A')

region = event.get('region', 'N/A')
finding_arn = finding.get('findingArn', '')
console_url = f"https://{region}.console.aws.amazon.com/inspector/v2/findings/details?finding-arn={finding_arn}" if finding_arn else "#"

# 슬랙 메시지 구성
slack_message = {
"text": f"*New High-Severity Inspector Finding*",
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": f"{severity}: {title}" } },
{ "type": "section", "text": { "type": "mrkdwn", "text": f"*Affected Resource:*\n```{resource_id}```" } },
{ "type": "actions", "elements": [{ "type": "button", "text": { "type": "plain_text", "text": "View Finding Details" }, "url": console_url, "style": "primary" }] }
]
}

if not SLACK_WEBHOOK_URL:
print("Slack Webhook URL is not set.")
return {'statusCode': 500}

req = urllib.request.Request(SLACK_WEBHOOK_URL, data=json.dumps(slack_message).encode('utf-8'), headers={'Content-Type': 'application/json'})

try:
with urllib.request.urlopen(req) as response:
print(f"Message posted to Slack, status: {response.status}")
except urllib.error.HTTPError as e:
print(f"Error posting to Slack: {e.code} {e.reason}")

return {'statusCode': 200}
Binary file not shown.
40 changes: 40 additions & 0 deletions operation-team-account/runtime-verification/lambda/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

}

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

data "terraform_remote_state" "iam" {
backend = "s3"
config = {
bucket = "cloudfence-operation-state"
key = "runtime-verification/iam.tfstate"
region = "ap-northeast-2"
dynamodb_table = "s3-operation-lock"
}
}

# 이 Lambda 함수는 단순 알림 기능만 수행하므로 X-Ray 옵션을 제외
#tfsec:ignore:aws-lambda-enable-tracing
resource "aws_lambda_function" "inspector_slack_notification" {
function_name = "inspector_slack_notification"
role = data.terraform_remote_state.iam.outputs.lambda_exec_role_arn
handler = "index.lambda_handler"
runtime = "python3.9"

environment {
variables = {
SLACK_WEBHOOK_URL = var.slack_webhook_url
}
}
filename = "lambda_function_payload.zip"
source_code_hash = filebase64sha256("lambda_function_payload.zip")
}
9 changes: 9 additions & 0 deletions operation-team-account/runtime-verification/lambda/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "lambda_function_arn" {
description = "The ARN of the Inspector Slack notification Lambda function"
value = aws_lambda_function.inspector_slack_notification.arn
}

output "lambda_function_name" {
description = "The name of the Inspector Slack notification Lambda function"
value = aws_lambda_function.inspector_slack_notification.function_name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "slack_webhook_url" {
description = "The incoming webhook URL for Slack notifications"
type = string
sensitive = true
}