From fb72abbe4e32eefc091287f7754d6e5f5cf6a7de Mon Sep 17 00:00:00 2001 From: "sivan.hajbi" Date: Sun, 3 Aug 2025 22:40:41 +0300 Subject: [PATCH 1/3] classification integration resources --- .github/workflows/dsf_poc_cli.yml | 2 + .../classification_integration_resources.tf | 148 ++++++++++++++++++ examples/aws/poc/dsf_deployment/outputs.tf | 10 +- examples/aws/poc/dsf_deployment/variables.tf | 6 + 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 examples/aws/poc/dsf_deployment/classification_integration_resources.tf diff --git a/.github/workflows/dsf_poc_cli.yml b/.github/workflows/dsf_poc_cli.yml index 8a5a1af67..a6eb515f0 100644 --- a/.github/workflows/dsf_poc_cli.yml +++ b/.github/workflows/dsf_poc_cli.yml @@ -236,6 +236,7 @@ jobs: mv $EXAMPLE_DIR/versions.tf{,_} mv $EXAMPLE_DIR/cm.tf{,_} mv $EXAMPLE_DIR/cte_ddc_agents.tf{,_} + mv $EXAMPLE_DIR/classification_integration_resources.tf{,_} terraform -chdir=$EXAMPLE_DIR destroy -var dam_license=license.mprv -auto-approve mv $EXAMPLE_DIR/main.tf{_,} mv $EXAMPLE_DIR/outputs.tf{_,} @@ -248,6 +249,7 @@ jobs: mv $EXAMPLE_DIR/versions.tf{_,} mv $EXAMPLE_DIR/cm.tf{_,} mv $EXAMPLE_DIR/cte_ddc_agents.tf{_,} + mv $EXAMPLE_DIR/classification_integration_resources.tf{_,} fi - name: Terraform Validate diff --git a/examples/aws/poc/dsf_deployment/classification_integration_resources.tf b/examples/aws/poc/dsf_deployment/classification_integration_resources.tf new file mode 100644 index 000000000..d5f89d484 --- /dev/null +++ b/examples/aws/poc/dsf_deployment/classification_integration_resources.tf @@ -0,0 +1,148 @@ +data "aws_caller_identity" "current" {} + +data "aws_region" "current" {} + +resource "aws_s3_bucket" "scan_results_bucket" { + count = var.create_classification_integration_resources ? 1 : 0 + bucket = join("-", [local.deployment_name_salted, "scan", "results", "bucket"]) + tags = local.tags +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_encryption" { + count = var.create_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.scan_results_bucket[0].id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + bucket_key_enabled = true + } +} + +resource "aws_s3_bucket_public_access_block" "bucket_pab" { + count = var.create_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.scan_results_bucket[0].id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + +resource "aws_s3_bucket_policy" "enforce_ssl" { + count = var.create_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.scan_results_bucket[0].id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "DenyInsecureTransport" + Effect = "Deny" + Principal = "*" + Action = "s3:*" + Resource = [ + "arn:aws:s3:::${aws_s3_bucket.scan_results_bucket[0].id}", + "arn:aws:s3:::${aws_s3_bucket.scan_results_bucket[0].id}/*" + ] + Condition = { + Bool = { + "aws:SecureTransport" = "false" + } + } + } + ] + }) +} + +resource "aws_sqs_queue" "scan_results_bucket_notifications_sqs" { + count = var.create_classification_integration_resources ? 1 : 0 + name = join("-", [local.deployment_name_salted, "scan", "results", "bucket", "notifications", "sqs"]) + sqs_managed_sse_enabled = true + + tags = local.tags +} + +resource "aws_sqs_queue_policy" "scan_results_bucket_notifications_sqs_policy" { + count = var.create_classification_integration_resources ? 1 : 0 + queue_url = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].id + + policy = jsonencode({ + Version = "2012-10-17" + Id = "PolicyForS3ToSendMessageToSQS" + Statement = [ + { + Sid = "PolicyForS3ToSendMessageToSQS" + Effect = "Allow" + Principal = { + Service = "s3.amazonaws.com" + } + Action = "SQS:SendMessage" + Resource = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn + Condition = { + StringEquals = { + "aws:SourceAccount" = data.aws_caller_identity.current.account_id + } + ArnLike = { + "aws:SourceArn": "arn:aws:s3:*:*:${aws_s3_bucket.scan_results_bucket[0].id}" + } + } + } + ] + }) +} + +resource "aws_s3_bucket_notification" "scan_results_bucket_notification" { + count = var.create_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.scan_results_bucket[0].id + + queue { + id = "classification_scan_result_incoming" + queue_arn = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn + events = [ + "s3:ObjectCreated:Put", + "s3:ObjectCreated:CompleteMultipartUpload" + ] + filter_prefix = "scan_result/incoming/" + } + + depends_on = [aws_sqs_queue_policy.scan_results_bucket_notifications_sqs_policy] +} + +resource "aws_iam_policy" "classification_integration_policy" { + count = var.create_classification_integration_resources ? 1 : 0 + name = join("-", [local.deployment_name_salted, "classification", "integration", "policy"]) + description = "Policy for FAM Classification service" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "s3:PutObject", + "s3:GetObject", + "s3:GetBucketNotification" + ] + Resource = [ + aws_s3_bucket.scan_results_bucket[0].arn, + "${aws_s3_bucket.scan_results_bucket[0].arn}/*" + ] + }, + { + Effect = "Allow" + Action = [ + "sqs:ReceiveMessage", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ] + Resource = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn + } + ] + }) + tags = local.tags +} + + diff --git a/examples/aws/poc/dsf_deployment/outputs.tf b/examples/aws/poc/dsf_deployment/outputs.tf index 3e31f4b0b..4e515b097 100644 --- a/examples/aws/poc/dsf_deployment/outputs.tf +++ b/examples/aws/poc/dsf_deployment/outputs.tf @@ -228,4 +228,12 @@ output "web_console_ciphertrust" { password = nonsensitive(local.password) user = local.ciphertrust_manager_web_console_username }, null) -} \ No newline at end of file +} + +output "classification_integration_resources" { + value = try({ + scan_results_bucket_name = aws_s3_bucket.scan_results_bucket[0].id + scan_results_bucket_notifications_sqs_name = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].name + classification_integration_policy = aws_iam_policy.classification_integration_policy[0].arn + }, null) +} diff --git a/examples/aws/poc/dsf_deployment/variables.tf b/examples/aws/poc/dsf_deployment/variables.tf index dca9b4814..69d7b4c14 100644 --- a/examples/aws/poc/dsf_deployment/variables.tf +++ b/examples/aws/poc/dsf_deployment/variables.tf @@ -488,4 +488,10 @@ variable "ddc_agents_windows_count" { type = number default = 0 description = "Number of DDC agent windows servers. Provisioning CTE and/or DDC agent servers requires the enable_ciphertrust variable to be set to 'true'." +} + +variable "create_classification_integration_resources" { + type = bool + default = false + description = "Whether to create the AWS S3 and SQS resources required for classification integration between Hub and CipherTrust." } \ No newline at end of file From db38b9913eff392a90d98e4f0e8dc3bfbef9884c Mon Sep 17 00:00:00 2001 From: "sivan.hajbi" Date: Sun, 10 Aug 2025 13:10:25 +0300 Subject: [PATCH 2/3] code review fixes --- .../classification_integration_resources.tf | 148 ----------------- ...am_classification_integration_resources.tf | 153 ++++++++++++++++++ examples/aws/poc/dsf_deployment/outputs.tf | 8 +- examples/aws/poc/dsf_deployment/variables.tf | 4 +- 4 files changed, 159 insertions(+), 154 deletions(-) delete mode 100644 examples/aws/poc/dsf_deployment/classification_integration_resources.tf create mode 100644 examples/aws/poc/dsf_deployment/fam_classification_integration_resources.tf diff --git a/examples/aws/poc/dsf_deployment/classification_integration_resources.tf b/examples/aws/poc/dsf_deployment/classification_integration_resources.tf deleted file mode 100644 index d5f89d484..000000000 --- a/examples/aws/poc/dsf_deployment/classification_integration_resources.tf +++ /dev/null @@ -1,148 +0,0 @@ -data "aws_caller_identity" "current" {} - -data "aws_region" "current" {} - -resource "aws_s3_bucket" "scan_results_bucket" { - count = var.create_classification_integration_resources ? 1 : 0 - bucket = join("-", [local.deployment_name_salted, "scan", "results", "bucket"]) - tags = local.tags -} - -resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_encryption" { - count = var.create_classification_integration_resources ? 1 : 0 - bucket = aws_s3_bucket.scan_results_bucket[0].id - - rule { - apply_server_side_encryption_by_default { - sse_algorithm = "AES256" - } - bucket_key_enabled = true - } -} - -resource "aws_s3_bucket_public_access_block" "bucket_pab" { - count = var.create_classification_integration_resources ? 1 : 0 - bucket = aws_s3_bucket.scan_results_bucket[0].id - - block_public_acls = true - block_public_policy = true - ignore_public_acls = true - restrict_public_buckets = true -} - -resource "aws_s3_bucket_policy" "enforce_ssl" { - count = var.create_classification_integration_resources ? 1 : 0 - bucket = aws_s3_bucket.scan_results_bucket[0].id - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Sid = "DenyInsecureTransport" - Effect = "Deny" - Principal = "*" - Action = "s3:*" - Resource = [ - "arn:aws:s3:::${aws_s3_bucket.scan_results_bucket[0].id}", - "arn:aws:s3:::${aws_s3_bucket.scan_results_bucket[0].id}/*" - ] - Condition = { - Bool = { - "aws:SecureTransport" = "false" - } - } - } - ] - }) -} - -resource "aws_sqs_queue" "scan_results_bucket_notifications_sqs" { - count = var.create_classification_integration_resources ? 1 : 0 - name = join("-", [local.deployment_name_salted, "scan", "results", "bucket", "notifications", "sqs"]) - sqs_managed_sse_enabled = true - - tags = local.tags -} - -resource "aws_sqs_queue_policy" "scan_results_bucket_notifications_sqs_policy" { - count = var.create_classification_integration_resources ? 1 : 0 - queue_url = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].id - - policy = jsonencode({ - Version = "2012-10-17" - Id = "PolicyForS3ToSendMessageToSQS" - Statement = [ - { - Sid = "PolicyForS3ToSendMessageToSQS" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = "SQS:SendMessage" - Resource = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn - Condition = { - StringEquals = { - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - ArnLike = { - "aws:SourceArn": "arn:aws:s3:*:*:${aws_s3_bucket.scan_results_bucket[0].id}" - } - } - } - ] - }) -} - -resource "aws_s3_bucket_notification" "scan_results_bucket_notification" { - count = var.create_classification_integration_resources ? 1 : 0 - bucket = aws_s3_bucket.scan_results_bucket[0].id - - queue { - id = "classification_scan_result_incoming" - queue_arn = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn - events = [ - "s3:ObjectCreated:Put", - "s3:ObjectCreated:CompleteMultipartUpload" - ] - filter_prefix = "scan_result/incoming/" - } - - depends_on = [aws_sqs_queue_policy.scan_results_bucket_notifications_sqs_policy] -} - -resource "aws_iam_policy" "classification_integration_policy" { - count = var.create_classification_integration_resources ? 1 : 0 - name = join("-", [local.deployment_name_salted, "classification", "integration", "policy"]) - description = "Policy for FAM Classification service" - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "s3:PutObject", - "s3:GetObject", - "s3:GetBucketNotification" - ] - Resource = [ - aws_s3_bucket.scan_results_bucket[0].arn, - "${aws_s3_bucket.scan_results_bucket[0].arn}/*" - ] - }, - { - Effect = "Allow" - Action = [ - "sqs:ReceiveMessage", - "sqs:DeleteMessage", - "sqs:GetQueueAttributes", - "sqs:GetQueueUrl" - ] - Resource = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].arn - } - ] - }) - tags = local.tags -} - - diff --git a/examples/aws/poc/dsf_deployment/fam_classification_integration_resources.tf b/examples/aws/poc/dsf_deployment/fam_classification_integration_resources.tf new file mode 100644 index 000000000..eac768c9a --- /dev/null +++ b/examples/aws/poc/dsf_deployment/fam_classification_integration_resources.tf @@ -0,0 +1,153 @@ +data "aws_caller_identity" "current" {} + +data "aws_region" "current" {} + +resource "random_id" "fam_scan_results_bucket_suffix" { + byte_length = 4 # 4 bytes → 8 hex chars +} + +resource "aws_s3_bucket" "fam_scan_results_bucket" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + bucket = join("-", [local.deployment_name_salted, "fam", "scan", "results", "bucket", random_id.fam_scan_results_bucket_suffix.hex]) + force_destroy = true + tags = local.tags +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "fam_scan_results_bucket_encryption" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.fam_scan_results_bucket[0].id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + bucket_key_enabled = true + } +} + +resource "aws_s3_bucket_public_access_block" "fam_scan_results_bucket_pab" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.fam_scan_results_bucket[0].id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + +resource "aws_s3_bucket_policy" "fam_scan_results_bucket_enforce_ssl" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.fam_scan_results_bucket[0].id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "DenyInsecureTransport" + Effect = "Deny" + Principal = "*" + Action = "s3:*" + Resource = [ + "arn:aws:s3:::${aws_s3_bucket.fam_scan_results_bucket[0].id}", + "arn:aws:s3:::${aws_s3_bucket.fam_scan_results_bucket[0].id}/*" + ] + Condition = { + Bool = { + "aws:SecureTransport" = "false" + } + } + } + ] + }) +} + +resource "aws_sqs_queue" "fam_scan_results_bucket_notifications_sqs" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + name = join("-", [local.deployment_name_salted, "fam", "scan", "results", "bucket", "notifications", "sqs"]) + sqs_managed_sse_enabled = true + + tags = local.tags +} + +resource "aws_sqs_queue_policy" "fam_scan_results_bucket_notifications_sqs_policy" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + queue_url = aws_sqs_queue.fam_scan_results_bucket_notifications_sqs[0].id + + policy = jsonencode({ + Version = "2012-10-17" + Id = "PolicyForS3ToSendMessageToSQS" + Statement = [ + { + Sid = "PolicyForS3ToSendMessageToSQS" + Effect = "Allow" + Principal = { + Service = "s3.amazonaws.com" + } + Action = "SQS:SendMessage" + Resource = aws_sqs_queue.fam_scan_results_bucket_notifications_sqs[0].arn + Condition = { + StringEquals = { + "aws:SourceAccount" = data.aws_caller_identity.current.account_id + } + ArnLike = { + "aws:SourceArn": "arn:aws:s3:*:*:${aws_s3_bucket.fam_scan_results_bucket[0].id}" + } + } + } + ] + }) +} + +resource "aws_s3_bucket_notification" "fam_scan_results_bucket_notification" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + bucket = aws_s3_bucket.fam_scan_results_bucket[0].id + + queue { + id = "fam_classification_scan_result_incoming" + queue_arn = aws_sqs_queue.fam_scan_results_bucket_notifications_sqs[0].arn + events = [ + "s3:ObjectCreated:Put", + "s3:ObjectCreated:CompleteMultipartUpload" + ] + filter_prefix = "scan_result/incoming/" + } + + depends_on = [aws_sqs_queue_policy.fam_scan_results_bucket_notifications_sqs_policy] +} + +resource "aws_iam_policy" "fam_classification_integration_policy" { + count = var.create_fam_classification_integration_resources ? 1 : 0 + name = join("-", [local.deployment_name_salted, "fam", "classification", "integration", "policy"]) + description = "Policy for FAM Classification service" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "s3:PutObject", + "s3:GetObject", + "s3:GetBucketNotification" + ] + Resource = [ + aws_s3_bucket.fam_scan_results_bucket[0].arn, + "${aws_s3_bucket.fam_scan_results_bucket[0].arn}/*" + ] + }, + { + Effect = "Allow" + Action = [ + "sqs:ReceiveMessage", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl" + ] + Resource = aws_sqs_queue.fam_scan_results_bucket_notifications_sqs[0].arn + } + ] + }) + tags = local.tags +} + + diff --git a/examples/aws/poc/dsf_deployment/outputs.tf b/examples/aws/poc/dsf_deployment/outputs.tf index 4e515b097..54c1d8ffd 100644 --- a/examples/aws/poc/dsf_deployment/outputs.tf +++ b/examples/aws/poc/dsf_deployment/outputs.tf @@ -230,10 +230,10 @@ output "web_console_ciphertrust" { }, null) } -output "classification_integration_resources" { +output "fam_classification_integration_resources" { value = try({ - scan_results_bucket_name = aws_s3_bucket.scan_results_bucket[0].id - scan_results_bucket_notifications_sqs_name = aws_sqs_queue.scan_results_bucket_notifications_sqs[0].name - classification_integration_policy = aws_iam_policy.classification_integration_policy[0].arn + scan_results_bucket_name = aws_s3_bucket.fam_scan_results_bucket[0].id + scan_results_bucket_notifications_sqs_name = aws_sqs_queue.fam_scan_results_bucket_notifications_sqs[0].name + classification_integration_iam_policy = aws_iam_policy.fam_classification_integration_policy[0].name }, null) } diff --git a/examples/aws/poc/dsf_deployment/variables.tf b/examples/aws/poc/dsf_deployment/variables.tf index 69d7b4c14..bc9503216 100644 --- a/examples/aws/poc/dsf_deployment/variables.tf +++ b/examples/aws/poc/dsf_deployment/variables.tf @@ -490,8 +490,8 @@ variable "ddc_agents_windows_count" { description = "Number of DDC agent windows servers. Provisioning CTE and/or DDC agent servers requires the enable_ciphertrust variable to be set to 'true'." } -variable "create_classification_integration_resources" { +variable "create_fam_classification_integration_resources" { type = bool default = false - description = "Whether to create the AWS S3 and SQS resources required for classification integration between Hub and CipherTrust." + description = "Whether to create the AWS S3 and SQS resources required for FAM classification integration between Hub and CipherTrust." } \ No newline at end of file From faa7faed00d09765ed22d7e568c93e460212cf68 Mon Sep 17 00:00:00 2001 From: "sivan.hajbi" Date: Mon, 11 Aug 2025 12:24:49 +0300 Subject: [PATCH 3/3] update file rename in yml --- .github/workflows/dsf_poc_cli.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dsf_poc_cli.yml b/.github/workflows/dsf_poc_cli.yml index a6eb515f0..79613268e 100644 --- a/.github/workflows/dsf_poc_cli.yml +++ b/.github/workflows/dsf_poc_cli.yml @@ -236,7 +236,7 @@ jobs: mv $EXAMPLE_DIR/versions.tf{,_} mv $EXAMPLE_DIR/cm.tf{,_} mv $EXAMPLE_DIR/cte_ddc_agents.tf{,_} - mv $EXAMPLE_DIR/classification_integration_resources.tf{,_} + mv $EXAMPLE_DIR/fam_classification_integration_resources.tf{,_} terraform -chdir=$EXAMPLE_DIR destroy -var dam_license=license.mprv -auto-approve mv $EXAMPLE_DIR/main.tf{_,} mv $EXAMPLE_DIR/outputs.tf{_,} @@ -249,7 +249,7 @@ jobs: mv $EXAMPLE_DIR/versions.tf{_,} mv $EXAMPLE_DIR/cm.tf{_,} mv $EXAMPLE_DIR/cte_ddc_agents.tf{_,} - mv $EXAMPLE_DIR/classification_integration_resources.tf{_,} + mv $EXAMPLE_DIR/fam_classification_integration_resources.tf{_,} fi - name: Terraform Validate