From 68d4572e0683a333e0a5ce5f3d2d5b5e7648ada8 Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 11:33:58 -0400 Subject: [PATCH 01/15] feat: Add platform-cx-s3-to-sqs module --- platform-cx-s3-to-sqs/README.md | 205 +++++++++++ .../examples/clickhouse-integration/README.md | 37 ++ .../examples/clickhouse-integration/main.tf | 57 +++ .../examples/cloudquery-integration/README.md | 46 +++ .../examples/cloudquery-integration/main.tf | 87 +++++ .../examples/dual-inegration/main.tf | 86 +++++ platform-cx-s3-to-sqs/main.tf | 337 ++++++++++++++++++ .../iam-role-for-serviceaccount/README.md | 71 ++++ .../iam-role-for-serviceaccount/main.tf | 221 ++++++++++++ .../iam-role-for-serviceaccount/outputs.tf | 48 +++ .../iam-role-for-serviceaccount/variables.tf | 161 +++++++++ platform-cx-s3-to-sqs/outputs.tf | 68 ++++ platform-cx-s3-to-sqs/variables.tf | 208 +++++++++++ 13 files changed, 1632 insertions(+) create mode 100644 platform-cx-s3-to-sqs/README.md create mode 100644 platform-cx-s3-to-sqs/examples/clickhouse-integration/README.md create mode 100644 platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf create mode 100644 platform-cx-s3-to-sqs/examples/cloudquery-integration/README.md create mode 100644 platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf create mode 100644 platform-cx-s3-to-sqs/examples/dual-inegration/main.tf create mode 100644 platform-cx-s3-to-sqs/main.tf create mode 100644 platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/README.md create mode 100644 platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/main.tf create mode 100644 platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/outputs.tf create mode 100644 platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/variables.tf create mode 100644 platform-cx-s3-to-sqs/outputs.tf create mode 100644 platform-cx-s3-to-sqs/variables.tf diff --git a/platform-cx-s3-to-sqs/README.md b/platform-cx-s3-to-sqs/README.md new file mode 100644 index 0000000..59e93f0 --- /dev/null +++ b/platform-cx-s3-to-sqs/README.md @@ -0,0 +1,205 @@ +# AWS S3 to SQS Integration Module + +This Terraform module helps you integrate your AWS S3 bucket with CloudQuery Platform and/or ClickHouse by creating the necessary resources and permissions. + +## What This Module Creates + +- **SQS Queue**: For S3 event notifications when objects are created/updated +- **S3 Bucket Event Notifications**: Configured to send events to the SQS queue +- **IAM Role**: With the necessary permissions for CloudQuery Platform and/or ClickHouse + +## Prerequisites + +- AWS account with permissions to create SQS queues, IAM roles, and modify S3 bucket policies +- Terraform v0.14+ installed +- An existing S3 bucket + +## Usage + +### Basic Setup with CloudQuery Platform Integration + +```hcl +module "s3_to_sqs_integration" { + source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + + # Existing S3 bucket details + s3_bucket_id = "my-existing-bucket" + s3_bucket_arn = "arn:aws:s3:::my-existing-bucket" + + # SQS queue configuration + queue_name = "my-existing-bucket-notifications" + + # CloudQuery Platform integration + cloudquery_platform_role_arn = "arn:aws:iam::767397982801:role/cloudquery-platform-production" + iam_role_name = "cloudquery-platform-access" + external_id = "cloudquery-${random_id.external_id.hex}" + require_external_id = true +} + +resource "random_id" "external_id" { + byte_length = 8 +} +``` + +### ClickHouse Integration + +```hcl +module "clickhouse_integration" { + source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + + # Existing S3 bucket details + s3_bucket_id = "my-existing-bucket" + s3_bucket_arn = "arn:aws:s3:::my-existing-bucket" + + # SQS queue configuration (optional for ClickHouse) + queue_name = "my-existing-bucket-notifications" + + # ClickHouse integration + clickhouse_role_arn = "arn:aws:iam::012345678901:role/ClickHouse-Integration-Role" + iam_role_name = "clickhouse-s3-access-role" +} +``` + +### Dual Integration (CloudQuery Platform and ClickHouse) + +```hcl +module "dual_integration" { + source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + + # Existing S3 bucket details + s3_bucket_id = "my-existing-bucket" + s3_bucket_arn = "arn:aws:s3:::my-existing-bucket" + + # SQS queue configuration + queue_name = "my-existing-bucket-notifications" + s3_events = ["s3:ObjectCreated:*"] + filter_prefix = "data/" # Optional: Filter events by prefix + + # Role configuration for both services + iam_role_name = "dual-integration-role" + cloudquery_platform_role_arn = "arn:aws:iam::767397982801:role/cloudquery-platform-production" + clickhouse_role_arn = "arn:aws:iam::012345678901:role/ClickHouse-Integration-Role" + external_id = "integration-${random_id.external_id.hex}" +} + +resource "random_id" "external_id" { + byte_length = 8 +} +``` + +## Examples + +The module includes several example configurations: + +1. [`examples/cloudquery-integration`](examples/cloudquery-integration/main.tf): Setting up CloudQuery Platform integration +2. [`examples/clickhouse-integration`](examples/clickhouse-integration/main.tf): Setting up ClickHouse integration +3. [`examples/dual-integration`](examples/dual-integration/main.tf): Setting up both integrations with a single role + +## How It Works + +1. The module creates an SQS queue in your AWS account +2. It configures your S3 bucket to send event notifications to the SQS queue +3. It creates an IAM role that CloudQuery Platform and/or ClickHouse can assume +4. You provide the Role ARN, External ID (if used), and other details to the service(s) +5. The services can then securely access your data using these credentials + + + +## Requirements + +| Name | Version | +| ------------------------------------------------------------------------ | -------- | +| [terraform](#requirement_terraform) | >= 1.0.0 | +| [aws](#requirement_aws) | >= 4.0.0 | + +## Providers + +| Name | Version | +| ------------------------------------------------ | -------- | +| [aws](#provider_aws) | >= 4.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| [aws_iam_policy.s3_sqs_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.s3_to_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.customer_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.s3_sqs_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_s3_bucket_notification.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_notification) | resource | +| [aws_s3_bucket_policy.allow_publish_to_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [aws_sqs_queue.dlq](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue_redrive_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_redrive_policy) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.sqs_consumer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.sqs_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +| ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | -------------- | ------------------------------------------------- | :------: | +| [queue_name](#input_queue_name) | Name of the SQS queue to create | `string` | n/a | yes | +| [s3_bucket_arn](#input_s3_bucket_arn) | The ARN of the S3 bucket | `string` | n/a | yes | +| [s3_bucket_id](#input_s3_bucket_id) | The ID of the S3 bucket to configure event notifications for | `string` | n/a | yes | +| [clickhouse_role_arn](#input_clickhouse_role_arn) | The ARN of the ClickHouse role that will be allowed to assume the customer role | `string` | `""` | no | +| [cloudquery_platform_role_arn](#input_cloudquery_platform_role_arn) | The ARN of the CloudQuery Platform role that will be allowed to assume the customer role | `string` | `""` | no | +| [cloudquery_role_arn](#input_cloudquery_role_arn) | The ARN of the CloudQuery Platform role that will be allowed to assume the customer role | `string` | `""` | no | +| [content_based_deduplication](#input_content_based_deduplication) | Enables content-based deduplication for FIFO queues | `bool` | `false` | no | +| [create_consumer_policy](#input_create_consumer_policy) | Whether to create an IAM policy for consumers of this SQS queue | `bool` | `true` | no | +| [customer_role_name](#input_customer_role_name) | Name of the IAM role to create in the customer's account | `string` | `"s3-sqs-integration-role"` | no | +| [deduplication_scope](#input_deduplication_scope) | Specifies whether message deduplication occurs at the message group or queue level | `string` | `"queue"` | no | +| [delay_seconds](#input_delay_seconds) | The time in seconds that the delivery of all messages in the queue will be delayed | `number` | `0` | no | +| [dlq_max_receive_count](#input_dlq_max_receive_count) | The number of times a message can be unsuccessfully dequeued before being moved to the DLQ | `number` | `5` | no | +| [dlq_message_retention_seconds](#input_dlq_message_retention_seconds) | The number of seconds Amazon SQS retains a message in the DLQ | `number` | `1209600` | no | +| [enable_dlq](#input_enable_dlq) | Whether to create a dead-letter queue | `bool` | `false` | no | +| [existing_bucket_policy](#input_existing_bucket_policy) | The existing bucket policy to merge with the S3 notification policy (in JSON format) | `string` | `"{\"Version\":\"2012-10-17\",\"Statement\":[]}"` | no | +| [external_id](#input_external_id) | The external ID to use for role assumption (recommended for security) | `string` | `""` | no | +| [fifo_queue](#input_fifo_queue) | Boolean designating a FIFO queue | `bool` | `false` | no | +| [fifo_throughput_limit](#input_fifo_throughput_limit) | Specifies whether the FIFO queue throughput quota applies to the entire queue or per message group | `string` | `"perQueue"` | no | +| [filter_prefix](#input_filter_prefix) | Optional prefix filter for S3 notifications | `string` | `""` | no | +| [filter_suffix](#input_filter_suffix) | Optional suffix filter for S3 notifications | `string` | `""` | no | +| [iam_policy_name](#input_iam_policy_name) | Name of the IAM policy to create for SQS queue consumers | `string` | `"s3-to-sqs-consumer-policy"` | no | +| [iam_role_name](#input_iam_role_name) | Name of the IAM role to create for S3 and SQS access | `string` | `"s3-sqs-integration-role"` | no | +| [kms_data_key_reuse_period_seconds](#input_kms_data_key_reuse_period_seconds) | The length of time in seconds for which Amazon SQS can reuse a data key to encrypt or decrypt messages | `number` | `300` | no | +| [kms_master_key_id](#input_kms_master_key_id) | The ID of an AWS-managed customer master key for Amazon SQS or a custom CMK | `string` | `null` | no | +| [max_message_size](#input_max_message_size) | The limit of how many bytes a message can contain | `number` | `262144` | no | +| [message_retention_seconds](#input_message_retention_seconds) | The number of seconds Amazon SQS retains a message | `number` | `345600` | no | +| [receive_wait_time_seconds](#input_receive_wait_time_seconds) | The time for which a ReceiveMessage call will wait for a message to arrive | `number` | `0` | no | +| [require_external_id](#input_require_external_id) | Whether to require an external ID when assuming the role | `bool` | `true` | no | +| [s3_events](#input_s3_events) | List of S3 events to trigger notifications for | `list(string)` |
[| no | +| [tags](#input_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no | +| [visibility_timeout_seconds](#input_visibility_timeout_seconds) | The visibility timeout for the queue in seconds | `number` | `30` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| [bucket_notification_id](#output_bucket_notification_id) | The ID of the S3 bucket notification configuration | +| [customer_role_arn](#output_customer_role_arn) | ARN of the IAM role created for CloudQuery/ClickHouse integration | +| [customer_role_name](#output_customer_role_name) | Name of the IAM role created for CloudQuery/ClickHouse integration | +| [external_id](#output_external_id) | External ID used for role assumption (if provided) | +| [iam_policy_arn](#output_iam_policy_arn) | The ARN of the IAM policy for consumers | +| [iam_policy_id](#output_iam_policy_id) | The ID of the IAM policy for consumers | +| [iam_policy_name](#output_iam_policy_name) | The name of the IAM policy for consumers | +| [sqs_dlq_arn](#output_sqs_dlq_arn) | The ARN of the SQS dead-letter queue | +| [sqs_dlq_id](#output_sqs_dlq_id) | The ID of the SQS dead-letter queue | +| [sqs_dlq_url](#output_sqs_dlq_url) | The URL of the SQS dead-letter queue | +| [sqs_queue_arn](#output_sqs_queue_arn) | The ARN of the SQS queue | +| [sqs_queue_id](#output_sqs_queue_id) | The ID of the SQS queue | +| [sqs_queue_url](#output_sqs_queue_url) | The URL of the SQS queue | + + + +## Security Best Practices + +- Always use an External ID in the trust policy for cross-account access +- Use a separate IAM role specific to these integrations +- Consider setting up S3 event notifications with prefix filtering to limit the scope +- Use a randomly generated External ID rather than a static value diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/README.md b/platform-cx-s3-to-sqs/examples/clickhouse-integration/README.md new file mode 100644 index 0000000..5645ff9 --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/README.md @@ -0,0 +1,37 @@ + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [random](#provider\_random) | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [s3\_to\_sqs\_integration](#module\_s3\_to\_sqs\_integration) | github.com/cloudquery/terraform-aws-s3-to-sqs | n/a | + +## Resources + +| Name | Type | +|------|------| +| [random_id.external_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [configuration\_instructions](#output\_configuration\_instructions) | Instructions for providing the role information to ClickHouse Cloud | +| [role\_arn](#output\_role\_arn) | The ARN of the IAM role to provide to ClickHouse Cloud | +| [role\_external\_id](#output\_role\_external\_id) | The external ID to provide to ClickHouse Cloud (keep this secure) | +| [sqs\_queue\_arn](#output\_sqs\_queue\_arn) | The ARN of the SQS queue | +| [sqs\_queue\_url](#output\_sqs\_queue\_url) | The URL of the SQS queue receiving S3 event notifications | + diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf new file mode 100644 index 0000000..246ed4f --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -0,0 +1,57 @@ +# Example for ClickHouse integration with existing S3 bucket +# This creates an IAM role that allows ClickHouse to access your S3 data + +provider "aws" { + region = "us-east-1" # Change to the region where your S3 bucket is located +} + +locals { + # ClickHouse IAM role ARN - THIS SHOULD BE THE ACTUAL ROLE ARN PROVIDED BY CLICKHOUSE + clickhouse_role_arn = "arn:aws:iam::191110999071:role/CH-S3-steel-mv-95-ue1-42-Role" + + # Your existing S3 bucket information + existing_bucket_name = "your-existing-bucket" + existing_bucket_arn = "arn:aws:s3:::your-existing-bucket" +} + +module "clickhouse_integration" { + source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + + # Existing S3 bucket details + s3_bucket_id = local.existing_bucket_name + s3_bucket_arn = local.existing_bucket_arn + + # The SQS queue is optional for ClickHouse, but we'll create it anyway + # to maintain compatibility with the module + queue_name = "${local.existing_bucket_name}-notifications" + + # Create IAM role with appropriate trust policy for ClickHouse + customer_role_name = "clickhouse-s3-access-role" + clickhouse_role_arn = local.clickhouse_role_arn +} + +# Output the information needed to provide to ClickHouse +output "role_arn" { + description = "The ARN of the IAM role to provide to ClickHouse" + value = module.clickhouse_integration.customer_role_arn +} + +output "bucket_name" { + description = "The name of the S3 bucket to provide to ClickHouse" + value = local.existing_bucket_name +} + +output "configuration_instructions" { + description = "Instructions for ClickHouse integration" + value = <<-EOT + ## ClickHouse Integration Instructions + + Provide the following information to ClickHouse: + + 1. Role ARN: ${module.clickhouse_integration.customer_role_arn} + 2. S3 Bucket Name: ${local.existing_bucket_name} + + This role has been configured with the exact permissions required by ClickHouse + to access your S3 bucket data. + EOT +} diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/README.md b/platform-cx-s3-to-sqs/examples/cloudquery-integration/README.md new file mode 100644 index 0000000..dd4ed23 --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/README.md @@ -0,0 +1,46 @@ + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [random](#provider\_random) | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [s3\_to\_sqs\_integration](#module\_s3\_to\_sqs\_integration) | github.com/cloudquery/terraform-aws-s3-to-sqs | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_s3_bucket.data_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_acl.data_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | +| [aws_s3_bucket_ownership_controls.data_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | +| [aws_s3_object.data_directory](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | +| [random_id.external_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | Environment name (e.g., dev, staging, prod) | `string` | `"dev"` | no | +| [tags](#input\_tags) | A map of tags to assign to all resources | `map(string)` |
"s3:ObjectCreated:*"
]
{
"ManagedBy": "Terraform"
} | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [bucket\_name](#output\_bucket\_name) | The name of the S3 bucket created for ClickHouse Cloud |
+| [configuration\_instructions](#output\_configuration\_instructions) | Instructions for providing the role information to ClickHouse Cloud |
+| [role\_arn](#output\_role\_arn) | The ARN of the IAM role to provide to ClickHouse Cloud |
+| [role\_external\_id](#output\_role\_external\_id) | The external ID to provide to ClickHouse Cloud (keep this secure) |
+| [sqs\_queue\_url](#output\_sqs\_queue\_url) | The URL of the SQS queue receiving S3 event notifications |
+
diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf
new file mode 100644
index 0000000..dc1bfef
--- /dev/null
+++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf
@@ -0,0 +1,87 @@
+# Example for CloudQuery Platform integration with an existing S3 bucket
+# This creates:
+# 1. A new SQS queue in the customer account
+# 2. S3 event notifications to the SQS queue
+# 3. An IAM role that CloudQuery Platform can assume to access both resources
+
+provider "aws" {
+ region = "us-east-1" # Change to the region where your S3 bucket is located
+}
+
+# Generate a secure random external ID
+resource "random_id" "external_id" {
+ byte_length = 8
+}
+
+# Replace these with your actual S3 bucket details
+locals {
+ # CloudQuery Platform Role ARN - THIS SHOULD BE THE ACTUAL ROLE ARN PROVIDED TO YOU
+ cloudquery_role_arn = "arn:aws:iam::586794438123:role/cq-platform-eks-latest-cloudquery-sync"
+
+ # Customer's existing S3 bucket information
+ existing_bucket_name = "your-existing-bucket"
+ existing_bucket_arn = "arn:aws:s3:::your-existing-bucket"
+}
+
+module "cloudquery_integration" {
+ source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs"
+
+ # Existing S3 bucket details
+ s3_bucket_id = local.existing_bucket_name
+ s3_bucket_arn = local.existing_bucket_arn
+
+ # SQS queue configuration
+ queue_name = "${local.existing_bucket_name}-notifications"
+ s3_events = ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"]
+ enable_dlq = true
+
+ # Optional: Filter events by prefix/suffix
+ filter_prefix = "uploads/" # Only monitor this prefix, remove if not needed
+
+ # Create IAM role with appropriate trust policy for CloudQuery Platform
+ customer_role_name = "cloudquery-platform-s3-sqs-access"
+ cloudquery_role_arn = local.cloudquery_role_arn
+ require_external_id = true
+ external_id = "cloudquery-${random_id.external_id.hex}" # Secure random external ID
+}
+
+# Output the information needed to provide to CloudQuery Platform
+output "role_arn" {
+ description = "The ARN of the IAM role to provide to CloudQuery Platform"
+ value = module.cloudquery_integration.customer_role_arn
+}
+
+output "role_external_id" {
+ description = "The external ID to provide to CloudQuery Platform (keep this secure)"
+ value = "cloudquery-${random_id.external_id.hex}"
+ sensitive = true
+}
+
+output "sqs_queue_url" {
+ description = "The URL of the SQS queue receiving S3 event notifications"
+ value = module.cloudquery_integration.sqs_queue_url
+}
+
+output "sqs_queue_arn" {
+ description = "The ARN of the SQS queue"
+ value = module.cloudquery_integration.sqs_queue_arn
+}
+
+output "configuration_instructions" {
+ description = "Instructions for providing the role information to CloudQuery Platform"
+ value = <<-EOT
+ ## Configuration Instructions
+
+ Provide the following information to CloudQuery Platform:
+
+ 1. Role ARN: ${module.cloudquery_integration.customer_role_arn}
+ 2. External ID: [Available in the Terraform state or CLI output]
+ 3. SQS Queue URL: ${module.cloudquery_integration.sqs_queue_url}
+
+ To update your bucket when data changes:
+ - Files added to s3://${local.existing_bucket_name}/uploads/ will trigger notifications
+ - CloudQuery Platform will poll the SQS queue and process new files
+
+ Note: Keep the external ID secure - it's required when CloudQuery Platform assumes this role.
+ EOT
+}
diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf
new file mode 100644
index 0000000..a953d1c
--- /dev/null
+++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf
@@ -0,0 +1,86 @@
+# Example for dual integration (CloudQuery Platform and ClickHouse)
+# This creates an IAM role that both services can assume to access your S3 and SQS resources
+
+provider "aws" {
+ region = "us-west-2" # Change to your preferred region
+}
+
+# Generate a secure random external ID
+resource "random_id" "external_id" {
+ byte_length = 8
+}
+
+locals {
+ # Replace these with the actual ARNs provided to you
+ cloudquery_role_arn = "arn:aws:iam::586794438123:role/cq-platform-eks-latest-cloudquery-sync"
+ clickhouse_role_arn = "arn:aws:iam::191110999071:role/CH-S3-steel-mv-95-ue1-42-Role"
+
+ # Your existing S3 bucket information
+ existing_bucket_name = "your-existing-bucket"
+ existing_bucket_arn = "arn:aws:s3:::your-existing-bucket"
+
+ # External ID with prefix for better identification
+ external_id = "integration-${random_id.external_id.hex}"
+}
+
+module "dual_integration" {
+ source = "github.com/cloudquery/terraform-aws-s3-to-sqs"
+
+ # Existing S3 bucket details
+ s3_bucket_id = local.existing_bucket_name
+ s3_bucket_arn = local.existing_bucket_arn
+
+ # SQS queue configuration
+ queue_name = "${local.existing_bucket_name}-notifications"
+ s3_events = ["s3:ObjectCreated:*"]
+ filter_prefix = "data/" # Optional: Filter events by prefix
+
+ # Role configuration for both CloudQuery and ClickHouse
+ customer_role_name = "cloudquery-clickhouse-integration-role"
+ cloudquery_role_arn = local.cloudquery_role_arn
+ clickhouse_role_arn = local.clickhouse_role_arn
+ require_external_id = true
+ external_id = local.external_id
+
+ tags = {
+ Environment = "production"
+ ManagedBy = "Terraform"
+ }
+}
+
+# Output the configuration information
+output "role_arn" {
+ description = "The ARN of the IAM role that CloudQuery and ClickHouse can assume"
+ value = module.dual_integration.customer_role_arn
+}
+
+output "external_id" {
+ description = "The external ID for role assumption (share with both services)"
+ value = local.external_id
+ sensitive = true
+}
+
+output "sqs_queue_url" {
+ description = "The URL of the SQS queue receiving S3 event notifications"
+ value = module.dual_integration.sqs_queue_url
+}
+
+output "configuration_instructions" {
+ description = "Instructions for integration"
+ value = <list(object({
namespace = string
name = string
})) | `[]` | no |
+| [sqs\_dlq\_arn](#input\_sqs\_dlq\_arn) | The ARN of the SQS dead-letter queue, if any | `string` | `null` | no |
+| [tags](#input\_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no |
+| [trusted\_account\_ids](#input\_trusted\_account\_ids) | List of AWS account IDs that are allowed to assume this role | `list(string)` | `[]` | no |
+| [trusted\_role\_arns](#input\_trusted\_role\_arns) | List of ARNs of IAM roles that are allowed to assume this role | `list(string)` | `[]` | no |
+| [trusted\_services](#input\_trusted\_services) | List of AWS services that are allowed to assume this role (e.g., ec2.amazonaws.com, lambda.amazonaws.com) | `list(string)` | `[]` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [instance\_profile\_arn](#output\_instance\_profile\_arn) | ARN of the instance profile |
+| [instance\_profile\_id](#output\_instance\_profile\_id) | ID of the instance profile |
+| [instance\_profile\_name](#output\_instance\_profile\_name) | Name of the instance profile |
+| [policy\_arn](#output\_policy\_arn) | ARN of the IAM policy |
+| [policy\_id](#output\_policy\_id) | ID of the IAM policy |
+| [policy\_name](#output\_policy\_name) | Name of the IAM policy |
+| [role\_arn](#output\_role\_arn) | ARN of the IAM role |
+| [role\_id](#output\_role\_id) | ID of the IAM role |
+| [role\_name](#output\_role\_name) | Name of the IAM role |
+
diff --git a/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/main.tf b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/main.tf
new file mode 100644
index 0000000..fbca145
--- /dev/null
+++ b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/main.tf
@@ -0,0 +1,221 @@
+################################################################################
+# IAM Role with Configurable Trust Policy
+#
+# This creates an IAM role with a configurable trust policy and attaches the
+# necessary permissions for S3 and SQS access.
+################################################################################
+
+resource "aws_iam_role" "this" {
+ count = var.create_role ? 1 : 0
+
+ name = var.role_name
+ description = var.role_description
+
+ # Use provided assume role policy if specified, otherwise build one based on provided trust options
+ assume_role_policy = var.custom_assume_role_policy != null ? var.custom_assume_role_policy : data.aws_iam_policy_document.trust_policy[0].json
+
+ max_session_duration = var.max_session_duration
+ path = var.path
+ permissions_boundary = var.permissions_boundary
+
+ tags = var.tags
+}
+
+# Generate a trust policy based on provided trusted entities
+data "aws_iam_policy_document" "trust_policy" {
+ count = var.create_role && var.custom_assume_role_policy == null ? 1 : 0
+
+ # Allow AWS accounts to assume this role
+ dynamic "statement" {
+ for_each = length(var.trusted_account_ids) > 0 ? [1] : []
+
+ content {
+ sid = "TrustedAccounts"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+
+ principals {
+ type = "AWS"
+ identifiers = formatlist("arn:aws:iam::%s:root", var.trusted_account_ids)
+ }
+
+ dynamic "condition" {
+ for_each = var.require_external_id ? [var.external_id] : []
+
+ content {
+ test = "StringEquals"
+ variable = "sts:ExternalId"
+ values = [condition.value]
+ }
+ }
+ }
+ }
+
+ # Allow specified AWS roles to assume this role
+ dynamic "statement" {
+ for_each = length(var.trusted_role_arns) > 0 ? [1] : []
+
+ content {
+ sid = "TrustedRoles"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+
+ principals {
+ type = "AWS"
+ identifiers = var.trusted_role_arns
+ }
+ }
+ }
+
+ # Allow Kubernetes service accounts via IRSA
+ dynamic "statement" {
+ for_each = var.oidc_provider_arn != null ? [1] : []
+
+ content {
+ sid = "EKSServiceAccounts"
+ effect = "Allow"
+ actions = ["sts:AssumeRoleWithWebIdentity"]
+
+ principals {
+ type = "Federated"
+ identifiers = [var.oidc_provider_arn]
+ }
+
+ condition {
+ test = "StringEquals"
+ variable = "${var.oidc_provider_url}:sub"
+ values = [
+ for sa in var.service_accounts :
+ "system:serviceaccount:${sa.namespace}:${sa.name}"
+ ]
+ }
+
+ condition {
+ test = "StringEquals"
+ variable = "${var.oidc_provider_url}:aud"
+ values = ["sts.amazonaws.com"]
+ }
+ }
+ }
+
+ # Allow EC2 to assume this role (for EC2 instance profiles)
+ dynamic "statement" {
+ for_each = var.trusted_services != null && contains(var.trusted_services, "ec2.amazonaws.com") ? [1] : []
+
+ content {
+ sid = "EC2AssumeRole"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+
+ principals {
+ type = "Service"
+ identifiers = ["ec2.amazonaws.com"]
+ }
+ }
+ }
+
+ # Allow Lambda to assume this role
+ dynamic "statement" {
+ for_each = var.trusted_services != null && contains(var.trusted_services, "lambda.amazonaws.com") ? [1] : []
+
+ content {
+ sid = "LambdaAssumeRole"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+
+ principals {
+ type = "Service"
+ identifiers = ["lambda.amazonaws.com"]
+ }
+ }
+ }
+}
+
+# Create the policy for S3 and SQS access
+resource "aws_iam_policy" "this" {
+ count = var.create_policy ? 1 : 0
+
+ name = var.policy_name != null ? var.policy_name : "${var.role_name}-policy"
+ description = var.policy_description != null ? var.policy_description : "Policy for accessing S3 bucket and SQS queues"
+ policy = data.aws_iam_policy_document.s3_sqs_access.json
+ path = var.path
+
+ tags = var.tags
+}
+
+# Attach the policy to the role
+resource "aws_iam_role_policy_attachment" "this" {
+ count = var.create_role && var.create_policy ? 1 : 0
+
+ role = aws_iam_role.this[0].name
+ policy_arn = aws_iam_policy.this[0].arn
+}
+
+# Attach any additional policies to the role
+resource "aws_iam_role_policy_attachment" "additional" {
+ for_each = var.create_role ? toset(var.additional_policy_arns) : toset([])
+
+ role = aws_iam_role.this[0].name
+ policy_arn = each.value
+}
+
+# Create instance profile if requested (for EC2)
+resource "aws_iam_instance_profile" "this" {
+ count = var.create_role && var.create_instance_profile ? 1 : 0
+
+ name = var.instance_profile_name != null ? var.instance_profile_name : var.role_name
+ path = var.path
+ role = aws_iam_role.this[0].name
+
+ tags = var.tags
+}
+
+# Policy document for S3 and SQS access
+data "aws_iam_policy_document" "s3_sqs_access" {
+ statement {
+ sid = "AllowSQSAccess"
+ effect = "Allow"
+ actions = [
+ "sqs:ReceiveMessage",
+ "sqs:DeleteMessage",
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ ]
+ resources = [var.sqs_queue_arn]
+ }
+
+ statement {
+ sid = "AllowS3ObjectAccess"
+ effect = "Allow"
+ actions = [
+ "s3:Get*",
+ "s3:List*"
+ ]
+ resources = ["${var.s3_bucket_arn}/*"]
+ }
+
+ statement {
+ sid = "AllowS3BucketAccess"
+ effect = "Allow"
+ actions = [
+ "s3:GetBucketLocation",
+ "s3:ListBucket"
+ ]
+ resources = [var.s3_bucket_arn]
+ }
+
+ dynamic "statement" {
+ for_each = var.sqs_dlq_arn != null ? [1] : []
+ content {
+ sid = "AllowDLQAccess"
+ effect = "Allow"
+ actions = [
+ "sqs:ReceiveMessage",
+ "sqs:DeleteMessage",
+ "sqs:GetQueueAttributes",
+ "sqs:GetQueueUrl",
+ ]
+ resources = [var.sqs_dlq_arn]
+ }
+ }
+}
diff --git a/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/outputs.tf b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/outputs.tf
new file mode 100644
index 0000000..86183ef
--- /dev/null
+++ b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/outputs.tf
@@ -0,0 +1,48 @@
+################################################################################
+# Outputs
+################################################################################
+
+output "role_name" {
+ description = "Name of the IAM role"
+ value = try(aws_iam_role.this[0].name, null)
+}
+
+output "role_arn" {
+ description = "ARN of the IAM role"
+ value = try(aws_iam_role.this[0].arn, null)
+}
+
+output "role_id" {
+ description = "ID of the IAM role"
+ value = try(aws_iam_role.this[0].id, null)
+}
+
+output "policy_name" {
+ description = "Name of the IAM policy"
+ value = try(aws_iam_policy.this[0].name, null)
+}
+
+output "policy_arn" {
+ description = "ARN of the IAM policy"
+ value = try(aws_iam_policy.this[0].arn, null)
+}
+
+output "policy_id" {
+ description = "ID of the IAM policy"
+ value = try(aws_iam_policy.this[0].id, null)
+}
+
+output "instance_profile_name" {
+ description = "Name of the instance profile"
+ value = try(aws_iam_instance_profile.this[0].name, null)
+}
+
+output "instance_profile_arn" {
+ description = "ARN of the instance profile"
+ value = try(aws_iam_instance_profile.this[0].arn, null)
+}
+
+output "instance_profile_id" {
+ description = "ID of the instance profile"
+ value = try(aws_iam_instance_profile.this[0].id, null)
+}
diff --git a/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/variables.tf b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/variables.tf
new file mode 100644
index 0000000..a78168a
--- /dev/null
+++ b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/variables.tf
@@ -0,0 +1,161 @@
+################################################################################
+# IAM Role and Trust Policy Variables
+################################################################################
+
+variable "create_role" {
+ description = "Whether to create the IAM role"
+ type = bool
+ default = true
+}
+
+variable "create_policy" {
+ description = "Whether to create the IAM policy"
+ type = bool
+ default = true
+}
+
+variable "role_name" {
+ description = "Name of the IAM role"
+ type = string
+}
+
+variable "role_description" {
+ description = "Description of the IAM role"
+ type = string
+ default = "Role for accessing S3 bucket and SQS queues"
+}
+
+variable "policy_name" {
+ description = "Name of the IAM policy to create. If not provided, will use role_name-policy"
+ type = string
+ default = null
+}
+
+variable "policy_description" {
+ description = "Description of the IAM policy"
+ type = string
+ default = null
+}
+
+variable "path" {
+ description = "Path for the role and policy"
+ type = string
+ default = "/"
+}
+
+variable "max_session_duration" {
+ description = "Maximum session duration (in seconds) for the role"
+ type = number
+ default = 3600
+}
+
+variable "permissions_boundary" {
+ description = "ARN of the permissions boundary to use for the role"
+ type = string
+ default = null
+}
+
+variable "custom_assume_role_policy" {
+ description = "A custom assume role policy JSON. If provided, this will be used instead of the generated one"
+ type = string
+ default = null
+}
+
+variable "trusted_account_ids" {
+ description = "List of AWS account IDs that are allowed to assume this role"
+ type = list(string)
+ default = []
+}
+
+variable "trusted_role_arns" {
+ description = "List of ARNs of IAM roles that are allowed to assume this role"
+ type = list(string)
+ default = []
+}
+
+variable "trusted_services" {
+ description = "List of AWS services that are allowed to assume this role (e.g., ec2.amazonaws.com, lambda.amazonaws.com)"
+ type = list(string)
+ default = []
+}
+
+variable "require_external_id" {
+ description = "Whether to require an external ID when other accounts assume this role"
+ type = bool
+ default = false
+}
+
+variable "external_id" {
+ description = "External ID to use when other accounts assume this role"
+ type = string
+ default = ""
+}
+
+variable "oidc_provider_arn" {
+ description = "ARN of the OIDC provider for IRSA (IAM Roles for Service Accounts)"
+ type = string
+ default = null
+}
+
+variable "oidc_provider_url" {
+ description = "URL of the OIDC provider for IRSA, without the https:// prefix"
+ type = string
+ default = null
+}
+
+variable "service_accounts" {
+ description = "List of Kubernetes service account objects that are allowed to assume this role via IRSA"
+ type = list(object({
+ namespace = string
+ name = string
+ }))
+ default = []
+}
+
+variable "create_instance_profile" {
+ description = "Whether to create an instance profile for the role"
+ type = bool
+ default = false
+}
+
+variable "instance_profile_name" {
+ description = "Name of the instance profile. If not provided, will use role_name"
+ type = string
+ default = null
+}
+
+variable "additional_policy_arns" {
+ description = "List of additional policy ARNs to attach to the role"
+ type = list(string)
+ default = []
+}
+
+################################################################################
+# S3 and SQS Resource Variables
+################################################################################
+
+variable "s3_bucket_arn" {
+ description = "The ARN of the S3 bucket"
+ type = string
+}
+
+variable "sqs_queue_arn" {
+ description = "The ARN of the SQS queue"
+ type = string
+}
+
+variable "sqs_dlq_arn" {
+ description = "The ARN of the SQS dead-letter queue, if any"
+ type = string
+ default = null
+}
+
+################################################################################
+# General
+################################################################################
+
+variable "tags" {
+ description = "A map of tags to assign to resources"
+ type = map(string)
+ default = {}
+}
diff --git a/platform-cx-s3-to-sqs/outputs.tf b/platform-cx-s3-to-sqs/outputs.tf
new file mode 100644
index 0000000..f2ecb4a
--- /dev/null
+++ b/platform-cx-s3-to-sqs/outputs.tf
@@ -0,0 +1,68 @@
+################################################################################
+# Outputs
+################################################################################
+
+output "sqs_queue_id" {
+ description = "The ID of the SQS queue"
+ value = aws_sqs_queue.this.id
+}
+
+output "sqs_queue_arn" {
+ description = "The ARN of the SQS queue"
+ value = aws_sqs_queue.this.arn
+}
+
+output "sqs_queue_url" {
+ description = "The URL of the SQS queue"
+ value = aws_sqs_queue.this.url
+}
+
+output "sqs_dlq_id" {
+ description = "The ID of the SQS dead-letter queue"
+ value = var.enable_dlq ? aws_sqs_queue.dlq[0].id : null
+}
+
+output "sqs_dlq_arn" {
+ description = "The ARN of the SQS dead-letter queue"
+ value = var.enable_dlq ? aws_sqs_queue.dlq[0].arn : null
+}
+
+output "sqs_dlq_url" {
+ description = "The URL of the SQS dead-letter queue"
+ value = var.enable_dlq ? aws_sqs_queue.dlq[0].url : null
+}
+
+output "bucket_notification_id" {
+ description = "The ID of the S3 bucket notification configuration"
+ value = aws_s3_bucket_notification.this.id
+}
+
+output "iam_policy_arn" {
+ description = "The ARN of the IAM policy for consumers"
+ value = var.create_consumer_policy ? aws_iam_policy.s3_to_sqs[0].arn : null
+}
+
+output "iam_policy_id" {
+ description = "The ID of the IAM policy for consumers"
+ value = var.create_consumer_policy ? aws_iam_policy.s3_to_sqs[0].id : null
+}
+
+output "iam_policy_name" {
+ description = "The name of the IAM policy for consumers"
+ value = var.create_consumer_policy ? aws_iam_policy.s3_to_sqs[0].name : null
+}
+
+output "customer_role_arn" {
+ description = "ARN of the IAM role created for CloudQuery/ClickHouse integration"
+ value = aws_iam_role.customer_role.arn
+}
+
+output "customer_role_name" {
+ description = "Name of the IAM role created for CloudQuery/ClickHouse integration"
+ value = aws_iam_role.customer_role.name
+}
+
+output "external_id" {
+ description = "External ID used for role assumption (if provided)"
+ value = var.external_id
+}
diff --git a/platform-cx-s3-to-sqs/variables.tf b/platform-cx-s3-to-sqs/variables.tf
new file mode 100644
index 0000000..22462b8
--- /dev/null
+++ b/platform-cx-s3-to-sqs/variables.tf
@@ -0,0 +1,208 @@
+################################################################################
+# Variables
+################################################################################
+
+#--------------------------------------------------------------
+# S3 Bucket Configuration
+#--------------------------------------------------------------
+
+variable "s3_bucket_id" {
+ description = "The ID of the S3 bucket to configure event notifications for"
+ type = string
+}
+
+variable "s3_bucket_arn" {
+ description = "The ARN of the S3 bucket"
+ type = string
+}
+
+variable "existing_bucket_policy" {
+ description = "The existing bucket policy to merge with the S3 notification policy (in JSON format)"
+ type = string
+ default = "{\"Version\":\"2012-10-17\",\"Statement\":[]}"
+}
+
+variable "s3_events" {
+ description = "List of S3 events to trigger notifications for"
+ type = list(string)
+ default = ["s3:ObjectCreated:*"]
+}
+
+variable "filter_prefix" {
+ description = "Optional prefix filter for S3 notifications"
+ type = string
+ default = ""
+}
+
+variable "filter_suffix" {
+ description = "Optional suffix filter for S3 notifications"
+ type = string
+ default = ""
+}
+
+#--------------------------------------------------------------
+# SQS Queue Configuration
+#--------------------------------------------------------------
+
+variable "queue_name" {
+ description = "Name of the SQS queue to create"
+ type = string
+}
+
+variable "visibility_timeout_seconds" {
+ description = "The visibility timeout for the queue in seconds"
+ type = number
+ default = 30
+}
+
+variable "message_retention_seconds" {
+ description = "The number of seconds Amazon SQS retains a message"
+ type = number
+ default = 345600 # 4 days
+}
+
+variable "max_message_size" {
+ description = "The limit of how many bytes a message can contain"
+ type = number
+ default = 262144 # 256 KiB
+}
+
+variable "delay_seconds" {
+ description = "The time in seconds that the delivery of all messages in the queue will be delayed"
+ type = number
+ default = 0
+}
+
+variable "receive_wait_time_seconds" {
+ description = "The time for which a ReceiveMessage call will wait for a message to arrive"
+ type = number
+ default = 0
+}
+
+variable "kms_master_key_id" {
+ description = "The ID of an AWS-managed customer master key for Amazon SQS or a custom CMK"
+ type = string
+ default = null
+}
+
+variable "kms_data_key_reuse_period_seconds" {
+ description = "The length of time in seconds for which Amazon SQS can reuse a data key to encrypt or decrypt messages"
+ type = number
+ default = 300 # 5 minutes
+}
+
+variable "fifo_queue" {
+ description = "Boolean designating a FIFO queue"
+ type = bool
+ default = false
+}
+
+variable "content_based_deduplication" {
+ description = "Enables content-based deduplication for FIFO queues"
+ type = bool
+ default = false
+}
+
+variable "deduplication_scope" {
+ description = "Specifies whether message deduplication occurs at the message group or queue level"
+ type = string
+ default = "queue"
+ validation {
+ condition = contains(["messageGroup", "queue"], var.deduplication_scope)
+ error_message = "Deduplication scope must be either 'messageGroup' or 'queue'."
+ }
+}
+
+variable "fifo_throughput_limit" {
+ description = "Specifies whether the FIFO queue throughput quota applies to the entire queue or per message group"
+ type = string
+ default = "perQueue"
+ validation {
+ condition = contains(["perQueue", "perMessageGroupId"], var.fifo_throughput_limit)
+ error_message = "FIFO throughput limit must be either 'perQueue' or 'perMessageGroupId'."
+ }
+}
+
+#--------------------------------------------------------------
+# Dead Letter Queue Configuration
+#--------------------------------------------------------------
+
+variable "enable_dlq" {
+ description = "Whether to create a dead-letter queue"
+ type = bool
+ default = false
+}
+
+variable "dlq_message_retention_seconds" {
+ description = "The number of seconds Amazon SQS retains a message in the DLQ"
+ type = number
+ default = 1209600 # 14 days
+}
+
+variable "dlq_max_receive_count" {
+ description = "The number of times a message can be unsuccessfully dequeued before being moved to the DLQ"
+ type = number
+ default = 5
+}
+
+#--------------------------------------------------------------
+# IAM Policy Configuration
+#--------------------------------------------------------------
+
+variable "create_consumer_policy" {
+ description = "Whether to create an IAM policy for consumers of this SQS queue"
+ type = bool
+ default = true
+}
+
+variable "iam_policy_name" {
+ description = "Name of the IAM policy to create for SQS queue consumers"
+ type = string
+ default = "s3-to-sqs-consumer-policy"
+}
+
+#--------------------------------------------------------------
+# General
+#--------------------------------------------------------------
+
+variable "tags" {
+ description = "A map of tags to assign to resources"
+ type = map(string)
+ default = {}
+}
+
+variable "clickhouse_role_arn" {
+ description = "The ARN of the ClickHouse role that will be allowed to assume the customer role"
+ type = string
+ default = ""
+}
+
+variable "external_id" {
+ description = "The external ID to use for role assumption (recommended for security)"
+ type = string
+ default = ""
+}
+
+variable "require_external_id" {
+ description = "Whether to require an external ID when assuming the role"
+ type = bool
+ default = true
+}
+
+variable "customer_role_name" {
+ description = "Name of the IAM role to create in the customer's account"
+ type = string
+ default = "s3-sqs-integration-role"
+}
+
+variable "cloudquery_platform_role_arn" {
+ description = "The ARN of the CloudQuery Platform role that will be allowed to assume the customer role"
+ type = string
+ default = ""
+}
+
+variable "iam_role_name" {
+ description = "Name of the IAM role to create for S3 and SQS access"
+ type = string
+ default = "s3-sqs-integration-role"
+}
From c855574e74b89ea8cc1b0919be0a47edcb4e12d2 Mon Sep 17 00:00:00 2001
From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com>
Date: Tue, 25 Mar 2025 11:46:16 -0400
Subject: [PATCH 02/15] chore: move provider config to separate file
---
platform-cx-s3-to-sqs/main.tf | 10 ----------
platform-cx-s3-to-sqs/providers.tf | 9 +++++++++
2 files changed, 9 insertions(+), 10 deletions(-)
create mode 100644 platform-cx-s3-to-sqs/providers.tf
diff --git a/platform-cx-s3-to-sqs/main.tf b/platform-cx-s3-to-sqs/main.tf
index a2a58fb..0b6e00b 100644
--- a/platform-cx-s3-to-sqs/main.tf
+++ b/platform-cx-s3-to-sqs/main.tf
@@ -15,16 +15,6 @@
# - sqs:SetQueueAttributes
################################################################################
-terraform {
- required_version = ">= 1.0.0"
- required_providers {
- aws = {
- source = "hashicorp/aws"
- version = ">= 4.0.0"
- }
- }
-}
-
#--------------------------------------------------------------
# SQS Queue
#--------------------------------------------------------------
diff --git a/platform-cx-s3-to-sqs/providers.tf b/platform-cx-s3-to-sqs/providers.tf
new file mode 100644
index 0000000..2aa1770
--- /dev/null
+++ b/platform-cx-s3-to-sqs/providers.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 1.0.0"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.0.0"
+ }
+ }
+}
From ee559050118d6b4cd4f37c7312303626d8542c03 Mon Sep 17 00:00:00 2001
From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com>
Date: Tue, 25 Mar 2025 11:54:45 -0400
Subject: [PATCH 03/15] chore: ci fixes
---
.../examples/clickhouse-integration/main.tf | 2 +-
.../examples/cloudquery-integration/main.tf | 2 +-
platform-cx-s3-to-sqs/examples/dual-inegration/main.tf | 2 +-
platform-cx-s3-to-sqs/variables.tf | 6 ------
4 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf
index 246ed4f..0d58162 100644
--- a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf
+++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf
@@ -26,7 +26,7 @@ module "clickhouse_integration" {
queue_name = "${local.existing_bucket_name}-notifications"
# Create IAM role with appropriate trust policy for ClickHouse
- customer_role_name = "clickhouse-s3-access-role"
+ iam_role_name = "clickhouse-s3-access-role"
clickhouse_role_arn = local.clickhouse_role_arn
}
diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf
index dc1bfef..fbc0a28 100644
--- a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf
+++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf
@@ -39,7 +39,7 @@ module "cloudquery_integration" {
filter_prefix = "uploads/" # Only monitor this prefix, remove if not needed
# Create IAM role with appropriate trust policy for CloudQuery Platform
- customer_role_name = "cloudquery-platform-s3-sqs-access"
+ iam_role_name = "cloudquery-platform-s3-sqs-access"
cloudquery_role_arn = local.cloudquery_role_arn
require_external_id = true
external_id = "cloudquery-${random_id.external_id.hex}" # Secure random external ID
diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf
index a953d1c..8631db5 100644
--- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf
+++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf
@@ -36,7 +36,7 @@ module "dual_integration" {
filter_prefix = "data/" # Optional: Filter events by prefix
# Role configuration for both CloudQuery and ClickHouse
- customer_role_name = "cloudquery-clickhouse-integration-role"
+ iam_role_name = "cloudquery-clickhouse-integration-role"
cloudquery_role_arn = local.cloudquery_role_arn
clickhouse_role_arn = local.clickhouse_role_arn
require_external_id = true
diff --git a/platform-cx-s3-to-sqs/variables.tf b/platform-cx-s3-to-sqs/variables.tf
index 22462b8..3017c15 100644
--- a/platform-cx-s3-to-sqs/variables.tf
+++ b/platform-cx-s3-to-sqs/variables.tf
@@ -189,12 +189,6 @@ variable "require_external_id" {
default = true
}
-variable "customer_role_name" {
- description = "Name of the IAM role to create in the customer's account"
- type = string
- default = "s3-sqs-integration-role"
-}
-
variable "cloudquery_platform_role_arn" {
description = "The ARN of the CloudQuery Platform role that will be allowed to assume the customer role"
type = string
From d7fb83e2dfcec0f5b333a67187dfbc9d36221947 Mon Sep 17 00:00:00 2001
From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com>
Date: Tue, 25 Mar 2025 11:58:13 -0400
Subject: [PATCH 04/15] chore: update providers, add versions file
---
platform-cx-s3-to-sqs/providers.tf | 12 +++++-------
platform-cx-s3-to-sqs/versions.tf | 9 +++++++++
2 files changed, 14 insertions(+), 7 deletions(-)
create mode 100644 platform-cx-s3-to-sqs/versions.tf
diff --git a/platform-cx-s3-to-sqs/providers.tf b/platform-cx-s3-to-sqs/providers.tf
index 2aa1770..6c843dc 100644
--- a/platform-cx-s3-to-sqs/providers.tf
+++ b/platform-cx-s3-to-sqs/providers.tf
@@ -1,9 +1,7 @@
-terraform {
- required_version = ">= 1.0.0"
- required_providers {
- aws = {
- source = "hashicorp/aws"
- version = ">= 4.0.0"
- }
+provider "aws" {
+ region = var.region
+
+ default_tags {
+ tags = var.tags
}
}
diff --git a/platform-cx-s3-to-sqs/versions.tf b/platform-cx-s3-to-sqs/versions.tf
new file mode 100644
index 0000000..2aa1770
--- /dev/null
+++ b/platform-cx-s3-to-sqs/versions.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 1.0.0"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.0.0"
+ }
+ }
+}
From 1df7291feda67b078ab7d1966269bcafc8a84b3c Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" [| no | -| [tags](#input_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no | -| [visibility_timeout_seconds](#input_visibility_timeout_seconds) | The visibility timeout for the queue in seconds | `number` | `30` | no | +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [clickhouse\_role\_arn](#input\_clickhouse\_role\_arn) | The ARN of the ClickHouse role that will be allowed to assume the customer role | `string` | `""` | no | +| [cloudquery\_platform\_role\_arn](#input\_cloudquery\_platform\_role\_arn) | The ARN of the CloudQuery Platform role that will be allowed to assume the customer role | `string` | `""` | no | +| [content\_based\_deduplication](#input\_content\_based\_deduplication) | Enables content-based deduplication for FIFO queues | `bool` | `false` | no | +| [create\_consumer\_policy](#input\_create\_consumer\_policy) | Whether to create an IAM policy for consumers of this SQS queue | `bool` | `true` | no | +| [deduplication\_scope](#input\_deduplication\_scope) | Specifies whether message deduplication occurs at the message group or queue level | `string` | `"queue"` | no | +| [delay\_seconds](#input\_delay\_seconds) | The time in seconds that the delivery of all messages in the queue will be delayed | `number` | `0` | no | +| [dlq\_max\_receive\_count](#input\_dlq\_max\_receive\_count) | The number of times a message can be unsuccessfully dequeued before being moved to the DLQ | `number` | `5` | no | +| [dlq\_message\_retention\_seconds](#input\_dlq\_message\_retention\_seconds) | The number of seconds Amazon SQS retains a message in the DLQ | `number` | `1209600` | no | +| [enable\_dlq](#input\_enable\_dlq) | Whether to create a dead-letter queue | `bool` | `false` | no | +| [existing\_bucket\_policy](#input\_existing\_bucket\_policy) | The existing bucket policy to merge with the S3 notification policy (in JSON format) | `string` | `"{\"Version\":\"2012-10-17\",\"Statement\":[]}"` | no | +| [external\_id](#input\_external\_id) | The external ID to use for role assumption (recommended for security) | `string` | `""` | no | +| [fifo\_queue](#input\_fifo\_queue) | Boolean designating a FIFO queue | `bool` | `false` | no | +| [fifo\_throughput\_limit](#input\_fifo\_throughput\_limit) | Specifies whether the FIFO queue throughput quota applies to the entire queue or per message group | `string` | `"perQueue"` | no | +| [filter\_prefix](#input\_filter\_prefix) | Optional prefix filter for S3 notifications | `string` | `""` | no | +| [filter\_suffix](#input\_filter\_suffix) | Optional suffix filter for S3 notifications | `string` | `""` | no | +| [iam\_policy\_name](#input\_iam\_policy\_name) | Name of the IAM policy to create for SQS queue consumers | `string` | `"s3-to-sqs-consumer-policy"` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Name of the IAM role to create for S3 and SQS access | `string` | `"s3-sqs-integration-role"` | no | +| [kms\_data\_key\_reuse\_period\_seconds](#input\_kms\_data\_key\_reuse\_period\_seconds) | The length of time in seconds for which Amazon SQS can reuse a data key to encrypt or decrypt messages | `number` | `300` | no | +| [kms\_master\_key\_id](#input\_kms\_master\_key\_id) | The ID of an AWS-managed customer master key for Amazon SQS or a custom CMK | `string` | `null` | no | +| [max\_message\_size](#input\_max\_message\_size) | The limit of how many bytes a message can contain | `number` | `262144` | no | +| [message\_retention\_seconds](#input\_message\_retention\_seconds) | The number of seconds Amazon SQS retains a message | `number` | `345600` | no | +| [queue\_name](#input\_queue\_name) | Name of the SQS queue to create | `string` | n/a | yes | +| [receive\_wait\_time\_seconds](#input\_receive\_wait\_time\_seconds) | The time for which a ReceiveMessage call will wait for a message to arrive | `number` | `0` | no | +| [require\_external\_id](#input\_require\_external\_id) | Whether to require an external ID when assuming the role | `bool` | `true` | no | +| [s3\_bucket\_arn](#input\_s3\_bucket\_arn) | The ARN of the S3 bucket | `string` | n/a | yes | +| [s3\_bucket\_id](#input\_s3\_bucket\_id) | The ID of the S3 bucket to configure event notifications for | `string` | n/a | yes | +| [s3\_events](#input\_s3\_events) | List of S3 events to trigger notifications for | `list(string)` |
"s3:ObjectCreated:*"
]
[| no | +| [tags](#input\_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no | +| [visibility\_timeout\_seconds](#input\_visibility\_timeout\_seconds) | The visibility timeout for the queue in seconds | `number` | `30` | no | ## Outputs -| Name | Description | -| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -| [bucket_notification_id](#output_bucket_notification_id) | The ID of the S3 bucket notification configuration | -| [customer_role_arn](#output_customer_role_arn) | ARN of the IAM role created for CloudQuery/ClickHouse integration | -| [customer_role_name](#output_customer_role_name) | Name of the IAM role created for CloudQuery/ClickHouse integration | -| [external_id](#output_external_id) | External ID used for role assumption (if provided) | -| [iam_policy_arn](#output_iam_policy_arn) | The ARN of the IAM policy for consumers | -| [iam_policy_id](#output_iam_policy_id) | The ID of the IAM policy for consumers | -| [iam_policy_name](#output_iam_policy_name) | The name of the IAM policy for consumers | -| [sqs_dlq_arn](#output_sqs_dlq_arn) | The ARN of the SQS dead-letter queue | -| [sqs_dlq_id](#output_sqs_dlq_id) | The ID of the SQS dead-letter queue | -| [sqs_dlq_url](#output_sqs_dlq_url) | The URL of the SQS dead-letter queue | -| [sqs_queue_arn](#output_sqs_queue_arn) | The ARN of the SQS queue | -| [sqs_queue_id](#output_sqs_queue_id) | The ID of the SQS queue | -| [sqs_queue_url](#output_sqs_queue_url) | The URL of the SQS queue | - +| Name | Description | +|------|-------------| +| [bucket\_notification\_id](#output\_bucket\_notification\_id) | The ID of the S3 bucket notification configuration | +| [customer\_role\_arn](#output\_customer\_role\_arn) | ARN of the IAM role created for CloudQuery/ClickHouse integration | +| [customer\_role\_name](#output\_customer\_role\_name) | Name of the IAM role created for CloudQuery/ClickHouse integration | +| [external\_id](#output\_external\_id) | External ID used for role assumption (if provided) | +| [iam\_policy\_arn](#output\_iam\_policy\_arn) | The ARN of the IAM policy for consumers | +| [iam\_policy\_id](#output\_iam\_policy\_id) | The ID of the IAM policy for consumers | +| [iam\_policy\_name](#output\_iam\_policy\_name) | The name of the IAM policy for consumers | +| [sqs\_dlq\_arn](#output\_sqs\_dlq\_arn) | The ARN of the SQS dead-letter queue | +| [sqs\_dlq\_id](#output\_sqs\_dlq\_id) | The ID of the SQS dead-letter queue | +| [sqs\_dlq\_url](#output\_sqs\_dlq\_url) | The URL of the SQS dead-letter queue | +| [sqs\_queue\_arn](#output\_sqs\_queue\_arn) | The ARN of the SQS queue | +| [sqs\_queue\_id](#output\_sqs\_queue\_id) | The ID of the SQS queue | +| [sqs\_queue\_url](#output\_sqs\_queue\_url) | The URL of the SQS queue | ## Security Best Practices From 83584d630a0ef635ed42275c6e1da3e83726bac8 Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:01:43 -0400 Subject: [PATCH 06/15] chore: update examples files --- platform-cx-s3-to-sqs/examples/dual-inegration/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf index 8631db5..e00e3e2 100644 --- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -24,7 +24,7 @@ locals { } module "dual_integration" { - source = "github.com/cloudquery/terraform-aws-s3-to-sqs" + source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name From 1ccbc407740dc5cf4088f54359a9da350ca62fac Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:08:50 -0400 Subject: [PATCH 07/15] chore: update paths for examples --- platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/dual-inegration/main.tf | 2 +- platform-cx-s3-to-sqs/providers.tf | 4 ---- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf index 0d58162..619c575 100644 --- a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -15,7 +15,7 @@ locals { } module "clickhouse_integration" { - source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + source = "../../platform-cx-s3-to-sqs" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf index fbc0a28..9a698c5 100644 --- a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf @@ -24,7 +24,7 @@ locals { } module "cloudquery_integration" { - source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + source = "../../platform-cx-s3-to-sqs" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf index e00e3e2..bc19e44 100644 --- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -24,7 +24,7 @@ locals { } module "dual_integration" { - source = "github.com/cloudquery/terraform-cloudquery-modules/platform-cx-s3-to-sqs" + source = "../../platform-cx-s3-to-sqs" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name diff --git a/platform-cx-s3-to-sqs/providers.tf b/platform-cx-s3-to-sqs/providers.tf index 6c843dc..dc58d9a 100644 --- a/platform-cx-s3-to-sqs/providers.tf +++ b/platform-cx-s3-to-sqs/providers.tf @@ -1,7 +1,3 @@ provider "aws" { region = var.region - - default_tags { - tags = var.tags - } } From 9aa0d2929c729b34f46ba1bd043469aee6c276c0 Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:12:38 -0400 Subject: [PATCH 08/15] chore: fix paths --- platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/dual-inegration/main.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf index 619c575..51a0b86 100644 --- a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -15,7 +15,7 @@ locals { } module "clickhouse_integration" { - source = "../../platform-cx-s3-to-sqs" + source = "../../" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf index 9a698c5..6be5e48 100644 --- a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf @@ -24,7 +24,7 @@ locals { } module "cloudquery_integration" { - source = "../../platform-cx-s3-to-sqs" + source = "../../" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf index bc19e44..9e6b21a 100644 --- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -24,7 +24,7 @@ locals { } module "dual_integration" { - source = "../../platform-cx-s3-to-sqs" + source = "../../" # Existing S3 bucket details s3_bucket_id = local.existing_bucket_name From bb85152db9119df6b3ccad2f35c605b6e42bc36c Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:15:19 -0400 Subject: [PATCH 09/15] chore: update outputs in examples --- platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf | 2 +- platform-cx-s3-to-sqs/examples/dual-inegration/main.tf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf index 51a0b86..e7be291 100644 --- a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -33,7 +33,7 @@ module "clickhouse_integration" { # Output the information needed to provide to ClickHouse output "role_arn" { description = "The ARN of the IAM role to provide to ClickHouse" - value = module.clickhouse_integration.customer_role_arn + value = module.clickhouse_integration.iam_role_arn } output "bucket_name" { diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf index 6be5e48..2bf0eec 100644 --- a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf @@ -48,7 +48,7 @@ module "cloudquery_integration" { # Output the information needed to provide to CloudQuery Platform output "role_arn" { description = "The ARN of the IAM role to provide to CloudQuery Platform" - value = module.cloudquery_integration.customer_role_arn + value = module.cloudquery_integration.iam_role_arn } output "role_external_id" { diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf index 9e6b21a..92c087a 100644 --- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -51,7 +51,7 @@ module "dual_integration" { # Output the configuration information output "role_arn" { description = "The ARN of the IAM role that CloudQuery and ClickHouse can assume" - value = module.dual_integration.customer_role_arn + value = module.dual_integration.iam_role_arn } output "external_id" { From 22e5cf2c50bbd04a21c2d13096d45ba97a8177e7 Mon Sep 17 00:00:00 2001 From: Steve Morgan <73501129+rebelopsio@users.noreply.github.com> Date: Tue, 25 Mar 2025 12:25:15 -0400 Subject: [PATCH 10/15] chore: small updates --- .../examples/clickhouse-integration/main.tf | 4 ---- .../examples/cloudquery-integration/main.tf | 12 ++++-------- .../examples/dual-inegration/main.tf | 14 +++++--------- platform-cx-s3-to-sqs/variables.tf | 5 +++++ 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf index e7be291..4b47dc5 100644 --- a/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -1,10 +1,6 @@ # Example for ClickHouse integration with existing S3 bucket # This creates an IAM role that allows ClickHouse to access your S3 data -provider "aws" { - region = "us-east-1" # Change to the region where your S3 bucket is located -} - locals { # ClickHouse IAM role ARN - THIS SHOULD BE THE ACTUAL ROLE ARN PROVIDED BY CLICKHOUSE clickhouse_role_arn = "arn:aws:iam::191110999071:role/CH-S3-steel-mv-95-ue1-42-Role" diff --git a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf index 2bf0eec..857590c 100644 --- a/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf @@ -4,10 +4,6 @@ # 2. S3 event notifications to the SQS queue # 3. An IAM role that CloudQuery Platform can assume to access both resources -provider "aws" { - region = "us-east-1" # Change to the region where your S3 bucket is located -} - # Generate a secure random external ID resource "random_id" "external_id" { byte_length = 8 @@ -39,10 +35,10 @@ module "cloudquery_integration" { filter_prefix = "uploads/" # Only monitor this prefix, remove if not needed # Create IAM role with appropriate trust policy for CloudQuery Platform - iam_role_name = "cloudquery-platform-s3-sqs-access" - cloudquery_role_arn = local.cloudquery_role_arn - require_external_id = true - external_id = "cloudquery-${random_id.external_id.hex}" # Secure random external ID + iam_role_name = "cloudquery-platform-s3-sqs-access" + cloudquery_platform_role_arn = local.cloudquery_role_arn + require_external_id = true + external_id = "cloudquery-${random_id.external_id.hex}" # Secure random external ID } # Output the information needed to provide to CloudQuery Platform diff --git a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf index 92c087a..a6e9710 100644 --- a/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -1,10 +1,6 @@ # Example for dual integration (CloudQuery Platform and ClickHouse) # This creates an IAM role that both services can assume to access your S3 and SQS resources -provider "aws" { - region = "us-west-2" # Change to your preferred region -} - # Generate a secure random external ID resource "random_id" "external_id" { byte_length = 8 @@ -36,11 +32,11 @@ module "dual_integration" { filter_prefix = "data/" # Optional: Filter events by prefix # Role configuration for both CloudQuery and ClickHouse - iam_role_name = "cloudquery-clickhouse-integration-role" - cloudquery_role_arn = local.cloudquery_role_arn - clickhouse_role_arn = local.clickhouse_role_arn - require_external_id = true - external_id = local.external_id + iam_role_name = "cloudquery-clickhouse-integration-role" + cloudquery_platform_role_arn = local.cloudquery_role_arn + clickhouse_role_arn = local.clickhouse_role_arn + require_external_id = true + external_id = local.external_id tags = { Environment = "production" diff --git a/platform-cx-s3-to-sqs/variables.tf b/platform-cx-s3-to-sqs/variables.tf index 3017c15..f6be4e0 100644 --- a/platform-cx-s3-to-sqs/variables.tf +++ b/platform-cx-s3-to-sqs/variables.tf @@ -165,6 +165,11 @@ variable "iam_policy_name" { # General #-------------------------------------------------------------- +variable "region" { + type = string + description = "The AWS region to deploy to" +} + variable "tags" { description = "A map of tags to assign to resources" type = map(string) From b314f9ba175c8498dec709140a80e8deb22b537b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]"
"s3:ObjectCreated:*"
]
list(object({
namespace = string
name = string
})) | `[]` | no |
| [sqs\_dlq\_arn](#input\_sqs\_dlq\_arn) | The ARN of the SQS dead-letter queue, if any | `string` | `null` | no |
+| [sqs\_queue\_arn](#input\_sqs\_queue\_arn) | The ARN of the SQS queue | `string` | n/a | yes |
| [tags](#input\_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no |
| [trusted\_account\_ids](#input\_trusted\_account\_ids) | List of AWS account IDs that are allowed to assume this role | `list(string)` | `[]` | no |
| [trusted\_role\_arns](#input\_trusted\_role\_arns) | List of ARNs of IAM roles that are allowed to assume this role | `list(string)` | `[]` | no |