diff --git a/platform-cx-s3-to-sqs/README.md b/platform-cx-s3-to-sqs/README.md new file mode 100644 index 0000000..68f3bc1 --- /dev/null +++ b/platform-cx-s3-to-sqs/README.md @@ -0,0 +1,202 @@ +# 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 | +|------|-------------|------|---------|:--------:| +| [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 | +| [region](#input\_region) | The AWS region to deploy to | `string` | n/a | yes | +| [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 | + + +## 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..48f7dda --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/clickhouse-integration/main.tf @@ -0,0 +1,56 @@ +# Example for ClickHouse integration with existing S3 bucket +# This creates an IAM role that allows ClickHouse to access your S3 data + +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 = "../../" + + # Region where the resources will be created + region = "us-west-2" + + # 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 + iam_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)` |
{
"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..9962224 --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/cloudquery-integration/main.tf @@ -0,0 +1,86 @@ +# 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 + +# 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 = "../../" + + # Region where the resources will be created + region = "us-west-2" + + # 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 + 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 +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..7ad056a --- /dev/null +++ b/platform-cx-s3-to-sqs/examples/dual-inegration/main.tf @@ -0,0 +1,85 @@ +# 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 + +# 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 = "../../" + + # Region where the resources will be created + region = "us-west-2" + + # 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 + 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" + 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 = < +## 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_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.additional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_policy_document.s3_sqs_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.trust_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [additional\_policy\_arns](#input\_additional\_policy\_arns) | List of additional policy ARNs to attach to the role | `list(string)` | `[]` | no | +| [create\_instance\_profile](#input\_create\_instance\_profile) | Whether to create an instance profile for the role | `bool` | `false` | no | +| [create\_policy](#input\_create\_policy) | Whether to create the IAM policy | `bool` | `true` | no | +| [create\_role](#input\_create\_role) | Whether to create the IAM role | `bool` | `true` | no | +| [custom\_assume\_role\_policy](#input\_custom\_assume\_role\_policy) | A custom assume role policy JSON. If provided, this will be used instead of the generated one | `string` | `null` | no | +| [external\_id](#input\_external\_id) | External ID to use when other accounts assume this role | `string` | `""` | no | +| [instance\_profile\_name](#input\_instance\_profile\_name) | Name of the instance profile. If not provided, will use role\_name | `string` | `null` | no | +| [max\_session\_duration](#input\_max\_session\_duration) | Maximum session duration (in seconds) for the role | `number` | `3600` | no | +| [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | ARN of the OIDC provider for IRSA (IAM Roles for Service Accounts) | `string` | `null` | no | +| [oidc\_provider\_url](#input\_oidc\_provider\_url) | URL of the OIDC provider for IRSA, without the https:// prefix | `string` | `null` | no | +| [path](#input\_path) | Path for the role and policy | `string` | `"/"` | no | +| [permissions\_boundary](#input\_permissions\_boundary) | ARN of the permissions boundary to use for the role | `string` | `null` | no | +| [policy\_description](#input\_policy\_description) | Description of the IAM policy | `string` | `null` | no | +| [policy\_name](#input\_policy\_name) | Name of the IAM policy to create. If not provided, will use role\_name-policy | `string` | `null` | no | +| [require\_external\_id](#input\_require\_external\_id) | Whether to require an external ID when other accounts assume this role | `bool` | `false` | no | +| [role\_description](#input\_role\_description) | Description of the IAM role | `string` | `"Role for accessing S3 bucket and SQS queues"` | no | +| [role\_name](#input\_role\_name) | Name of the IAM role | `string` | n/a | yes | +| [s3\_bucket\_arn](#input\_s3\_bucket\_arn) | The ARN of the S3 bucket | `string` | n/a | yes | +| [service\_accounts](#input\_service\_accounts) | List of Kubernetes service account objects that are allowed to assume this role via IRSA |
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 | +| [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/provider.tf b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/provider.tf new file mode 100644 index 0000000..dc58d9a --- /dev/null +++ b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/provider.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +} 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/modules/iam-role-for-serviceaccount/versions.tf b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/versions.tf new file mode 100644 index 0000000..2aa1770 --- /dev/null +++ b/platform-cx-s3-to-sqs/modules/iam-role-for-serviceaccount/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0.0" + } + } +} 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/providers.tf b/platform-cx-s3-to-sqs/providers.tf new file mode 100644 index 0000000..dc58d9a --- /dev/null +++ b/platform-cx-s3-to-sqs/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +} diff --git a/platform-cx-s3-to-sqs/variables.tf b/platform-cx-s3-to-sqs/variables.tf new file mode 100644 index 0000000..f6be4e0 --- /dev/null +++ b/platform-cx-s3-to-sqs/variables.tf @@ -0,0 +1,207 @@ +################################################################################ +# 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 "region" { + type = string + description = "The AWS region to deploy to" +} + +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 "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" +} diff --git a/platform-cx-s3-to-sqs/versions.tf b/platform-cx-s3-to-sqs/versions.tf new file mode 100644 index 0000000..97f0cf5 --- /dev/null +++ b/platform-cx-s3-to-sqs/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0.0" + } + } +}