Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
782e3e0
feat: cloudtrail>s3&eventbridge>lambda>opensearch
3olly Jul 6, 2025
703cfe5
fix: eventbridge, lambda 수정
3olly Jul 6, 2025
3f48cd6
feat: s3_aws_kms_key 추가
3olly Jul 6, 2025
17877d1
fix: kms 권한 수정
3olly Jul 6, 2025
1c314fe
fix: s3 main 권한 및 정책 수정
3olly Jul 6, 2025
485b463
feat: managemenet-s3 접근 허용
3olly Jul 6, 2025
7a6a709
fix: terraform 형식 수정
3olly Jul 6, 2025
5abfe85
fix: s3 main.tf kms 정책 수정사항
3olly Jul 7, 2025
34f9b38
fix: format 수정
3olly Jul 7, 2025
3f9fa65
fix: lambda 폴더 통합
3olly Jul 7, 2025
505b2d7
fix:cloudtrail->s3 로그 전송 성공
3olly Jul 8, 2025
b697303
feat: SSE-KMS 암호화 설정
3olly Jul 8, 2025
c8eb33b
fix: cloudtrail module로 분리
3olly Jul 8, 2025
622836f
fix: backend s3 migration (operation, management)
3olly Jul 8, 2025
350e483
chore: 강화된 s3 bucket&KMS 정책 적용
3olly Jul 8, 2025
36e876f
chore: 강화된 S3 버킷·KMS 정책 적용
3olly Jul 8, 2025
abe80b6
fix: cloudtrail 로깅 멈춤 문제 해결
3olly Jul 9, 2025
88cc060
fix: cloudtrail 로깅 멈춤 문제 해결2
3olly Jul 9, 2025
42a163b
feat: lambda>slack 알림 구현 완료
3olly Jul 10, 2025
f890f8a
fix: lambda 구성 수정
3olly Jul 13, 2025
78e04cc
feat: lambda>opensearch 연결
3olly Jul 15, 2025
ca944da
chore: tfsec 관련 network main.tf 수정
3olly Jul 15, 2025
ed6013a
fix: slack 알림까지 완료. opensearch연결 x
3olly Jul 15, 2025
e95dae1
feat: lambda -> opensearch 전송 로직 추가, 알림 잘 옴
3olly Jul 15, 2025
2b33aed
fix: slack 알림 반복되는 문제 해결
3olly Jul 16, 2025
b154501
refactor: 전체 폴더구조 수정(slack 알림 잘 옴)
3olly Jul 16, 2025
be03d1d
remove: s3 profile 삭제
3olly Jul 16, 2025
977e361
chore: format 수정
3olly Jul 16, 2025
8a5cc45
chore: .gitignor 수정
3olly Jul 16, 2025
6429256
Merge branch 'main' of https://github.com/WHS-DevSecOps-infra/Monitor…
3olly Jul 16, 2025
d545791
fix: network_vpc main.tf 수정(알림 잘 옴)
3olly Jul 17, 2025
270cc5f
chore: tfsec 통과 위한 주석 추가
3olly Jul 17, 2025
d53f0f0
feat: lambda to opensearch 로그 전송 성공(알림 O)
3olly Jul 18, 2025
581203c
fix: network_vpc>main.tf에서 opensearch쪽 tfsec 경고 해결(알림O)
3olly Jul 18, 2025
ce545a8
fix: ci 코드 수정
3olly Jul 18, 2025
00b1691
fix: ci 코드 2차 수정
3olly Jul 18, 2025
e061ab2
feat: ci 쪽에 slack 정보 추가
3olly Jul 18, 2025
dacc87e
fix: ci 코드 3차 수정
3olly Jul 18, 2025
e422322
fix: ci 4차 수정
3olly Jul 18, 2025
8ae97ca
feat: opensearch에 slack 채널 생성까지 성공
3olly Jul 23, 2025
3ca67e5
Delete: lambda와 opensearch 구성 삭제
3olly Jul 23, 2025
ee4f354
feat: cloudtrail 관련 opensearch 모니터링 환경 구성
3olly Jul 24, 2025
fdbffe9
fix: profile 삭제
3olly Jul 24, 2025
a5b09a1
chore: tf format 수정
3olly Jul 24, 2025
1a5e36f
chore: 주석 수정
3olly Jul 24, 2025
bcbf3ef
chore: variables 수정
3olly Jul 27, 2025
28b6b1f
fix: lmabda nodejs 버전 수정 18.x>22.x
3olly Jul 27, 2025
9ebd685
chore: output 수정
3olly Jul 27, 2025
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
68 changes: 36 additions & 32 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,22 @@ jobs:
echo "Changed files:"
echo "$FILES"

declare -A ROLE_MAP=(
declare -A ROLE_MAP=(
["operation-team-account"]="ROLE_ARN_OPERATION"
["identity-team-account"]="ROLE_ARN_IDENTITY"
["prod-team-account"]="ROLE_ARN_PROD"
["dev-team-account"]="ROLE_ARN_DEV"
["security-team-account"]="ROLE_ARN_SECURITY"
["stage-team-account"]="ROLE_ARN_STAGE"
["management-team-account"]="ROLE_ARN_MANAGEMENT"
)

TMP_FILE=$(mktemp)

for FILE in $FILES; do
DIR=$(dirname "$FILE")
TOP_DIR=$(echo $DIR | cut -d/ -f1)
ROLE_KEY="${ROLE_MAP[$TOP_DIR]}"

if [ -n "$ROLE_KEY" ]; then
if [ "$DIR" == "$TOP_DIR" ]; then
TF_COUNT=$(find "$DIR" -maxdepth 1 -name '*.tf' | wc -l)
if [ "$TF_COUNT" -gt 0 ]; then
echo "$DIR|$ROLE_KEY" >> $TMP_FILE
fi
else
TF_COUNT=$(find "$DIR" -maxdepth 1 -name '*.tf' | wc -l)
if [ "$TF_COUNT" -gt 0 ]; then
echo "$DIR|$ROLE_KEY" >> $TMP_FILE
fi
TF_COUNT=$(find "$DIR" -maxdepth 1 -name '*.tf' | wc -l)
if [ "$TF_COUNT" -gt 0 ]; then
echo "$DIR|$ROLE_KEY" >> $TMP_FILE
fi
fi
done
Expand All @@ -84,10 +72,8 @@ jobs:
done <<< "$UNIQUE_LINES"

MATRIX_JSON="$MATRIX_JSON]"

echo "Final JSON matrix:"
echo "$MATRIX_JSON"

echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT

terraform-ci:
Expand All @@ -104,6 +90,7 @@ jobs:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INFRACOST_TERRAFORM_CLI_WRAPPER: false
TF_VAR_slack_webhook_url: ${{ secrets.TF_VAR_slack_webhook_url }}

steps:
- name: Checkout Code
Expand Down Expand Up @@ -152,29 +139,41 @@ jobs:
PLAN_TXT=plan.txt
PLAN_JSON=plan.json

# Run terraform plan
terraform plan -no-color -out=$PLAN_FILE > /dev/null 2> plan_error.txt || echo "PLAN_FAILED=true" >> $GITHUB_ENV
if terraform plan -no-color -out=$PLAN_FILE > /dev/null 2> plan_error.txt; then
echo "PLAN_FAILED=false" >> $GITHUB_ENV
terraform show -no-color $PLAN_FILE > $PLAN_TXT
terraform show -json $PLAN_FILE > $PLAN_JSON || true
else
echo "PLAN_FAILED=true" >> $GITHUB_ENV
echo "Plan failed" > $PLAN_TXT
echo "{}" > $PLAN_JSON
fi

# Show plan text output
terraform show -no-color $PLAN_FILE > $PLAN_TXT 2>/dev/null || echo "Plan failed" > $PLAN_TXT
# 디버깅용 출력
echo "::group::Raw terraform show output"
cat $PLAN_TXT || echo "(empty)"
echo "::endgroup::"

# Remove ANSI color codes
cat $PLAN_TXT | \
sed 's/`/\\`/g' | \
tr -d '\r' | \
sed -r "s/\x1B\[[0-9;]*[JKmsu]//g" \
> cleaned_plan.txt
sed 's/`/\\`/g' $PLAN_TXT | tr -d '\r' | sed -r "s/\x1B\[[0-9;]*[JKmsu]//g" > cleaned_plan.txt

PLAN_CONTENT=$(cat cleaned_plan.txt)
PLAN_ERROR=$(cat plan_error.txt || echo "No error captured")

if [ -z "$PLAN_CONTENT" ]; then
PLAN_CONTENT="(no changes or output empty)"
fi

# Save JSON plan for infracost
terraform show -json $PLAN_FILE > $PLAN_JSON || true
if [ -z "$PLAN_ERROR" ]; then
PLAN_ERROR="(no errors)"
fi

# Output plan content for PR comment
{
echo "PLAN_CONTENT<<EOF"
echo "$PLAN_CONTENT"
echo "EOF"
echo "PLAN_ERROR<<EOF"
echo "$PLAN_ERROR"
echo "EOF"
} >> $GITHUB_OUTPUT
working-directory: ${{ matrix.dir }}

Expand All @@ -198,6 +197,11 @@ jobs:
${{ steps.plan.outputs.PLAN_CONTENT }}
```

### Plan Error (if any)
```
${{ steps.plan.outputs.PLAN_ERROR }}
```

- name: Setup Infracost
uses: infracost/actions/setup@v2

Expand All @@ -213,4 +217,4 @@ jobs:
uses: infracost/actions/comment@v1
with:
path: ${{ matrix.dir }}/infracost.json
behavior: update
behavior: update
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ ehthumbs.db # Windows
*.tmp # 임시 파일

# VSCode 설정 (선택사항)
.vscode/
.vscode/

# OpenSearch alert 생성 시 생기는 임시 파일
modules/opensearch/slack_response.json
39 changes: 39 additions & 0 deletions management-team-account/monitoring/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
terraform {
required_version = ">= 1.1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

backend "s3" {
bucket = "cloudfence-management-state"
key = "cloudtrail/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "tfstate-management-lock"
}
}

provider "aws" {
region = var.aws_region
}

data "terraform_remote_state" "operation" {
backend = "s3"
config = {
bucket = "cloudfence-operation-state"
key = "monitoring/terraform.tfstate"
region = "ap-northeast-2"
}
}

data "aws_caller_identity" "current" {}

module "cloudtrail" {
source = "../../modules/cloudtrail_org"
org_trail_name = var.org_trail_name
cloudtrail_bucket_name = data.terraform_remote_state.operation.outputs.bucket_name
cloudtrail_kms_key_arn = data.terraform_remote_state.operation.outputs.kms_key_arn
}
11 changes: 11 additions & 0 deletions management-team-account/monitoring/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
variable "aws_region" {
description = "AWS region"
type = string
default = "ap-northeast-2"
}

variable "org_trail_name" {
description = "Organization CloudTrail name"
type = string
default = "org-cloudtrail"
}
29 changes: 29 additions & 0 deletions modules/cloudtrail_org/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource "aws_cloudtrail" "org" {
name = var.org_trail_name
is_organization_trail = true
is_multi_region_trail = true
include_global_service_events = true
enable_log_file_validation = true
enable_logging = true

s3_bucket_name = var.cloudtrail_bucket_name
kms_key_id = var.cloudtrail_kms_key_arn

event_selector {
read_write_type = "All"
include_management_events = true

data_resource {
type = "AWS::S3::Object"
values = [
"arn:aws:s3:::${var.cloudtrail_bucket_name}/AWSLogs/"
]
}
}

tags = {
Name = var.org_trail_name
Environment = "prod"
Owner = "security-team"
}
}
14 changes: 14 additions & 0 deletions modules/cloudtrail_org/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "org_trail_name" {
description = "Organization CloudTrail name"
type = string
}

variable "cloudtrail_bucket_name" {
description = "S3 bucket name for CloudTrail logs (from operation account)"
type = string
}

variable "cloudtrail_kms_key_arn" {
description = "KMS key ARN for CloudTrail SSE-KMS (from operation account)"
type = string
}
30 changes: 30 additions & 0 deletions modules/eventbridge_triggers/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
resource "aws_cloudwatch_event_rule" "s3_object_created" {
name = "cloudtrail-s3-event-rule"
description = "Trigger Lambda on CloudTrail S3 delivery objects"

event_pattern = jsonencode({
source = ["aws.s3"]
detail = {
eventName = ["PutObject"]
requestParameters = {
bucketName = [var.bucket_name]
key = [{ prefix = "AWSLogs/" }]
}
}
})
event_bus_name = "default"
}

resource "aws_cloudwatch_event_target" "lambda" {
rule = aws_cloudwatch_event_rule.s3_object_created.name
target_id = "lambda-target"
arn = var.lambda_function_arn
}

resource "aws_lambda_permission" "allow_eventbridge" {
statement_id = "AllowExecutionFromEventBridge"
action = "lambda:InvokeFunction"
function_name = var.lambda_function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.s3_object_created.arn
}
3 changes: 3 additions & 0 deletions modules/eventbridge_triggers/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "event_rule_arn" {
value = aws_cloudwatch_event_rule.s3_object_created.arn
}
14 changes: 14 additions & 0 deletions modules/eventbridge_triggers/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "bucket_name" {
description = "Name of the S3 bucket where CloudTrail logs are stored"
type = string
}

variable "lambda_function_name" {
description = "Lambda function name to be triggered"
type = string
}

variable "lambda_function_arn" {
description = "ARN of the Lambda function to trigger"
type = string
}
Loading