diff --git a/management-team-account/.gitignore b/management-team-account/.gitignore new file mode 100644 index 00000000..6f6a3603 --- /dev/null +++ b/management-team-account/.gitignore @@ -0,0 +1,28 @@ +# Terraform 관련 파일 무시 +.terraform/ # terraform init 시 생성되는 폴더 +*.tfstate # 상태 파일 (리소스 실제 정보 포함) +*.tfstate.* # 상태 파일 백업 +terraform.tfstate +terraform.tfstate.* +*.tfvars +*.tfstate.backup +.terraform.lock.hcl +terraform.tfvars # 민감 정보 입력용 파일 +*.auto.tfvars +crash.log # Terraform 충돌 로그 +.terraform +override.tf +override.tf.json +# AWS CLI 자격 증명 +.aws/ # ~/.aws/credentials, config 등 +~/.aws/ +.aws +# 시스템 자동 생성 파일 (Windows/macOS) +.DS_Store # macOS +Thumbs.db # Windows +ehthumbs.db # Windows +*.log # 일반 로그 파일 +*.tmp # 임시 파일 + +# VSCode 설정 (선택사항) +.vscode/ diff --git a/management-team-account/main.tf b/management-team-account/main.tf new file mode 100644 index 00000000..8364699f --- /dev/null +++ b/management-team-account/main.tf @@ -0,0 +1,42 @@ +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" + profile = "whs-sso-management" + } +} + +provider "aws" { + region = var.aws_region + profile = "whs-sso-management" +} + +data "terraform_remote_state" "operation" { + backend = "s3" + config = { + bucket = "cloudfence-operation-state" + key = "monitoring/terraform.tfstate" + region = "ap-northeast-2" + profile = "whs-sso-operation" + } +} + +data "aws_caller_identity" "current" {} + +module "cloudtrail" { + source = "./modules/cloudtrail" + 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 +} \ No newline at end of file diff --git a/management-team-account/modules/cloudtrail/main.tf b/management-team-account/modules/cloudtrail/main.tf new file mode 100644 index 00000000..bd66a554 --- /dev/null +++ b/management-team-account/modules/cloudtrail/main.tf @@ -0,0 +1,17 @@ +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 + + tags = { + Name = var.org_trail_name + Environment = "prod" + Owner = "security-team" + } +} \ No newline at end of file diff --git a/management-team-account/modules/cloudtrail/variables.tf b/management-team-account/modules/cloudtrail/variables.tf new file mode 100644 index 00000000..0133252c --- /dev/null +++ b/management-team-account/modules/cloudtrail/variables.tf @@ -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 +} diff --git a/management-team-account/variables.tf b/management-team-account/variables.tf new file mode 100644 index 00000000..27580262 --- /dev/null +++ b/management-team-account/variables.tf @@ -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" +} \ No newline at end of file diff --git a/operation-team-account/.gitignore b/operation-team-account/.gitignore new file mode 100644 index 00000000..6f6a3603 --- /dev/null +++ b/operation-team-account/.gitignore @@ -0,0 +1,28 @@ +# Terraform 관련 파일 무시 +.terraform/ # terraform init 시 생성되는 폴더 +*.tfstate # 상태 파일 (리소스 실제 정보 포함) +*.tfstate.* # 상태 파일 백업 +terraform.tfstate +terraform.tfstate.* +*.tfvars +*.tfstate.backup +.terraform.lock.hcl +terraform.tfvars # 민감 정보 입력용 파일 +*.auto.tfvars +crash.log # Terraform 충돌 로그 +.terraform +override.tf +override.tf.json +# AWS CLI 자격 증명 +.aws/ # ~/.aws/credentials, config 등 +~/.aws/ +.aws +# 시스템 자동 생성 파일 (Windows/macOS) +.DS_Store # macOS +Thumbs.db # Windows +ehthumbs.db # Windows +*.log # 일반 로그 파일 +*.tmp # 임시 파일 + +# VSCode 설정 (선택사항) +.vscode/ diff --git a/operation-team-account/main.tf b/operation-team-account/main.tf new file mode 100644 index 00000000..b4470fac --- /dev/null +++ b/operation-team-account/main.tf @@ -0,0 +1,98 @@ +terraform { + required_version = ">= 1.1.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } + backend "s3" { + bucket = "cloudfence-operation-state" + key = "monitoring/terraform.tfstate" + region = "ap-northeast-2" + encrypt = true + dynamodb_table = "tfstate-operation-lock" + profile = "whs-sso-operation" + } +} + +provider "aws" { + region = var.aws_region + profile = "whs-sso-operation" +} + +provider "aws" { + alias = "management" + region = var.aws_region + profile = "whs-sso-management" +} + +data "aws_caller_identity" "current" {} + +# 기본(default) VPC 자동 조회 +data "aws_vpc" "default" { + default = true +} + +# 해당 VPC의 모든 서브넷 ID +data "aws_subnets" "default" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} + +# 해당 VPC의 default 보안 그룹 +data "aws_security_group" "default" { + name = "default" + vpc_id = data.aws_vpc.default.id +} + +data "aws_caller_identity" "management" { + provider = aws.management +} + +# 2) S3 모듈: CloudTrail 로그 버킷 + KMS +module "s3" { + source = "./modules/s3" + bucket_name = var.cloudtrail_bucket_name + aws_region = var.aws_region + kms_alias_name = var.kms_alias_name + management_account_id = data.aws_caller_identity.management.account_id +} + +# 3) OpenSearch 모듈: 도메인 생성 + 접근 정책 +module "opensearch" { + source = "./modules/opensearch" + domain_name = var.opensearch_domain_name + engine_version = var.opensearch_engine_version + cluster_instance_type = var.opensearch_instance_type + cluster_instance_count = var.opensearch_instance_count + ebs_volume_size = var.opensearch_ebs_size + kms_key_arn = module.s3.kms_key_arn + lambda_role_arn = module.lambda.lambda_function_role_arn + subnet_ids = [data.aws_subnets.default.ids[0]] + security_group_ids = [data.aws_security_group.default.id] +} + +# 4) Lambda 모듈: 로그 파싱 → OpenSearch + Slack 전송 +module "lambda" { + source = "./modules/lambda" + lambda_function_name = "cloudtrail-log-processor" + lambda_zip_path = "./modules/lambda/lambda_package.zip" + opensearch_domain_arn = module.opensearch.domain_arn + opensearch_endpoint = module.opensearch.endpoint + slack_webhook_url = var.slack_webhook_url + kms_key_arn = module.s3.kms_key_arn + bucket_arn = module.s3.bucket_arn + lambda_subnet_ids = [data.aws_subnets.default.ids[0]] + lambda_security_group_ids = [data.aws_security_group.default.id] +} + +# 5) EventBridge 모듈: S3 PutObject → Lambda 트리거 +module "eventbridge" { + source = "./modules/eventbridge" + bucket_name = module.s3.bucket_name + lambda_function_name = module.lambda.lambda_function_name + lambda_function_arn = module.lambda.lambda_function_arn +} \ No newline at end of file diff --git a/operation-team-account/modules/eventbridge/main.tf b/operation-team-account/modules/eventbridge/main.tf new file mode 100644 index 00000000..36306150 --- /dev/null +++ b/operation-team-account/modules/eventbridge/main.tf @@ -0,0 +1,263 @@ +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 +} + +# 루트 계정 로그인 실패 탐지 +resource "aws_cloudwatch_event_rule" "detect_root_fail" { + name = "detect-root-login-failure" + description = "Detect failed root console login" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["ConsoleLogin"] + errorCode = ["FailedAuthentication"] + userIdentity = { type = ["Root"] } + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_root_fail" { + rule = aws_cloudwatch_event_rule.detect_root_fail.name + target_id = "root-fail" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_root_fail" { + statement_id = "AllowDetectRootFail" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_root_fail.arn +} + +# 권한 변경 액션 탐지 +resource "aws_cloudwatch_event_rule" "detect_permission_change" { + name = "detect-iam-permission-change" + description = "Detect changes to IAM policies" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = [ + "AttachUserPolicy", "DetachUserPolicy", + "PutUserPolicy", "DeleteUserPolicy", + "CreatePolicy", "DeletePolicy" + ] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_permission_change" { + rule = aws_cloudwatch_event_rule.detect_permission_change.name + target_id = "permission-change" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_permission_change" { + statement_id = "AllowDetectPermissionChange" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_permission_change.arn +} + +# IAM 사용자/역할 삭제 탐지 +resource "aws_cloudwatch_event_rule" "detect_iam_delete" { + name = "detect-iam-deletion" + description = "Detect deletion of IAM users, roles, or login profiles" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["DeleteUser", "DeleteRole", "DeleteLoginProfile"] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_iam_delete" { + rule = aws_cloudwatch_event_rule.detect_iam_delete.name + target_id = "iam-deletion" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_iam_delete" { + statement_id = "AllowDetectIamDelete" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_iam_delete.arn +} + +# CloudTrail 로그 중지/삭제 탐지 +resource "aws_cloudwatch_event_rule" "detect_cloudtrail_disable" { + name = "detect-cloudtrail-disable" + description = "Detect when CloudTrail is stopped or deleted" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["StopLogging", "DeleteTrail"] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_cloudtrail_disable" { + rule = aws_cloudwatch_event_rule.detect_cloudtrail_disable.name + target_id = "cloudtrail-disable" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_cloudtrail_disable" { + statement_id = "AllowDetectCloudtrailDisable" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_cloudtrail_disable.arn +} + +# MFA 디바이스 비활성화 탐지 +resource "aws_cloudwatch_event_rule" "detect_mfa_deactivate" { + name = "detect-mfa-deactivation" + description = "Detect MFA deactivation or deletion" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["DeactivateMFADevice", "DeleteVirtualMFADevice"] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_mfa_deactivate" { + rule = aws_cloudwatch_event_rule.detect_mfa_deactivate.name + target_id = "mfa-deactivate" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_mfa_deactivate" { + statement_id = "AllowDetectMfaDeactivate" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_mfa_deactivate.arn +} + +# 보안 그룹 규칙 변경 탐지 +resource "aws_cloudwatch_event_rule" "detect_sg_change" { + name = "detect-security-group-change" + description = "Detect changes to Security Group ingress/egress rules" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = [ + "AuthorizeSecurityGroupIngress", "RevokeSecurityGroupIngress", + "AuthorizeSecurityGroupEgress", "RevokeSecurityGroupEgress" + ] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_sg_change" { + rule = aws_cloudwatch_event_rule.detect_sg_change.name + target_id = "sg-change" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_sg_change" { + statement_id = "AllowDetectSgChange" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_sg_change.arn +} + +# S3 퍼블릭 접근 허용 탐지 +resource "aws_cloudwatch_event_rule" "detect_s3_public" { + name = "detect-s3-public-access" + description = "Detect when S3 bucket ACL or policy makes it public" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["PutBucketAcl", "PutBucketPolicy", "PutPublicAccessBlock"] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_s3_public" { + rule = aws_cloudwatch_event_rule.detect_s3_public.name + target_id = "s3-public" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_s3_public" { + statement_id = "AllowDetectS3Public" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_s3_public.arn +} + +# EC2 인스턴스 생성 탐지 +resource "aws_cloudwatch_event_rule" "detect_ec2_launch" { + name = "detect-ec2-instance-launch" + description = "Detect when EC2 instances are launched" + event_pattern = jsonencode({ + source = ["aws.cloudtrail"] + "detail-type" = ["AWS API Call via CloudTrail"] + detail = { + eventName = ["RunInstances"] + } + }) + event_bus_name = "default" +} + +resource "aws_cloudwatch_event_target" "detect_ec2_launch" { + rule = aws_cloudwatch_event_rule.detect_ec2_launch.name + target_id = "ec2-launch" + arn = var.lambda_function_arn +} + +resource "aws_lambda_permission" "allow_detect_ec2_launch" { + statement_id = "AllowDetectEc2Launch" + action = "lambda:InvokeFunction" + function_name = var.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.detect_ec2_launch.arn +} \ No newline at end of file diff --git a/operation-team-account/modules/eventbridge/outputs.tf b/operation-team-account/modules/eventbridge/outputs.tf new file mode 100644 index 00000000..cf9967c0 --- /dev/null +++ b/operation-team-account/modules/eventbridge/outputs.tf @@ -0,0 +1,3 @@ +output "event_rule_arn" { + value = aws_cloudwatch_event_rule.s3_object_created.arn +} \ No newline at end of file diff --git a/operation-team-account/modules/eventbridge/variables.tf b/operation-team-account/modules/eventbridge/variables.tf new file mode 100644 index 00000000..f7d96b7c --- /dev/null +++ b/operation-team-account/modules/eventbridge/variables.tf @@ -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 +} \ No newline at end of file diff --git a/operation-team-account/modules/lambda/lambda_function.py b/operation-team-account/modules/lambda/lambda_function.py new file mode 100644 index 00000000..c3c672da --- /dev/null +++ b/operation-team-account/modules/lambda/lambda_function.py @@ -0,0 +1,4 @@ +def lambda_handler(event, context): + # TODO: Slack 알림, OpenSearch 색인 로직 구현 + print("Event:", event) + return {"status": "ok"} \ No newline at end of file diff --git a/operation-team-account/modules/lambda/lambda_package.zip b/operation-team-account/modules/lambda/lambda_package.zip new file mode 100644 index 00000000..8d507740 Binary files /dev/null and b/operation-team-account/modules/lambda/lambda_package.zip differ diff --git a/operation-team-account/modules/lambda/main.tf b/operation-team-account/modules/lambda/main.tf new file mode 100644 index 00000000..09f1bfae --- /dev/null +++ b/operation-team-account/modules/lambda/main.tf @@ -0,0 +1,86 @@ +resource "aws_iam_role" "lambda_exec" { + name = "lambda-log-processor-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { Service = "lambda.amazonaws.com" } + Action = "sts:AssumeRole" + } + ] + }) +} + +resource "aws_iam_role_policy" "lambda_policy" { + name = "lambda-log-policy" + role = aws_iam_role.lambda_exec.id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "AllowCloudWatchLogs" + Effect = "Allow" + Action = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + Resource = "*" + }, + { + Sid = "AllowOpenSearchAccess" + Effect = "Allow" + Action = [ + "es:ESHttpPost", + "es:ESHttpPut", + "es:ESHttpGet" + ] + # 인덱스 패턴 아래 모든 경로 허용 + Resource = "${var.opensearch_domain_arn}/security-events-*/*" + }, + { + Sid = "AllowKMSDecrypt" + Effect = "Allow" + Action = ["kms:Decrypt"] + Resource = var.kms_key_arn + }, + { + Sid = "AllowS3Read" + Effect = "Allow" + Action = ["s3:GetObject"] + Resource = "${var.bucket_arn}/*" + } + ] + }) +} + +resource "aws_lambda_function" "log_processor" { + function_name = var.lambda_function_name + handler = "lambda_function.lambda_handler" + runtime = "python3.11" + role = aws_iam_role.lambda_exec.arn + timeout = 30 + memory_size = 256 + filename = var.lambda_zip_path + source_code_hash = filebase64sha256(var.lambda_zip_path) + + vpc_config { + subnet_ids = var.lambda_subnet_ids + security_group_ids = var.lambda_security_group_ids + } + + environment { + variables = { + SLACK_WEBHOOK_URL = var.slack_webhook_url + OPENSEARCH_URL = var.opensearch_endpoint + } + } +} + +resource "aws_iam_role_policy_attachment" "vpc_access" { + role = aws_iam_role.lambda_exec.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole" +} diff --git a/operation-team-account/modules/lambda/outputs.tf b/operation-team-account/modules/lambda/outputs.tf new file mode 100644 index 00000000..3a9ee18f --- /dev/null +++ b/operation-team-account/modules/lambda/outputs.tf @@ -0,0 +1,14 @@ +output "lambda_function_name" { + value = aws_lambda_function.log_processor.function_name + description = "Name of the deployed Lambda function" +} + +output "lambda_function_role_arn" { + value = aws_iam_role.lambda_exec.arn + description = "IAM Role ARN for Lambda execution" +} + +output "lambda_function_arn" { + value = aws_lambda_function.log_processor.arn + description = "ARN of the Lambda function" +} \ No newline at end of file diff --git a/operation-team-account/modules/lambda/variables.tf b/operation-team-account/modules/lambda/variables.tf new file mode 100644 index 00000000..cdb999ed --- /dev/null +++ b/operation-team-account/modules/lambda/variables.tf @@ -0,0 +1,45 @@ +variable "lambda_function_name" { + type = string + description = "Name of the Lambda function" +} + +variable "lambda_zip_path" { + type = string + description = "Path to the zipped Lambda package" +} + +variable "opensearch_domain_arn" { + type = string + description = "ARN of the OpenSearch domain" +} + +variable "opensearch_endpoint" { + type = string + description = "OpenSearch endpoint URL" +} + +variable "slack_webhook_url" { + type = string + description = "Slack Webhook URL" + sensitive = true +} + +variable "kms_key_arn" { + type = string + description = "KMS key for decrypting Slack secret (if encrypted)" +} + +variable "bucket_arn" { + description = "ARN of the S3 bucket for CloudTrail logs" + type = string +} + +variable "lambda_subnet_ids" { + description = "List of subnet IDs for the Lambda function to attach to the VPC" + type = list(string) +} + +variable "lambda_security_group_ids" { + description = "Security group IDs for the Lambda function in the VPC" + type = list(string) +} \ No newline at end of file diff --git a/operation-team-account/modules/opensearch/ISM/delete-after-30d.json b/operation-team-account/modules/opensearch/ISM/delete-after-30d.json new file mode 100644 index 00000000..1f757774 --- /dev/null +++ b/operation-team-account/modules/opensearch/ISM/delete-after-30d.json @@ -0,0 +1,28 @@ +{ + "policy": { + "policy_id": "delete-after-30d", + "description": "Delete indices older than 30 days", + "default_state": "hot", + "states": [ + { + "name": "hot", + "actions": [], + "transitions": [ + { + "state_name": "delete", + "conditions": { + "min_index_age": "30d" + } + } + ] + }, + { + "name": "delete", + "actions": [ + { "delete": {} } + ], + "transitions": [] + } + ] + } +} diff --git a/operation-team-account/modules/opensearch/main.tf b/operation-team-account/modules/opensearch/main.tf new file mode 100644 index 00000000..46347ed1 --- /dev/null +++ b/operation-team-account/modules/opensearch/main.tf @@ -0,0 +1,43 @@ +resource "aws_opensearch_domain" "siem" { + domain_name = "siem-${var.domain_name}" + engine_version = var.engine_version + + cluster_config { + instance_type = var.cluster_instance_type + instance_count = var.cluster_instance_count + } + + ebs_options { + ebs_enabled = true + volume_size = var.ebs_volume_size + } + + encrypt_at_rest { + enabled = true + kms_key_id = var.kms_key_arn + } + + node_to_node_encryption { + enabled = true + } + + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-2-2019-07" + } + + vpc_options { + subnet_ids = var.subnet_ids + security_group_ids = var.security_group_ids + } + + tags = { + Name = "siem-opensearch" + Environment = "dev" + Owner = "monitoring-team" + } +} + +output "endpoint" { + value = aws_opensearch_domain.siem.endpoint +} \ No newline at end of file diff --git a/operation-team-account/modules/opensearch/null_resource.tf b/operation-team-account/modules/opensearch/null_resource.tf new file mode 100644 index 00000000..6c59c266 --- /dev/null +++ b/operation-team-account/modules/opensearch/null_resource.tf @@ -0,0 +1,35 @@ +resource "null_resource" "import_saved_query" { + provisioner "local-exec" { + command = <