diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml deleted file mode 100644 index 9a21ebf..0000000 --- a/.github/workflows/pre-commit.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: "Run Pre Commit Checks" - -on: # yamllint disable-line rule:truthy - push: - branches: - - '**' - - '!main' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - ## run pre-commit - pre-commit: - name: Run pre-commit checks - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - actions: write - pages: write - id-token: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - token: ${{ secrets.ARC_JOB_TOKEN }} - - - uses: actions/setup-python@v3 - - - name: Install terraform-docs - run: | - cd /tmp - curl -sSLo ./terraform-docs.tar.gz \ - https://terraform-docs.io/dl/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz - tar -xzf terraform-docs.tar.gz - rm terraform-docs.tar.gz - chmod +x terraform-docs - mv terraform-docs /usr/local/bin/terraform-docs - - name: Install tflint - run: | - cd /tmp - curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash - - name: Run pre-commit - uses: pre-commit/action@v3.0.0 - continue-on-error: true # we want to push the changes pre-commit makes - - - name: Push pre-commit changes to branch - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: Push pre-commit changes diff --git a/.github/workflows/snyk.yaml b/.github/workflows/snyk.yaml deleted file mode 100644 index eb42d59..0000000 --- a/.github/workflows/snyk.yaml +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: snyk - -on: # yamllint disable-line rule:truthy - push: - branches: - - "**" # matches every branch - - "!main" # excludes main - pull_request: - branches: - - main - -jobs: - security: - runs-on: ubuntu-latest - name: snyk - steps: - - name: checkout - uses: actions/checkout@v3 - - name: Vulnerability scan - uses: snyk/actions/iac@master - with: - command: monitor - args: --severity-threshold=low - - name: Set up Node 18 - uses: actions/setup-node@v4 - with: - node-version: 18 - - name: install Snyk CLI - run: npm install -g snyk - - name: snyk monitor - run: snyk iac test --report - env: - SNYK_TOKEN: ${{ secrets.ARC_SNYK_TOKEN }} diff --git a/.gitignore b/.gitignore index cd9c25d..bb68928 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .terraform terraform.tfstate *.tfstate* -terraform.tfvars *.backup .idea .external_momdules diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 1ff9a8d..1c4f1f6 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,67 +2,44 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "4.67.0" - constraints = ">= 2.0.0, >= 3.0.0, ~> 4.0" + version = "5.100.0" + constraints = ">= 5.0.0, ~> 5.0" hashes = [ - "h1:P43vwcDPG99x5WBbmqwUPgfJrfXf6/ucAIbGlRb7k1w=", - "h1:dCRc4GqsyfqHEMjgtlM1EympBcgTmcTkWaJmtd91+KA=", - "zh:0843017ecc24385f2b45f2c5fce79dc25b258e50d516877b3affee3bef34f060", - "zh:19876066cfa60de91834ec569a6448dab8c2518b8a71b5ca870b2444febddac6", - "zh:24995686b2ad88c1ffaa242e36eee791fc6070e6144f418048c4ce24d0ba5183", - "zh:4a002990b9f4d6d225d82cb2fb8805789ffef791999ee5d9cb1fef579aeff8f1", - "zh:559a2b5ace06b878c6de3ecf19b94fbae3512562f7a51e930674b16c2f606e29", - "zh:6a07da13b86b9753b95d4d8218f6dae874cf34699bca1470d6effbb4dee7f4b7", - "zh:768b3bfd126c3b77dc975c7c0e5db3207e4f9997cf41aa3385c63206242ba043", - "zh:7be5177e698d4b547083cc738b977742d70ed68487ce6f49ecd0c94dbf9d1362", - "zh:8b562a818915fb0d85959257095251a05c76f3467caa3ba95c583ba5fe043f9b", + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9c385d03a958b54e2afd5279cd8c7cbdd2d6ca5c7d6a333e61092331f38af7cf", - "zh:b3ca45f2821a89af417787df8289cb4314b273d29555ad3b2a5ab98bb4816b3b", - "zh:da3c317f1db2469615ab40aa6baba63b5643bae7110ff855277a1fb9d8eb4f2c", - "zh:dc6430622a8dc5cdab359a8704aec81d3825ea1d305bbb3bbd032b1c6adfae0c", - "zh:fac0d2ddeadf9ec53da87922f666e1e73a603a611c57bcbc4b86ac2821619b1d", - ] -} - -provider "registry.terraform.io/hashicorp/local" { - version = "2.4.1" - constraints = ">= 1.3.0" - hashes = [ - "h1:FzraUapGrJoH3ZOWiUT2m6QpZAD+HmU+JmqZgM4/o2Y=", - "h1:V2G4qygMV0uHy+QTMlrjSyYgzpYmYyB6gWuE09+5CPI=", - "zh:244b445bf34ddbd167731cc6c6b95bbed231dc4493f8cc34bd6850cfe1f78528", - "zh:3c330bdb626123228a0d1b1daa6c741b4d5d484ab1c7ae5d2f48d4c9885cc5e9", - "zh:5ff5f9b791ddd7557e815449173f2db38d338e674d2d91800ac6e6d808de1d1d", - "zh:70206147104f4bf26ae67d730c995772f85bf23e28c2c2e7612c74f4dae3c46f", - "zh:75029676993accd6bef933c196b2fad51a9ec8a69a847dbbe96ec8ebf7926cdc", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7d48d5999fe1fcdae9295a7c3448ac1541f5a24c474bd82df6d4fa3732483f2b", - "zh:b766b38b027f0f84028244d1c2f990431a37d4fc3ac645962924554016507e77", - "zh:bfc7ad301dada204cf51c59d8bd6a9a87de5fddb42190b4d6ba157d6e08a1f10", - "zh:c902b527702a8c5e2c25a6637d07bbb1690cb6c1e63917a5f6dc460efd18d43f", - "zh:d68ae0e1070cf429c46586bc87580c3ed113f76241da2b6e4f1a8348126b3c46", - "zh:f4903fd89f7c92a346ae9e666c2d0b6884c4474ae109e9b4bd15e7efaa4bfc29", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", ] } provider "registry.terraform.io/hashicorp/random" { - version = "3.6.0" - constraints = ">= 1.0.0" + version = "3.7.2" + constraints = ">= 3.1.0" hashes = [ - "h1:R5Ucn26riKIEijcsiOMBR3uOAjuOMfI1x7XvH4P6B1w=", - "h1:p6WG1IPHnqx1fnJVKNjv733FBaArIugqy58HRZnpPCk=", - "zh:03360ed3ecd31e8c5dac9c95fe0858be50f3e9a0d0c654b5e504109c2159287d", - "zh:1c67ac51254ba2a2bb53a25e8ae7e4d076103483f55f39b426ec55e47d1fe211", - "zh:24a17bba7f6d679538ff51b3a2f378cedadede97af8a1db7dad4fd8d6d50f829", - "zh:30ffb297ffd1633175d6545d37c2217e2cef9545a6e03946e514c59c0859b77d", - "zh:454ce4b3dbc73e6775f2f6605d45cee6e16c3872a2e66a2c97993d6e5cbd7055", + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:91df0a9fab329aff2ff4cf26797592eb7a3a90b4a0c04d64ce186654e0cc6e17", - "zh:aa57384b85622a9f7bfb5d4512ca88e61f22a9cea9f30febaa4c98c68ff0dc21", - "zh:c4a3e329ba786ffb6f2b694e1fd41d413a7010f3a53c20b432325a94fa71e839", - "zh:e2699bc9116447f96c53d55f2a00570f982e6f9935038c3810603572693712d0", - "zh:e747c0fd5d7684e5bfad8aa0ca441903f15ae7a98a737ff6aca24ba223207e2c", - "zh:f1ca75f417ce490368f047b63ec09fd003711ae48487fba90b4aba2ccf71920e", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 38fdae3..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,135 +0,0 @@ -# Contributing to AWS ARC Document DB -Thank you for considering contributing to AWS ARC Document DB! We appreciate your time and effort. -To ensure a smooth collaboration, please take a moment to review the following guidelines. - -## How to Contribute -1. Fork the repository to your own GitHub account. -2. Clone the repository to your local machine. - ```bash - git clone https://github.com//.git - ``` -3. Create a new branch for your feature / bugfix. - ```bash - git checkout -b feature/branch_name - ``` -4. Make your changes and commit them. - ```bash - git commit -m "Your descriptive commit message" - -5. Run pre-commit checks - ```bash - pre-commit run --all-files - -6. Push to your forked repository. - ```bash - git push origin feature/branch_name - ``` -7. Open a pull request in the original repository with a clear title and description. - If your pull request addresses an issue, please reference the issue number in the pull request description. - -## Git commits -while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch - -For Example - -```sh -git commit -m "your commit message #major" -``` -By specifying this , it will bump the version and if you don't specify this in your commit message then by default it will consider patch and will bump that accordingly - -# Terraform Code Collaboration Guidelines - -## File Naming Conventions - -1. **Variables File (variables.tf):** - - All variable names should be in snake_case. - - Each variable declaration must contain: - - Description: A brief explanation of the variable's purpose. - - Type: The data type of the variable. - - Example: - ```hcl - variable "example_variable" { - description = "This is an example variable." - type = string - } - ``` - -2. **Outputs File (outputs.tf):** - - All output names should be in snake_case. - - Each output declaration must contain: - - Description: A brief explanation of the output's purpose. - - Value: The value that will be exposed as the output. - - Example: - ```hcl - output "example_output" { - description = "This is an example output." - value = module.example_module.example_attribute - } - ``` - -## Resource and Module Naming - -1. **Terraform Resources/Modules:** - - Resource and module names should be in snake_case. - - Choose descriptive names that reflect the purpose of the resource or module. - - Example: - ```hcl - resource "aws_instance" "web_server" { - // ... - } - - module "document_db" { - // ... - } - ``` - -## General Guidelines - -1. **Consistent Formatting:** - - Follow consistent code formatting to enhance readability. - - Use indentation and line breaks appropriately. - -2. **Comments:** - - Add comments to explain complex logic, decisions, or any non-trivial code. - - Keep comments up-to-date with the code. - -3. **Module Documentation:** - - Include a README.md file within each module directory, explaining its purpose, inputs, and outputs. - - Use inline documentation within the code for complex modules. - -4. **Avoid Hardcoding:** - - Minimize hardcoded values; prefer using variables and references for increased flexibility. - -5. **Sensitive Information:** - - Do not hardcode sensitive information (e.g., passwords, API keys). Use appropriate methods for securing sensitive data. - -6. **Error Handling:** - - Implement proper error handling and consider the impact of potential failures. - -## Version Control - -1. **Commit Messages:** - - Use descriptive and concise commit messages that explain the purpose of the changes. - -2. **Branching:** - - Follow a branching strategy (e.g., feature branches) for better collaboration. - -## Code Style -Please follow the Terraform language conventions and formatting guidelines. Consider using an editor with Terraform support or a linter to ensure adherence to the style. - -## Testing -!!! This section is a work-in-progress, as we are starting to adopt testing using Terratest. !!! - -Before submitting a pull request, ensure that your changes pass all tests. If applicable, add new tests to cover your changes. - -## Documentation -Keep the module documentation up-to-date. If you add new features or change existing functionality, update the [README](README.md) and any relevant documentation files. - -## Security and Compliance Checks -GitHub Actions are in place to perform security and compliance checks. Please make sure your changes pass these checks before submitting a pull request. - -## Licensing -By contributing, you agree that your contributions will be licensed under the project's [LICENSE](LICENSE). diff --git a/README.md b/README.md index 647816d..3935269 100644 --- a/README.md +++ b/README.md @@ -6,156 +6,515 @@ [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=sourcefuse_terraform-aws-arc-document-db)](https://sonarcloud.io/summary/new_code?id=sourcefuse_terraform-aws-arc-document-db) -[![snyk](https://github.com/sourcefuse/terraform-aws-arc-document-db/actions/workflows/snyk.yaml/badge.svg)](https://github.com/sourcefuse/terraform-aws-arc-document-db/actions/workflows/snyk.yaml) ## Overview -The SourceFuse AWS Reference Architecture (ARC) Terraform module for managing AWS DocumentDB offers a streamlined solution for provisioning, configuring, and managing DocumentDB clusters within the Amazon Web Services (AWS) environment. This Terraform module is specifically designed to simplify the deployment and maintenance of DocumentDB. +The SourceFuse AWS Reference Architecture (ARC) Terraform module for managing AWS DocumentDB offers a streamlined solution for provisioning, configuring, and managing DocumentDB clusters within the Amazon Web Services (AWS) environment. This Terraform module is specifically designed to simplify the deployment and maintenance of DocumentDB clusters with enterprise-grade features including: + +- **Multi-AZ Deployment**: High availability across multiple availability zones +- **Global Clusters**: Cross-region replication for disaster recovery +- **Security**: Encryption at rest and in transit, VPC security groups, and Secrets Manager integration +- **Monitoring**: CloudWatch logs, metrics, and event subscriptions +- **Backup & Recovery**: Automated backups with configurable retention periods +- **Parameter Groups**: Custom database parameter configurations For more information about this repository and its usage, please see [Terraform AWS ARC Document DB Usage Guide](https://github.com/sourcefuse/terraform-aws-arc-document-db/blob/main/docs/module-usage-guide/README.md). ## Usage -To see a full example, check out the [main.tf](https://github.com/sourcefuse/terraform-aws-arc-document-db/blob/main/example/main.tf) file in the example folder. +To see full examples, check out the [examples](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/examples) folder. + + +## Examples + +### [Basic Cluster](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/examples/basic-cluster) + +This example demonstrates a simple DocumentDB cluster setup with basic configuration: + +- Single-AZ deployment +- Basic security group configuration +- Standard backup settings +- Minimal configuration for development/testing + +```hcl +module "documentdb_cluster" { + source = "sourcefuse/arc-document-db/aws" + + cluster_identifier = var.cluster_identifier + master_username = var.master_username + + instance_count = var.instance_count + instance_class = var.instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.private.ids + } + vpc_id = data.aws_vpc.vpc.id + + security_group_data = local.security_group_data + + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + skip_final_snapshot = var.skip_final_snapshot + + storage_encrypted = var.storage_encrypted + deletion_protection = var.deletion_protection + + tags = module.tags.tags +} +``` + +### [Multi-AZ Cluster](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/examples/multi-az-cluster) + +This example shows a production-ready multi-AZ DocumentDB cluster with advanced features: + +- Multiple instances across availability zones +- Secrets Manager integration for credential management +- KMS encryption with custom keys +- CloudWatch monitoring and alarms +- Custom parameter groups + +```hcl +module "documentdb_cluster" { + source = "sourcefuse/arc-document-db/aws" + +cluster_identifier = var.cluster_identifier + master_username = var.master_username + + instance_count = var.instance_count + instance_class = var.instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.private.ids + } + vpc_id = data.aws_vpc.main.id + + security_group_data = local.security_group_data + + # Enable Secrets Manager integration + secret_config = { + create = true + name = null # Use auto-generated name with random suffix + recovery_window_in_days = var.secret_recovery_window_in_days + } + + # Enable KMS encryption + kms_config = { + create_key = true + description = var.kms_key_description + } + + # Enhanced backup configuration + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + + storage_encrypted = true + deletion_protection = var.deletion_protection + skip_final_snapshot = true + + # Enable CloudWatch logs + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + # Parameter group configuration + parameter_group_config = { + create = true + family = var.db_cluster_parameter_group_family + parameters = var.db_cluster_parameter_group_parameters + } + + tags = module.tags.tags +} + +``` + +### [Global Cluster Multi-Region](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/examples/global-cluster-multi-region) + +This example demonstrates a global DocumentDB cluster spanning multiple AWS regions: + +- Primary cluster in us-east-1 +- Secondary cluster in us-east-2 +- Cross-region replication +- Region-specific configurations +- Disaster recovery setup + +```hcl +# Primary cluster in us-east-1 +module "primary_cluster" { + source = "sourcefuse/arc-document-db/aws" + + providers = { + aws = aws.primary + } + + cluster_identifier = var.primary_cluster_identifier + master_username = var.master_username + + instance_count = var.primary_instance_count + instance_class = var.primary_instance_class -```tcl -module "example_doc_db_cluster" { - source = "sourcefuse/arc-document-db/aws" - // we recommend to pin the version we aren't simply for an example reference against our latest changes. - namespace = var.namespace - environment = var.environment + subnet_config = { + subnet_ids = data.aws_subnets.primary_private.ids + } + vpc_id = data.aws_vpc.primary.id + # Use security group rules + security_group_data = local.primary_security_group_data - doc_db_cluster_name = var.doc_db_cluster_name - cluster_size = var.cluster_size - master_username = var.master_username - instance_class = var.instance_class - vpc_id = data.aws_vpc.vpc_id.id - subnet_ids = data.aws_subnets.private.ids + # Global cluster configuration + create_global_cluster = true + global_cluster_identifier = var.global_cluster_identifier + + # Security features + secret_config = { + create = true + } + kms_config = { + create_key = true + } + storage_encrypted = true + deletion_protection = var.deletion_protection + + # Monitoring + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + # Enhanced backup + backup_retention_period = var.backup_retention_period + skip_final_snapshot = var.skip_final_snapshot tags = module.tags.tags +} + +# Secondary cluster in us-west-2 +module "secondary_cluster" { + source = "../../" + + providers = { + aws = aws.secondary + } + + cluster_identifier = var.secondary_cluster_identifier + + instance_count = var.secondary_instance_count + instance_class = var.secondary_instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.secondary_private.ids + } + vpc_id = data.aws_vpc.secondary.id + + # Use security group rules + security_group_data = local.secondary_security_group_data + + # Global cluster configuration + existing_global_cluster_identifier = module.primary_cluster.global_cluster_identifier + is_secondary_cluster = true + # Security features (inherit from global cluster) + kms_config = { + create_key = true + } + storage_encrypted = true + deletion_protection = var.deletion_protection + skip_final_snapshot = var.skip_final_snapshot + + # Monitoring + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + tags = module.tags.tags + + depends_on = [module.primary_cluster] } + ``` - +## Features + +### Core Features +- **DocumentDB Cluster Management**: Complete lifecycle management of DocumentDB clusters +- **Instance Configuration**: Flexible instance count and class configuration +- **Network Security**: VPC integration with security group management +- **Backup & Recovery**: Automated backup with configurable retention and windows + +### Advanced Features +- **Global Clusters**: Cross-region replication for disaster recovery +- **Secrets Manager Integration**: Secure credential management +- **KMS Encryption**: Custom encryption key management +- **Parameter Groups**: Custom database parameter configurations +- **CloudWatch Integration**: Comprehensive monitoring and logging +- **Event Subscriptions**: SNS notifications for database events + +### Security Features +- **Encryption**: At-rest and in-transit encryption +- **Network Isolation**: VPC and security group integration +- **Access Control**: IAM integration and credential management +- **Audit Logging**: Comprehensive audit trail + +## Configuration Options + +### Consolidated Variables + +This module uses consolidated configuration objects to reduce complexity and improve usability: + +#### `kms_config` +```hcl +kms_config = { + create_key = true + key_id = null + description = "DocumentDB encryption key" +} +``` + +#### `subnet_config` +```hcl +subnet_config = { + group_name = null + create_group = true + subnet_ids = ["subnet-12345", "subnet-67890"] +} +``` + +#### `secret_config` +```hcl +secret_config = { + create = true + name = null + description = "DocumentDB credentials" + recovery_window_in_days = 7 +} +``` + +#### `parameter_group_config` +```hcl +parameter_group_config = { + create = true + family = "docdb4.0" + parameters = [ + { + name = "tls" + value = "enabled" + } + ] +} +``` + +#### `alarm_config` +```hcl +alarm_config = { + create_alarms = true + cpu = { + threshold = 80 + evaluation_periods = 2 + period = 300 + } + connections = { + threshold = 80 + evaluation_periods = 2 + period = 300 + } + alarm_actions = ["arn:aws:sns:us-east-1:123456789012:alerts"] +} +``` + +#### `event_subscription_config` +```hcl +event_subscription_config = { + create = true + name = "docdb-events" + sns_topic_arn = "arn:aws:sns:us-east-1:123456789012:docdb-events" + enabled = true + source_type = "db-cluster" + event_categories = ["backup", "failure", "maintenance"] +} +``` + ## Requirements | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | -| [aws](#requirement\_aws) | >= 4.0, < 6.0 | +| [aws](#requirement\_aws) | >= 5.0, < 7.0 | +| [random](#requirement\_random) | >= 3.1 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | 4.67.0 | +| [aws](#provider\_aws) | 5.100.0 | +| [random](#provider\_random) | 3.7.2 | ## Modules | Name | Source | Version | |------|--------|---------| -| [doc\_db\_cluster](#module\_doc\_db\_cluster) | cloudposse/documentdb-cluster/aws | 0.24.0 | +| [kms](#module\_kms) | sourcefuse/arc-kms/aws | 0.0.1 | +| [security\_group](#module\_security\_group) | sourcefuse/arc-security-group/aws | 0.0.2 | ## Resources | Name | Type | |------|------| -| [aws_ssm_parameter.documentdb_host](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | -| [aws_ssm_parameter.documentdb_port](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | -| [aws_ssm_parameter.documentdb_username](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [aws_cloudwatch_log_group.audit](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_cloudwatch_log_group.profiler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_cloudwatch_metric_alarm.cpu_utilization](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | +| [aws_cloudwatch_metric_alarm.database_connections](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | +| [aws_docdb_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster) | resource | +| [aws_docdb_cluster_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster_instance) | resource | +| [aws_docdb_cluster_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_cluster_parameter_group) | resource | +| [aws_docdb_event_subscription.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_event_subscription) | resource | +| [aws_docdb_global_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_global_cluster) | resource | +| [aws_docdb_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/docdb_subnet_group) | resource | +| [aws_iam_role.enhanced_monitoring](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.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_secretsmanager_secret.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | +| [aws_secretsmanager_secret_version.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | +| [random_id.secret_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [random_password.master](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks to be allowed to connect to the DocumentDB cluster | `list(string)` | `[]` | no | -| [allowed\_security\_groups](#input\_allowed\_security\_groups) | List of existing Security Groups to be allowed to connect to the DocumentDB cluster | `list(string)` | `[]` | no | +| [additional\_policy\_arns](#input\_additional\_policy\_arns) | List of additional IAM policy ARNs to attach to the Lambda role | `list(string)` | `[]` | no | +| [alarm\_config](#input\_alarm\_config) | CloudWatch alarm configuration for DocumentDB monitoring |
object({
create_alarms = optional(bool, false)
cpu = optional(object({
threshold = optional(number, 80)
evaluation_periods = optional(number, 2)
period = optional(number, 300)
}), {})
connections = optional(object({
threshold = optional(number, 80)
evaluation_periods = optional(number, 2)
period = optional(number, 300)
}), {})
alarm_actions = optional(list(string), [])
ok_actions = optional(list(string), [])
})
| `{}` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Enable to allow major engine version upgrades when changing engine versions | `bool` | `false` | no | | [apply\_immediately](#input\_apply\_immediately) | Specifies whether any cluster modifications are applied immediately, or during the next maintenance window | `bool` | `true` | no | -| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Specifies whether any minor engine upgrades will be applied automatically to the DB instance during the maintenance window or not | `bool` | `true` | no | -| [cluster\_dns\_name](#input\_cluster\_dns\_name) | Name of the cluster CNAME record to create in the parent DNS zone specified by `zone_id`. If left empty, the name will be auto-asigned using the format `master.var.name` | `string` | `""` | no | -| [cluster\_family](#input\_cluster\_family) | The family of the DocumentDB cluster parameter group. For more details, see https://docs.aws.amazon.com/documentdb/latest/developerguide/db-cluster-parameter-group-create.html | `string` | `"docdb3.6"` | no | -| [cluster\_parameters](#input\_cluster\_parameters) | List of DB parameters to apply |
list(object({
apply_method = string
name = string
value = string
}))
| `[]` | no | -| [cluster\_size](#input\_cluster\_size) | Number of DB instances to create in the cluster | `number` | n/a | yes | -| [db\_port](#input\_db\_port) | The port on which the DB accepts connections | `number` | `27017` | no | -| [doc\_db\_cluster\_name](#input\_doc\_db\_cluster\_name) | Name of the DB cluster | `string` | n/a | yes | -| [documentdb\_host](#input\_documentdb\_host) | The name for the DocumentDB host SSM parameter | `string` | `"/arc/doc_db/host"` | no | -| [documentdb\_port](#input\_documentdb\_port) | The name for the DocumentDB port SSM parameter | `string` | `"/arc/doc_db/port"` | no | -| [documentdb\_username](#input\_documentdb\_username) | The name for the DocumentDB username SSM parameter | `string` | `"/arc/doc_db/username"` | no | -| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to cloudwatch. The following log types are supported: `audit`, `error`, `general`, `slowquery` | `list(string)` | `[]` | no | -| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster. Defaults to `docdb`. Valid values: `docdb` | `string` | `"docdb"` | no | -| [engine\_version](#input\_engine\_version) | The version number of the database engine to use | `string` | `"3.6.0"` | no | -| [environment](#input\_environment) | environment value, e.g 'prod', 'staging', 'dev', 'UAT' | `string` | `""` | no | -| [instance\_class](#input\_instance\_class) | Instance class to use for the DB instances in the cluster | `string` | n/a | yes | -| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true` | `string` | `""` | no | -| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | n/a | yes | -| [namespace](#input\_namespace) | Namespace for the resources. | `string` | n/a | yes | -| [preferred\_backup\_window](#input\_preferred\_backup\_window) | Daily time range during which the backups happen | `string` | `"07:00-09:00"` | no | -| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The window to perform maintenance in. Syntax: `ddd:hh24:mi-ddd:hh24:mi`. | `string` | `"Mon:22:00-Mon:23:00"` | no | -| [reader\_dns\_name](#input\_reader\_dns\_name) | Name of the reader endpoint CNAME record to create in the parent DNS zone specified by `zone_id`. If left empty, the name will be auto-asigned using the format `replicas.var.name` | `string` | `""` | no | -| [retention\_period](#input\_retention\_period) | Number of days to retain backups for | `number` | `5` | no | -| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Determines whether a final DB snapshot is created before the DB cluster is deleted | `bool` | `true` | no | -| [snapshot\_identifier](#input\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `""` | no | -| [ssm\_parameter\_enabled](#input\_ssm\_parameter\_enabled) | Whether to create an SSM parameter for the master password | `bool` | `true` | no | -| [ssm\_parameter\_path\_prefix](#input\_ssm\_parameter\_path\_prefix) | The path prefix for the created SSM parameter e.g. '/docdb/master-password/dev'. `ssm_parameter_enabled` must be set to `true` for this to take affect. | `string` | `"/arc/doc_db/master_password/"` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB cluster during the maintenance window | `bool` | `true` | no | +| [availability\_zones](#input\_availability\_zones) | A list of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created | `list(string)` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `7` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [cloudwatch\_log\_kms\_key\_id](#input\_cloudwatch\_log\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_retention\_in\_days](#input\_cloudwatch\_log\_retention\_in\_days) | Specifies the number of days you want to retain log events in the specified log group | `number` | `7` | no | +| [cluster\_identifier](#input\_cluster\_identifier) | The cluster identifier. If omitted, Terraform will assign a random, unique identifier | `string` | `null` | no | +| [cluster\_identifier\_prefix](#input\_cluster\_identifier\_prefix) | Creates a unique cluster identifier beginning with the specified prefix | `string` | `null` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | Copy all Cluster tags to snapshots | `bool` | `false` | no | +| [create\_global\_cluster](#input\_create\_global\_cluster) | Whether to create a DocumentDB Global Cluster | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Whether to create an IAM role for enhanced monitoring | `bool` | `false` | no | +| [create\_security\_group](#input\_create\_security\_group) | Whether to create a security group for the DocumentDB cluster | `bool` | `true` | no | +| [database\_name](#input\_database\_name) | The name of the database to create when the DB cluster is created | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_description](#input\_db\_cluster\_parameter\_group\_description) | Description for the DB cluster parameter group | `string` | `"DocumentDB cluster parameter group"` | no | +| [db\_parameter\_group\_name](#input\_db\_parameter\_group\_name) | Name of the DB parameter group to associate with instances | `string` | `null` | no | +| [db\_subnet\_group\_description](#input\_db\_subnet\_group\_description) | Description for the DB subnet group | `string` | `"DocumentDB subnet group"` | no | +| [deletion\_protection](#input\_deletion\_protection) | A value that indicates whether the DB cluster has deletion protection enabled | `bool` | `false` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to cloudwatch | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster | `string` | `"docdb"` | no | +| [engine\_version](#input\_engine\_version) | The database engine version | `string` | `"4.0.0"` | no | +| [environment](#input\_environment) | Environment name | `string` | `"dev"` | no | +| [event\_subscription\_config](#input\_event\_subscription\_config) | Configuration for RDS event subscription |
object({
create = optional(bool, false)
name = optional(string, null)
sns_topic_arn = optional(string, null)
enabled = optional(bool, true)
source_type = optional(string, "db-cluster")
source_ids = optional(list(string), [])
event_categories = optional(list(string), [])
})
| `{}` | no | +| [existing\_global\_cluster\_identifier](#input\_existing\_global\_cluster\_identifier) | The identifier of an existing global cluster to join | `string` | `null` | no | +| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB cluster is deleted | `string` | `null` | no | +| [force\_overwrite\_replica\_secret](#input\_force\_overwrite\_replica\_secret) | Accepts boolean value to specify whether to overwrite a secret with the same name in the destination Region | `bool` | `false` | no | +| [global\_cluster\_identifier](#input\_global\_cluster\_identifier) | The global cluster identifier | `string` | `null` | no | +| [instance\_availability\_zones](#input\_instance\_availability\_zones) | List of availability zones for instances. If not specified, instances will be distributed across available AZs | `list(string)` | `null` | no | +| [instance\_class](#input\_instance\_class) | The instance class to use | `string` | `"db.t3.medium"` | no | +| [instance\_count](#input\_instance\_count) | Number of instances in the cluster | `number` | `1` | no | +| [instance\_identifier\_prefix](#input\_instance\_identifier\_prefix) | Creates a unique identifier beginning with the specified prefix | `string` | `null` | no | +| [instance\_promotion\_tiers](#input\_instance\_promotion\_tiers) | Map of instance index to promotion tier (0-15). Lower number = higher priority for promotion | `map(number)` | `{}` | no | +| [is\_secondary\_cluster](#input\_is\_secondary\_cluster) | Whether this cluster is a secondary cluster in a global cluster | `bool` | `false` | no | +| [kms\_config](#input\_kms\_config) | KMS configuration for DocumentDB encryption |
object({
key_id = optional(string, null)
create_key = optional(bool, false)
description = optional(string, "DocumentDB cluster encryption key")
})
| `{}` | no | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager | `bool` | `true` | no | +| [master\_password](#input\_master\_password) | Password for the master DB user. If not provided and create\_secret is true, will be auto-generated | `string` | `null` | no | +| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `"docdbadmin"` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval for collecting enhanced monitoring metrics. Valid values: 0, 1, 5, 10, 15, 30, 60 | `number` | `0` | no | +| [name\_prefix](#input\_name\_prefix) | Name prefix for resources | `string` | `"docdb"` | no | +| [parameter\_group\_config](#input\_parameter\_group\_config) | DB cluster parameter group configuration |
object({
name = optional(string, null)
create = optional(bool, false)
family = optional(string, "docdb4.0")
parameters = optional(list(object({
name = string
value = string
})), [])
})
| `{}` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `number` | `27017` | no | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created | `string` | `"07:00-09:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur | `string` | `"sun:05:00-sun:06:00"` | no | +| [replica\_kms\_key\_id](#input\_replica\_kms\_key\_id) | KMS key ID for replica secret encryption | `string` | `null` | no | +| [replica\_region](#input\_replica\_region) | Region for replicating the secret | `string` | `null` | no | +| [secret\_config](#input\_secret\_config) | Secrets Manager configuration for DocumentDB credentials |
object({
create = optional(bool, false)
name = optional(string, null)
description = optional(string, "DocumentDB cluster master credentials")
recovery_window_in_days = optional(number, 7)
})
| `{}` | no | +| [secret\_version\_stages](#input\_secret\_version\_stages) | Specifies text data that you want to encrypt and store in this version of the secret | `list(string)` | `null` | no | +| [security\_group\_data](#input\_security\_group\_data) | (optional) Security Group data |
object({
security_group_ids_to_attach = optional(list(string), [])
create = optional(bool, true)
description = optional(string, null)
ingress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
source_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
self = optional(bool, false)
})), [])
egress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
destination_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
prefix_list_id = optional(string, null)
})), [])
})
|
{
"create": false
}
| no | +| [security\_group\_ids](#input\_security\_group\_ids) | List of security group IDs to associate with the DocumentDB cluster | `list(string)` | `[]` | no | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Determines whether a final DB snapshot is created before the DB cluster is deleted | `bool` | `false` | no | +| [snapshot\_identifier](#input\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot | `string` | `null` | no | +| [source\_db\_cluster\_identifier](#input\_source\_db\_cluster\_identifier) | The identifier of the source cluster for global cluster | `string` | `null` | no | | [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB cluster is encrypted | `bool` | `true` | no | -| [subnet\_ids](#input\_subnet\_ids) | List of subnet IDs to create the DB cluster in | `list(string)` | n/a | yes | -| [tags](#input\_tags) | Additional tags to apply to all resources | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | ID of the VPC to create the DB cluster in | `string` | n/a | yes | -| [zone\_id](#input\_zone\_id) | Route53 parent zone ID. If provided (not empty), the module will create sub-domain DNS records for the DocumentDB master and replicas | `string` | `""` | no | +| [subnet\_config](#input\_subnet\_config) | Subnet configuration for DocumentDB cluster |
object({
group_name = optional(string, null)
create_group = optional(bool, true)
subnet_ids = optional(list(string), [])
})
| `{}` | no | +| [tags](#input\_tags) | A map of tags to assign to the resource | `map(string)` | `{}` | no | +| [treat\_missing\_data](#input\_treat\_missing\_data) | Sets how this alarm is to handle missing data points | `string` | `"missing"` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID where the security group will be created | `string` | `null` | no | ## Outputs | Name | Description | |------|-------------| -| [arn](#output\_arn) | Amazon Resource Name (ARN) of the DocumentDB cluster | -| [cluster\_name](#output\_cluster\_name) | DocumentDB Cluster Identifier | -| [endpoint](#output\_endpoint) | Endpoint of the DocumentDB cluster | -| [reader\_endpoint](#output\_reader\_endpoint) | Read-only endpoint of the DocumentDB cluster, automatically load-balanced across replicas | - - -### Git commits - -while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch - -For Example - -```sh -git commit -m "your commit message #major" -``` -By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly - -## Development - -### Prerequisites - -- [terraform](https://learn.hashicorp.com/terraform/getting-started/install#installing-terraform) -- [terraform-docs](https://github.com/segmentio/terraform-docs) -- [pre-commit](https://pre-commit.com/#install) -- [golang](https://golang.org/doc/install#install) -- [golint](https://github.com/golang/lint#installation) - -### Configurations - -- Configure pre-commit hooks - ```sh - pre-commit install - ``` - -### Tests -- Tests are available in `test` directory -- Configure the dependencies - ```sh - cd test/ - go mod init github.com/sourcefuse/terraform-aws-refarch- - go get github.com/gruntwork-io/terratest/modules/terraform - ``` -- Now execute the test - ```sh - go test -timeout 30m - ``` - -## Authors - -This project is authored by: -- SourceFuse ARC Team +| [cloudwatch\_alarm\_connection\_arns](#output\_cloudwatch\_alarm\_connection\_arns) | List of ARNs for database connection CloudWatch alarms | +| [cloudwatch\_alarm\_cpu\_arns](#output\_cloudwatch\_alarm\_cpu\_arns) | List of ARNs for CPU utilization CloudWatch alarms | +| [cloudwatch\_log\_group\_audit\_arn](#output\_cloudwatch\_log\_group\_audit\_arn) | The ARN of the CloudWatch log group for audit logs | +| [cloudwatch\_log\_group\_audit\_name](#output\_cloudwatch\_log\_group\_audit\_name) | The name of the CloudWatch log group for audit logs | +| [cloudwatch\_log\_group\_profiler\_arn](#output\_cloudwatch\_log\_group\_profiler\_arn) | The ARN of the CloudWatch log group for profiler logs | +| [cloudwatch\_log\_group\_profiler\_name](#output\_cloudwatch\_log\_group\_profiler\_name) | The name of the CloudWatch log group for profiler logs | +| [cluster\_arn](#output\_cluster\_arn) | Amazon Resource Name (ARN) of the cluster | +| [cluster\_availability\_zones](#output\_cluster\_availability\_zones) | The availability zones of the cluster | +| [cluster\_backup\_retention\_period](#output\_cluster\_backup\_retention\_period) | The backup retention period | +| [cluster\_database\_name](#output\_cluster\_database\_name) | The name of the database | +| [cluster\_deletion\_protection](#output\_cluster\_deletion\_protection) | Specifies whether the cluster has deletion protection enabled | +| [cluster\_enabled\_cloudwatch\_logs\_exports](#output\_cluster\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to cloudwatch | +| [cluster\_endpoint](#output\_cluster\_endpoint) | The DNS address of the DocumentDB instance | +| [cluster\_engine](#output\_cluster\_engine) | The database engine | +| [cluster\_engine\_version](#output\_cluster\_engine\_version) | The database engine version | +| [cluster\_hosted\_zone\_id](#output\_cluster\_hosted\_zone\_id) | The Route53 Hosted Zone ID of the endpoint | +| [cluster\_id](#output\_cluster\_id) | The DocumentDB cluster identifier | +| [cluster\_identifier](#output\_cluster\_identifier) | The DocumentDB cluster identifier | +| [cluster\_kms\_key\_id](#output\_cluster\_kms\_key\_id) | The ARN for the KMS encryption key | +| [cluster\_members](#output\_cluster\_members) | List of DocumentDB Instances that are a part of this cluster | +| [cluster\_port](#output\_cluster\_port) | The database port | +| [cluster\_preferred\_backup\_window](#output\_cluster\_preferred\_backup\_window) | The daily time range during which the backups happen | +| [cluster\_preferred\_maintenance\_window](#output\_cluster\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur | +| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the DocumentDB cluster, automatically load-balanced across replicas | +| [cluster\_resource\_id](#output\_cluster\_resource\_id) | The DocumentDB Cluster Resource ID | +| [cluster\_storage\_encrypted](#output\_cluster\_storage\_encrypted) | Specifies whether the DB cluster is encrypted | +| [cluster\_vpc\_security\_group\_ids](#output\_cluster\_vpc\_security\_group\_ids) | List of VPC security groups associated to the cluster | +| [db\_cluster\_parameter\_group\_arn](#output\_db\_cluster\_parameter\_group\_arn) | The ARN of the DB cluster parameter group | +| [db\_cluster\_parameter\_group\_name](#output\_db\_cluster\_parameter\_group\_name) | The name of the DB cluster parameter group | +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the DB parameter group | +| [db\_parameter\_group\_name](#output\_db\_parameter\_group\_name) | The name of the DB parameter group | +| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the DB subnet group | +| [db\_subnet\_group\_name](#output\_db\_subnet\_group\_name) | The name of the DB subnet group | +| [enhanced\_monitoring\_role\_arn](#output\_enhanced\_monitoring\_role\_arn) | The ARN of the enhanced monitoring IAM role | +| [enhanced\_monitoring\_role\_name](#output\_enhanced\_monitoring\_role\_name) | The name of the enhanced monitoring IAM role | +| [event\_subscription\_arn](#output\_event\_subscription\_arn) | The ARN of the DocumentDB event subscription | +| [event\_subscription\_id](#output\_event\_subscription\_id) | The ID of the DocumentDB event subscription | +| [global\_cluster\_arn](#output\_global\_cluster\_arn) | Amazon Resource Name (ARN) of the global cluster | +| [global\_cluster\_id](#output\_global\_cluster\_id) | The DocumentDB global cluster identifier | +| [global\_cluster\_identifier](#output\_global\_cluster\_identifier) | The DocumentDB global cluster identifier | +| [global\_cluster\_members](#output\_global\_cluster\_members) | List of DocumentDB Clusters that are part of this global cluster | +| [global\_cluster\_resource\_id](#output\_global\_cluster\_resource\_id) | The DocumentDB Global Cluster Resource ID | +| [instance\_arns](#output\_instance\_arns) | List of DocumentDB instance ARNs | +| [instance\_availability\_zones](#output\_instance\_availability\_zones) | List of availability zones for the instances | +| [instance\_ca\_cert\_identifiers](#output\_instance\_ca\_cert\_identifiers) | List of CA certificate identifiers for the instances | +| [instance\_classes](#output\_instance\_classes) | List of DocumentDB instance classes | +| [instance\_endpoints](#output\_instance\_endpoints) | List of DocumentDB instance endpoints | +| [instance\_engine\_versions](#output\_instance\_engine\_versions) | List of database engine versions for the instances | +| [instance\_engines](#output\_instance\_engines) | List of database engines for the instances | +| [instance\_identifiers](#output\_instance\_identifiers) | List of DocumentDB instance identifiers | +| [instance\_ids](#output\_instance\_ids) | List of DocumentDB instance identifiers | +| [instance\_performance\_insights\_kms\_key\_ids](#output\_instance\_performance\_insights\_kms\_key\_ids) | List of KMS key identifiers for Performance Insights encryption | +| [instance\_ports](#output\_instance\_ports) | List of database ports for the instances | +| [instance\_promotion\_tiers](#output\_instance\_promotion\_tiers) | List of promotion tiers for the instances | +| [instance\_writers](#output\_instance\_writers) | List indicating which instances are writers | +| [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key | +| [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key | +| [master\_username](#output\_master\_username) | The master username for the DB cluster | +| [secret\_arn](#output\_secret\_arn) | The ARN of the secret | +| [secret\_id](#output\_secret\_id) | The ID of the secret | +| [security\_group\_arn](#output\_security\_group\_arn) | The ARN of the security group created for the DocumentDB cluster | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group created for the DocumentDB cluster | + +## Versioning +This project uses a 3-digit [Semantic Versioning](https://semver.org/) scheme. + +## Contributing + +### Bug Reports & Feature Requests + +Please use the [issue tracker](https://github.com/sourcefuse/terraform-aws-arc-document-db/issues) to report any bugs or file feature requests. + + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/sourcefuse/terraform-aws-arc-document-db/blob/main/LICENSE) for full details. diff --git a/docs/module-usage-guide/README.md b/docs/module-usage-guide/README.md index 98552a2..70d91d7 100644 --- a/docs/module-usage-guide/README.md +++ b/docs/module-usage-guide/README.md @@ -27,9 +27,32 @@ To use the module in your Terraform configuration, include the following source ```tcl module "example_doc_db_cluster" { source = "sourcefuse/arc-document-db/aws" - // we recommend to pin the version we aren't simply for an example reference against our latest changes. - # insert the required variables here + + cluster_identifier = var.cluster_identifier + master_username = var.master_username + master_password = var.master_password + + instance_count = var.instance_count + instance_class = var.instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.private.ids + } + vpc_id = data.aws_vpc.vpc.id + + security_group_data = local.security_group_data + + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + skip_final_snapshot = var.skip_final_snapshot + + storage_encrypted = var.storage_encrypted + deletion_protection = var.deletion_protection + + tags = module.tags.tags } + ``` ### Integration with Existing Terraform Configurations @@ -64,7 +87,7 @@ For a list of outputs, see the README [Outputs](https://github.com/sourcefuse/te ### Basic Usage -For basic usage, see the [example](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/example) folder. +For basic usage, see the [example](https://github.com/sourcefuse/terraform-aws-arc-document-db/tree/main/examples) folder. This example will create: diff --git a/example/.terraform.lock.hcl b/example/.terraform.lock.hcl deleted file mode 100644 index c572210..0000000 --- a/example/.terraform.lock.hcl +++ /dev/null @@ -1,68 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/aws" { - version = "4.67.0" - constraints = ">= 2.0.0, >= 3.0.0, >= 4.0.0, ~> 4.0, < 6.0.0" - hashes = [ - "h1:LfOuBkdYCzQhtiRvVIxdP/KGJODa3cRsKjn8xKCTbVY=", - "h1:dCRc4GqsyfqHEMjgtlM1EympBcgTmcTkWaJmtd91+KA=", - "zh:0843017ecc24385f2b45f2c5fce79dc25b258e50d516877b3affee3bef34f060", - "zh:19876066cfa60de91834ec569a6448dab8c2518b8a71b5ca870b2444febddac6", - "zh:24995686b2ad88c1ffaa242e36eee791fc6070e6144f418048c4ce24d0ba5183", - "zh:4a002990b9f4d6d225d82cb2fb8805789ffef791999ee5d9cb1fef579aeff8f1", - "zh:559a2b5ace06b878c6de3ecf19b94fbae3512562f7a51e930674b16c2f606e29", - "zh:6a07da13b86b9753b95d4d8218f6dae874cf34699bca1470d6effbb4dee7f4b7", - "zh:768b3bfd126c3b77dc975c7c0e5db3207e4f9997cf41aa3385c63206242ba043", - "zh:7be5177e698d4b547083cc738b977742d70ed68487ce6f49ecd0c94dbf9d1362", - "zh:8b562a818915fb0d85959257095251a05c76f3467caa3ba95c583ba5fe043f9b", - "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9c385d03a958b54e2afd5279cd8c7cbdd2d6ca5c7d6a333e61092331f38af7cf", - "zh:b3ca45f2821a89af417787df8289cb4314b273d29555ad3b2a5ab98bb4816b3b", - "zh:da3c317f1db2469615ab40aa6baba63b5643bae7110ff855277a1fb9d8eb4f2c", - "zh:dc6430622a8dc5cdab359a8704aec81d3825ea1d305bbb3bbd032b1c6adfae0c", - "zh:fac0d2ddeadf9ec53da87922f666e1e73a603a611c57bcbc4b86ac2821619b1d", - ] -} - -provider "registry.terraform.io/hashicorp/local" { - version = "2.5.1" - constraints = ">= 1.3.0" - hashes = [ - "h1:8oTPe2VUL6E2d3OcrvqyjI4Nn/Y/UEQN26WLk5O/B0g=", - "h1:Np4kERf9SMrqUi7DJ1rK3soMK14k49nfgE7l/ipQ5xw=", - "zh:0af29ce2b7b5712319bf6424cb58d13b852bf9a777011a545fac99c7fdcdf561", - "zh:126063ea0d79dad1f68fa4e4d556793c0108ce278034f101d1dbbb2463924561", - "zh:196bfb49086f22fd4db46033e01655b0e5e036a5582d250412cc690fa7995de5", - "zh:37c92ec084d059d37d6cffdb683ccf68e3a5f8d2eb69dd73c8e43ad003ef8d24", - "zh:4269f01a98513651ad66763c16b268f4c2da76cc892ccfd54b401fff6cc11667", - "zh:51904350b9c728f963eef0c28f1d43e73d010333133eb7f30999a8fb6a0cc3d8", - "zh:73a66611359b83d0c3fcba2984610273f7954002febb8a57242bbb86d967b635", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7ae387993a92bcc379063229b3cce8af7eaf082dd9306598fcd42352994d2de0", - "zh:9e0f365f807b088646db6e4a8d4b188129d9ebdbcf2568c8ab33bddd1b82c867", - "zh:b5263acbd8ae51c9cbffa79743fbcadcb7908057c87eb22fd9048268056efbc4", - "zh:dfcd88ac5f13c0d04e24be00b686d069b4879cc4add1b7b1a8ae545783d97520", - ] -} - -provider "registry.terraform.io/hashicorp/random" { - version = "3.6.2" - constraints = ">= 1.0.0" - hashes = [ - "h1:5lstwe/L8AZS/CP0lil2nPvmbbjAu8kCaU/ogSGNbxk=", - "h1:wmG0QFjQ2OfyPy6BB7mQ57WtoZZGGV07uAPQeDmIrAE=", - "zh:0ef01a4f81147b32c1bea3429974d4d104bbc4be2ba3cfa667031a8183ef88ec", - "zh:1bcd2d8161e89e39886119965ef0f37fcce2da9c1aca34263dd3002ba05fcb53", - "zh:37c75d15e9514556a5f4ed02e1548aaa95c0ecd6ff9af1119ac905144c70c114", - "zh:4210550a767226976bc7e57d988b9ce48f4411fa8a60cd74a6b246baf7589dad", - "zh:562007382520cd4baa7320f35e1370ffe84e46ed4e2071fdc7e4b1a9b1f8ae9b", - "zh:5efb9da90f665e43f22c2e13e0ce48e86cae2d960aaf1abf721b497f32025916", - "zh:6f71257a6b1218d02a573fc9bff0657410404fb2ef23bc66ae8cd968f98d5ff6", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:9647e18f221380a85f2f0ab387c68fdafd58af6193a932417299cdcae4710150", - "zh:bb6297ce412c3c2fa9fec726114e5e0508dd2638cad6a0cb433194930c97a544", - "zh:f83e925ed73ff8a5ef6e3608ad9225baa5376446349572c2449c0c0b3cf184b7", - "zh:fbef0781cb64de76b1df1ca11078aecba7800d82fd4a956302734999cfd9a4af", - ] -} diff --git a/example/README.md b/example/README.md deleted file mode 100644 index 7d68ede..0000000 --- a/example/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# terraform-aws-module-template example - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | -| [aws](#requirement\_aws) | >= 4.0, < 6.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | 4.67.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [doc\_db\_cluster](#module\_doc\_db\_cluster) | sourcefuse/arc-document-db/aws | n/a | -| [tags](#module\_tags) | sourcefuse/arc-tags/aws | 1.2.3 | - -## Resources - -| Name | Type | -|------|------| -| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | -| [aws_vpc.vpc_id](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [cluster\_size](#input\_cluster\_size) | Number of instances to create in the cluster | `number` | `1` | no | -| [doc\_db\_cluster\_name](#input\_doc\_db\_cluster\_name) | Name of the DocumentDB cluster | `string` | `""` | no | -| [environment](#input\_environment) | environment value, e.g 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | -| [instance\_class](#input\_instance\_class) | Instance class to use | `string` | `""` | no | -| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `""` | no | -| [namespace](#input\_namespace) | Namespace for the resources. | `string` | n/a | yes | -| [project\_name](#input\_project\_name) | The project name | `string` | `""` | no | -| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [example\_arn](#output\_example\_arn) | Amazon Resource Name (ARN) of the DocumentDB cluster | -| [example\_cluster\_name](#output\_example\_cluster\_name) | DocumentDB Cluster Identifier | -| [example\_endpoint](#output\_example\_endpoint) | Endpoint of the DocumentDB cluster | -| [example\_reader\_endpoint](#output\_example\_reader\_endpoint) | Read-only endpoint of the DocumentDB cluster, automatically load-balanced across replicas | - - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | -| [aws](#requirement\_aws) | ~> 4.0 | - -## Providers - -No providers. - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [example\_doc\_db\_cluster](#module\_example\_doc\_db\_cluster) | ../documentdb_cluster | n/a | -| [tags](#module\_tags) | sourcefuse/arc-tags/aws | 1.2.3 | - -## Resources - -No resources. - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks to allow connections to the DocumentDB cluster | `list(string)` | `[]` | no | -| [allowed\_security\_groups](#input\_allowed\_security\_groups) | List of security groups to allow access to the cluster | `list(string)` | `[]` | no | -| [cluster\_size](#input\_cluster\_size) | Number of instances to create in the cluster | `number` | `1` | no | -| [doc\_db\_cluster\_name](#input\_doc\_db\_cluster\_name) | Name of the DocumentDB cluster | `string` | `""` | no | -| [environment](#input\_environment) | environment value, e.g 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | -| [instance\_class](#input\_instance\_class) | Instance class to use | `string` | `""` | no | -| [master\_password](#input\_master\_password) | Password for the master DB user | `string` | `""` | no | -| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `""` | no | -| [namespace](#input\_namespace) | Namespace for the resources. | `string` | n/a | yes | -| [project\_name](#input\_project\_name) | The project name | `string` | `""` | no | -| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | -| [zone\_id](#input\_zone\_id) | Route53 parent zone ID. If provided (not empty), the module will create sub-domain DNS records for the DocumentDB master and replicas | `string` | `""` | no | - -## Outputs - -No outputs. - diff --git a/example/data.tf b/example/data.tf deleted file mode 100644 index 051c1e9..0000000 --- a/example/data.tf +++ /dev/null @@ -1,17 +0,0 @@ - -data "aws_vpc" "vpc_id" { - filter { - name = "tag:Name" - values = ["${var.namespace}-${var.environment}-vpc"] - } -} - -data "aws_subnets" "private" { - filter { - name = "tag:Name" - values = [ - "${var.namespace}-${var.environment}-private-subnet-private-${var.region}a", - "${var.namespace}-${var.environment}-private-subnet-private-${var.region}b" - ] - } -} diff --git a/example/example.tfvars b/example/example.tfvars deleted file mode 100644 index 0b86a8b..0000000 --- a/example/example.tfvars +++ /dev/null @@ -1,12 +0,0 @@ -region = "us-east-1" -namespace = "arc" -environment = "poc" -project = "arc-module" - -doc_db_cluster_name = "doc-db" - -instance_class = "db.r4.large" - -cluster_size = 1 - -master_username = "arc" diff --git a/example/main.tf b/example/main.tf deleted file mode 100644 index a9e37a7..0000000 --- a/example/main.tf +++ /dev/null @@ -1,39 +0,0 @@ -################################################################################ -## defaults -################################################################################ -terraform { - required_version = "~> 1.3, < 2.0.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.0, < 6.0" - } - } -} - -module "tags" { - source = "sourcefuse/arc-tags/aws" - version = "1.2.3" - environment = var.environment - project = var.project_name - -} - -provider "aws" { - region = var.region -} - -module "doc_db_cluster" { - source = "sourcefuse/arc-document-db/aws" - // we recommend to pin the version we aren't simply for an example reference against our latest changes. - namespace = var.namespace - environment = var.environment - doc_db_cluster_name = var.doc_db_cluster_name - cluster_size = var.cluster_size - master_username = var.master_username - instance_class = var.instance_class - vpc_id = data.aws_vpc.vpc_id.id - subnet_ids = data.aws_subnets.private.ids - tags = module.tags.tags -} diff --git a/example/outputs.tf b/example/outputs.tf deleted file mode 100644 index 346bec1..0000000 --- a/example/outputs.tf +++ /dev/null @@ -1,19 +0,0 @@ -output "example_cluster_name" { - description = "DocumentDB Cluster Identifier" - value = module.doc_db_cluster.cluster_name -} - -output "example_arn" { - description = "Amazon Resource Name (ARN) of the DocumentDB cluster" - value = module.doc_db_cluster.arn -} - -output "example_endpoint" { - description = "Endpoint of the DocumentDB cluster" - value = module.doc_db_cluster.endpoint -} - -output "example_reader_endpoint" { - description = "Read-only endpoint of the DocumentDB cluster, automatically load-balanced across replicas" - value = module.doc_db_cluster.reader_endpoint -} diff --git a/example/variables.tf b/example/variables.tf deleted file mode 100644 index d7ea35c..0000000 --- a/example/variables.tf +++ /dev/null @@ -1,51 +0,0 @@ -####################################################################### -## shared -####################################################################### -variable "namespace" { - type = string - description = "Namespace for the resources." -} - -variable "environment" { - type = string - default = "poc" - description = "environment value, e.g 'prod', 'staging', 'dev', 'UAT'" -} - -variable "region" { - type = string - description = "AWS region" - default = "us-east-1" -} - -variable "project_name" { - type = string - description = "The project name" - default = "" -} - -###### documentdb cluster variables - -variable "cluster_size" { - type = number - description = "Number of instances to create in the cluster" - default = 1 -} - -variable "doc_db_cluster_name" { - type = string - description = "Name of the DocumentDB cluster" - default = "" -} - -variable "instance_class" { - type = string - description = "Instance class to use" - default = "" -} - -variable "master_username" { - type = string - description = "Username for the master DB user" - default = "" -} diff --git a/examples/basic-cluster/.terraform.lock.hcl b/examples/basic-cluster/.terraform.lock.hcl new file mode 100644 index 0000000..1c4f1f6 --- /dev/null +++ b/examples/basic-cluster/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = ">= 5.0.0, ~> 5.0" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = ">= 3.1.0" + hashes = [ + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/examples/basic-cluster/README.md b/examples/basic-cluster/README.md new file mode 100644 index 0000000..a277cba --- /dev/null +++ b/examples/basic-cluster/README.md @@ -0,0 +1,139 @@ +# Basic DocumentDB Cluster Example + +This example demonstrates how to create a minimal DocumentDB cluster with a single writer instance in an existing VPC. + +## What This Example Creates + +- DocumentDB cluster with 1 instance +- DB subnet group using provided subnet IDs +- Security group with ingress rules for specified CIDR blocks +- Basic backup and maintenance configuration + +## Prerequisites + +- Existing VPC with at least 2 subnets in different AZs +- Appropriate IAM permissions to create DocumentDB resources +- Terraform >= 1.3 +- AWS Provider >= 5.0 + +## Usage + +1. Copy the example tfvars file: + ```bash + terraform.tfvars + ``` + +2. Edit `terraform.tfvars` with your specific values: + - Replace `subnet_ids` with your actual subnet IDs + - Replace `vpc_id` with your VPC ID + - Set a secure `master_password` + - Adjust `allowed_cidr_blocks` as needed + +3. Initialize and apply: + ```bash + terraform init + terraform plan + terraform apply + ``` + +## Variables Used + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| cluster_identifier | The cluster identifier | `string` | `"basic-docdb-cluster"` | no | +| master_username | Username for the master DB user | `string` | `"docdbadmin"` | no | +| master_password | Password for the master DB user | `string` | n/a | yes | +| instance_count | Number of instances in the cluster | `number` | `1` | no | +| instance_class | The instance class to use | `string` | `"db.t3.medium"` | no | +| subnet_ids | List of VPC subnet IDs | `list(string)` | n/a | yes | +| vpc_id | VPC ID where the security group will be created | `string` | n/a | yes | +| allowed_cidr_blocks | List of CIDR blocks allowed to access the DocumentDB cluster | `list(string)` | `["10.0.0.0/8"]` | no | + +## Expected Outputs + +- `cluster_endpoint`: Primary endpoint for write operations +- `cluster_reader_endpoint`: Read-only endpoint for read operations +- `cluster_id`: The DocumentDB cluster identifier +- `cluster_port`: Database port (27017) +- `instance_ids`: List of instance identifiers +- `security_group_id`: Security group ID for the cluster + +## Security Considerations + +- The master password is stored in Terraform state - consider using Secrets Manager in production +- Security group allows access from specified CIDR blocks only +- Encryption at rest is enabled by default using AWS managed keys +- Consider enabling deletion protection for production workloads + +## Clean Up + +```bash +terraform destroy +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.100.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [documentdb\_cluster](#module\_documentdb\_cluster) | ../../ | n/a | +| [tags](#module\_tags) | sourcefuse/arc-tags/aws | 1.2.5 | + +## Resources + +| Name | Type | +|------|------| +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | +| [aws_subnet.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks allowed to access the DocumentDB cluster | `list(string)` |
[
"10.0.0.0/8"
]
| no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `7` | no | +| [cluster\_identifier](#input\_cluster\_identifier) | The cluster identifier | `string` | `"basic-docdb-cluster"` | no | +| [deletion\_protection](#input\_deletion\_protection) | A value that indicates whether the DB cluster has deletion protection enabled | `bool` | `false` | no | +| [environment](#input\_environment) | Environment name | `string` | `"dev"` | no | +| [extra\_tags](#input\_extra\_tags) | Additional tags to apply to resources | `map(string)` | `{}` | no | +| [instance\_class](#input\_instance\_class) | The instance class to use | `string` | `"db.t3.medium"` | no | +| [instance\_count](#input\_instance\_count) | Number of instances in the cluster | `number` | `1` | no | +| [master\_password](#input\_master\_password) | Password for the master DB user | `string` | n/a | yes | +| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `"docdbadmin"` | no | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created | `string` | `"07:00-09:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur | `string` | `"sun:05:00-sun:06:00"` | no | +| [project](#input\_project) | Project name | `string` | `"basic-docdb"` | no | +| [security\_group\_ids](#input\_security\_group\_ids) | List of security group IDs to associate with the DocumentDB cluster | `list(string)` | `[]` | no | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Skip final snapshot when destroying cluster | `bool` | `false` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB cluster is encrypted | `bool` | `true` | no | +| [subnet\_ids](#input\_subnet\_ids) | List of VPC subnet IDs (will be populated from data sources) | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to assign to the resource (legacy support) | `map(string)` |
{
"Environment": "dev",
"Project": "basic-docdb"
}
| no | +| [vpc\_id](#input\_vpc\_id) | VPC ID (will be populated from data sources) | `string` | `""` | no | +| [vpc\_name](#input\_vpc\_name) | Name of the VPC to use | `string` | `"arc-poc-vpc"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [cluster\_endpoint](#output\_cluster\_endpoint) | The DNS address of the DocumentDB instance | +| [cluster\_id](#output\_cluster\_id) | The DocumentDB cluster identifier | +| [cluster\_port](#output\_cluster\_port) | The database port | +| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the DocumentDB cluster | +| [instance\_ids](#output\_instance\_ids) | List of DocumentDB instance identifiers | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group created for the DocumentDB cluster | + diff --git a/examples/basic-cluster/data.tf b/examples/basic-cluster/data.tf new file mode 100644 index 0000000..6cd3f18 --- /dev/null +++ b/examples/basic-cluster/data.tf @@ -0,0 +1,22 @@ +################################################################################ +## lookups +################################################################################ + +data "aws_vpc" "vpc" { + filter { + name = "tag:Name" + values = [var.vpc_name] + } +} + +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.vpc.id] + } + + filter { + name = "tag:Type" + values = ["private"] + } +} diff --git a/examples/basic-cluster/locals.tf b/examples/basic-cluster/locals.tf new file mode 100644 index 0000000..a23b391 --- /dev/null +++ b/examples/basic-cluster/locals.tf @@ -0,0 +1,26 @@ +locals { + security_group_data = { + create = true + description = "Security Group for docdb instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.vpc.cidr_block + from_port = 27017 + ip_protocol = "tcp" + to_port = 27017 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } +} diff --git a/examples/basic-cluster/main.tf b/examples/basic-cluster/main.tf new file mode 100644 index 0000000..e52a11c --- /dev/null +++ b/examples/basic-cluster/main.tf @@ -0,0 +1,34 @@ +module "tags" { + source = "sourcefuse/arc-tags/aws" + version = "1.2.5" + + environment = var.environment + project = var.project +} + +module "documentdb_cluster" { + source = "../../" + + cluster_identifier = var.cluster_identifier + master_username = var.master_username + + instance_count = var.instance_count + instance_class = var.instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.private.ids + } + vpc_id = data.aws_vpc.vpc.id + + security_group_data = local.security_group_data + + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + skip_final_snapshot = var.skip_final_snapshot + + storage_encrypted = var.storage_encrypted + deletion_protection = var.deletion_protection + + tags = module.tags.tags +} diff --git a/examples/basic-cluster/outputs.tf b/examples/basic-cluster/outputs.tf new file mode 100644 index 0000000..2b022e6 --- /dev/null +++ b/examples/basic-cluster/outputs.tf @@ -0,0 +1,29 @@ +output "cluster_endpoint" { + description = "The DNS address of the DocumentDB instance" + value = module.documentdb_cluster.cluster_endpoint +} + +output "cluster_reader_endpoint" { + description = "A read-only endpoint for the DocumentDB cluster" + value = module.documentdb_cluster.cluster_reader_endpoint +} + +output "cluster_id" { + description = "The DocumentDB cluster identifier" + value = module.documentdb_cluster.cluster_id +} + +output "cluster_port" { + description = "The database port" + value = module.documentdb_cluster.cluster_port +} + +output "instance_ids" { + description = "List of DocumentDB instance identifiers" + value = module.documentdb_cluster.instance_ids +} + +output "security_group_id" { + description = "The ID of the security group created for the DocumentDB cluster" + value = module.documentdb_cluster.security_group_id +} diff --git a/examples/basic-cluster/providers.tf b/examples/basic-cluster/providers.tf new file mode 100644 index 0000000..6ffa800 --- /dev/null +++ b/examples/basic-cluster/providers.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0, < 7.0" + } + } +} + +provider "aws" { + region = "us-east-1" +} diff --git a/examples/basic-cluster/terraform.tfvars b/examples/basic-cluster/terraform.tfvars new file mode 100644 index 0000000..305b2aa --- /dev/null +++ b/examples/basic-cluster/terraform.tfvars @@ -0,0 +1,20 @@ +cluster_identifier = "basic-docdb-cluster" +master_username = "docdbadmin" + +vpc_name = "arc-poc-vpc" + +instance_count = 1 +instance_class = "db.t3.medium" + + +backup_retention_period = 7 +preferred_backup_window = "07:00-09:00" +preferred_maintenance_window = "sun:05:00-sun:06:00" + +storage_encrypted = true +deletion_protection = false +skip_final_snapshot = true + +# Tags module configuration +environment = "dev" +project = "basic-docdb" diff --git a/examples/basic-cluster/variables.tf b/examples/basic-cluster/variables.tf new file mode 100644 index 0000000..db7fcb0 --- /dev/null +++ b/examples/basic-cluster/variables.tf @@ -0,0 +1,79 @@ +variable "cluster_identifier" { + description = "The cluster identifier" + type = string + default = "basic-docdb-cluster" +} + +variable "master_username" { + description = "Username for the master DB user" + type = string + default = "docdbadmin" +} + + +variable "instance_count" { + description = "Number of instances in the cluster" + type = number + default = 1 +} + +variable "instance_class" { + description = "The instance class to use" + type = string + default = "db.t3.medium" +} + +variable "vpc_name" { + description = "Name of the VPC to use" + type = string + default = "arc-poc-vpc" +} + + +variable "backup_retention_period" { + description = "The days to retain backups for" + type = number + default = 7 +} + +variable "preferred_backup_window" { + description = "The daily time range during which automated backups are created" + type = string + default = "07:00-09:00" +} + +variable "preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur" + type = string + default = "sun:05:00-sun:06:00" +} + +variable "storage_encrypted" { + description = "Specifies whether the DB cluster is encrypted" + type = bool + default = true +} + +variable "deletion_protection" { + description = "A value that indicates whether the DB cluster has deletion protection enabled" + type = bool + default = false +} + +variable "environment" { + description = "Environment name" + type = string + default = "dev" +} + +variable "project" { + description = "Project name" + type = string + default = "basic-docdb" +} + +variable "skip_final_snapshot" { + description = "Skip final snapshot when destroying cluster" + type = bool + default = false +} diff --git a/examples/global-cluster-multi-region/.terraform.lock.hcl b/examples/global-cluster-multi-region/.terraform.lock.hcl new file mode 100644 index 0000000..1c4f1f6 --- /dev/null +++ b/examples/global-cluster-multi-region/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = ">= 5.0.0, ~> 5.0" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = ">= 3.1.0" + hashes = [ + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/examples/global-cluster-multi-region/README.md b/examples/global-cluster-multi-region/README.md new file mode 100644 index 0000000..671c5fd --- /dev/null +++ b/examples/global-cluster-multi-region/README.md @@ -0,0 +1,140 @@ +# DocumentDB Global Cluster Multi-Region Example + +This example demonstrates how to create a DocumentDB Global Cluster with primary and secondary clusters across multiple AWS regions for disaster recovery and high availability. + +## What This Example Creates + +- **Global Cluster**: DocumentDB Global Cluster spanning multiple regions +- **Primary Cluster**: Full-featured cluster in primary region (us-east-1) with: + - 2 instances for high availability + - Secrets Manager integration + - Customer-managed KMS key + - CloudWatch logs exports +- **Secondary Cluster**: Read-only cluster in secondary region (us-west-2) with: + - 1 instance (can be scaled up) + - Inherits encryption from global cluster + - Independent VPC and security configuration + + +## Prerequisites + +- **Multi-Region Setup**: VPCs and subnets in both primary and secondary regions +- **Cross-Region Permissions**: IAM permissions for both regions +- **Network Connectivity**: Ensure proper routing between regions if needed +- **Terraform**: >= 1.3 +- **AWS Provider**: >= 5.0 + +## Key Features + +### Global Cluster Benefits +- **Cross-Region Replication**: Automatic data replication to secondary region +- **Disaster Recovery**: Fast failover capability (typically < 1 minute) +- **Read Scaling**: Distribute read workloads across regions +- **Low Latency**: Serve users from the nearest region + +## Usage + +1. **Set up VPCs in both regions**: + ```bash + # Ensure you have VPCs and subnets in both us-east-1 and us-west-2 + ``` + +2. **Copy and configure variables**: + ```bash + terraform.tfvars + # Edit terraform.tfvars with your actual VPC/subnet IDs + ``` + +3. **Deploy the global cluster**: + ```bash + terraform init + terraform plan + terraform apply + ``` + +## Security Considerations + +- **Encryption**: Both clusters use encryption at rest +- **Network Isolation**: Each cluster in its own VPC +- **Access Control**: Independent security groups per region +- **Credential Management**: Secrets Manager in primary region only + + +## Troubleshooting + +### Common Issues +1. **Cross-region permissions**: Ensure IAM roles have permissions in both regions +2. **VPC connectivity**: Verify subnets and security groups in both regions +3. **Replication lag**: Monitor CloudWatch metrics for replication health + + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [primary\_cluster](#module\_primary\_cluster) | ../../ | n/a | +| [secondary\_cluster](#module\_secondary\_cluster) | ../../ | n/a | +| [tags](#module\_tags) | sourcefuse/arc-tags/aws | 1.2.5 | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `30` | no | +| [deletion\_protection](#input\_deletion\_protection) | A value that indicates whether the clusters have deletion protection enabled | `bool` | `true` | no | +| [egress\_rules](#input\_egress\_rules) | List of egress rules for the security groups |
list(object({
description = optional(string, null)
cidr_block = optional(string, null)
destination_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
prefix_list_id = optional(string, null)
}))
|
[
{
"cidr_block": "0.0.0.0/0",
"description": "All outbound traffic",
"from_port": -1,
"ip_protocol": "-1",
"to_port": "-1"
}
]
| no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to cloudwatch | `list(string)` |
[
"audit",
"profiler"
]
| no | +| [environment](#input\_environment) | Environment name | `string` | `"prod"` | no | +| [extra\_tags](#input\_extra\_tags) | Additional tags to apply to resources | `map(string)` | `{}` | no | +| [global\_cluster\_identifier](#input\_global\_cluster\_identifier) | The global cluster identifier | `string` | `"global-docdb-cluster"` | no | +| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `"docdbadmin"` | no | +| [primary\_cluster\_identifier](#input\_primary\_cluster\_identifier) | The primary cluster identifier | `string` | `"primary-docdb-cluster"` | no | +| [primary\_ingress\_rules](#input\_primary\_ingress\_rules) | List of ingress rules for the primary cluster security group |
list(object({
description = optional(string, null)
cidr_block = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
self = optional(bool, false)
}))
| `[]` | no | +| [primary\_instance\_class](#input\_primary\_instance\_class) | The instance class for primary cluster | `string` | `"db.r5.large"` | no | +| [primary\_instance\_count](#input\_primary\_instance\_count) | Number of instances in the primary cluster | `number` | `2` | no | +| [primary\_region](#input\_primary\_region) | Primary region for the global cluster | `string` | `"us-east-1"` | no | +| [primary\_subnet\_ids](#input\_primary\_subnet\_ids) | List of VPC subnet IDs in primary region | `list(string)` | n/a | yes | +| [primary\_vpc\_id](#input\_primary\_vpc\_id) | VPC ID in primary region | `string` | n/a | yes | +| [project](#input\_project) | Project name | `string` | `"global-docdb"` | no | +| [secondary\_cluster\_identifier](#input\_secondary\_cluster\_identifier) | The secondary cluster identifier | `string` | `"secondary-docdb-cluster"` | no | +| [secondary\_ingress\_rules](#input\_secondary\_ingress\_rules) | List of ingress rules for the secondary cluster security group |
list(object({
description = optional(string, null)
cidr_block = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
self = optional(bool, false)
}))
| `[]` | no | +| [secondary\_instance\_class](#input\_secondary\_instance\_class) | The instance class for secondary cluster | `string` | `"db.r5.large"` | no | +| [secondary\_instance\_count](#input\_secondary\_instance\_count) | Number of instances in the secondary cluster | `number` | `1` | no | +| [secondary\_region](#input\_secondary\_region) | Secondary region for the global cluster | `string` | `"us-west-2"` | no | +| [secondary\_subnet\_ids](#input\_secondary\_subnet\_ids) | List of VPC subnet IDs in secondary region | `list(string)` | n/a | yes | +| [secondary\_vpc\_id](#input\_secondary\_vpc\_id) | VPC ID in secondary region | `string` | n/a | yes | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Skip final snapshot when destroying clusters | `bool` | `false` | no | +| [tags](#input\_tags) | A map of tags to assign to the resources (legacy support) | `map(string)` |
{
"Environment": "prod",
"Project": "global-docdb",
"Purpose": "multi-region-dr"
}
| no | + +## Outputs + +| Name | Description | +|------|-------------| +| [connection\_info](#output\_connection\_info) | Connection information for both clusters | +| [global\_cluster\_arn](#output\_global\_cluster\_arn) | Amazon Resource Name (ARN) of the global cluster | +| [global\_cluster\_identifier](#output\_global\_cluster\_identifier) | The DocumentDB global cluster identifier | +| [global\_cluster\_members](#output\_global\_cluster\_members) | List of DocumentDB Clusters that are part of this global cluster | +| [primary\_cluster\_endpoint](#output\_primary\_cluster\_endpoint) | The DNS address of the primary DocumentDB cluster | +| [primary\_cluster\_id](#output\_primary\_cluster\_id) | The primary DocumentDB cluster identifier | +| [primary\_cluster\_reader\_endpoint](#output\_primary\_cluster\_reader\_endpoint) | A read-only endpoint for the primary DocumentDB cluster | +| [primary\_secret\_arn](#output\_primary\_secret\_arn) | The ARN of the secret containing primary cluster credentials | +| [secondary\_cluster\_endpoint](#output\_secondary\_cluster\_endpoint) | The DNS address of the secondary DocumentDB cluster | +| [secondary\_cluster\_id](#output\_secondary\_cluster\_id) | The secondary DocumentDB cluster identifier | +| [secondary\_cluster\_reader\_endpoint](#output\_secondary\_cluster\_reader\_endpoint) | A read-only endpoint for the secondary DocumentDB cluster | + diff --git a/examples/global-cluster-multi-region/data.tf b/examples/global-cluster-multi-region/data.tf new file mode 100644 index 0000000..f5e5df1 --- /dev/null +++ b/examples/global-cluster-multi-region/data.tf @@ -0,0 +1,40 @@ +################################################################################ +## Primary Region Lookups +################################################################################ +data "aws_vpc" "primary" { + provider = aws.primary + filter { + name = "tag:Name" + values = [var.primary_vpc_name] + } +} + +data "aws_subnets" "primary_private" { + provider = aws.primary + filter { + name = "vpc-id" + values = [data.aws_vpc.primary.id] + } + + filter { + name = "tag:Type" + values = ["private"] + } +} + +################################################################################ +## Secondary Region Lookups +################################################################################ + +data "aws_vpc" "secondary" { + provider = aws.secondary + default = true +} + +data "aws_subnets" "secondary_private" { + provider = aws.secondary + filter { + name = "vpc-id" + values = [data.aws_vpc.secondary.id] + } +} diff --git a/examples/global-cluster-multi-region/locals.tf b/examples/global-cluster-multi-region/locals.tf new file mode 100644 index 0000000..68a0c42 --- /dev/null +++ b/examples/global-cluster-multi-region/locals.tf @@ -0,0 +1,50 @@ +locals { + primary_security_group_data = { + create = true + description = "Security Group for docdb instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.primary.cidr_block + from_port = 27017 + ip_protocol = "tcp" + to_port = 27017 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } + secondary_security_group_data = { + create = true + description = "Security Group for docdb instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.secondary.cidr_block + from_port = 27017 + ip_protocol = "tcp" + to_port = 27017 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } +} diff --git a/examples/global-cluster-multi-region/main.tf b/examples/global-cluster-multi-region/main.tf new file mode 100644 index 0000000..00ad255 --- /dev/null +++ b/examples/global-cluster-multi-region/main.tf @@ -0,0 +1,94 @@ +# Tags module +module "tags" { + source = "sourcefuse/arc-tags/aws" + version = "1.2.5" + + environment = var.environment + project = var.project + +} + +## Primary cluster in us-east-1 +module "primary_cluster" { + source = "../../" + + providers = { + aws = aws.primary + } + + cluster_identifier = var.primary_cluster_identifier + master_username = var.master_username + + instance_count = var.primary_instance_count + instance_class = var.primary_instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.primary_private.ids + } + vpc_id = data.aws_vpc.primary.id + # Use security group rules + security_group_data = local.primary_security_group_data + + # Global cluster configuration + create_global_cluster = true + global_cluster_identifier = var.global_cluster_identifier + + # Security features + secret_config = { + create = true + } + kms_config = { + create_key = true + } + storage_encrypted = true + deletion_protection = var.deletion_protection + + # Monitoring + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + # Enhanced backup + backup_retention_period = var.backup_retention_period + skip_final_snapshot = var.skip_final_snapshot + + tags = module.tags.tags +} + +# Secondary cluster in us-west-2 +module "secondary_cluster" { + source = "../../" + + providers = { + aws = aws.secondary + } + + cluster_identifier = var.secondary_cluster_identifier + + instance_count = var.secondary_instance_count + instance_class = var.secondary_instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.secondary_private.ids + } + vpc_id = data.aws_vpc.secondary.id + + # Use security group rules + security_group_data = local.secondary_security_group_data + + # Global cluster configuration + existing_global_cluster_identifier = module.primary_cluster.global_cluster_identifier + is_secondary_cluster = true + + # Security features (inherit from global cluster) + kms_config = { + create_key = true + } + storage_encrypted = true + deletion_protection = var.deletion_protection + skip_final_snapshot = var.skip_final_snapshot + + # Monitoring + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + tags = module.tags.tags + + depends_on = [module.primary_cluster] +} diff --git a/examples/global-cluster-multi-region/outputs.tf b/examples/global-cluster-multi-region/outputs.tf new file mode 100644 index 0000000..677a91e --- /dev/null +++ b/examples/global-cluster-multi-region/outputs.tf @@ -0,0 +1,70 @@ +output "global_cluster_arn" { + description = "Amazon Resource Name (ARN) of the global cluster" + value = module.primary_cluster.global_cluster_arn +} + +output "global_cluster_identifier" { + description = "The DocumentDB global cluster identifier" + value = module.primary_cluster.global_cluster_identifier +} + +output "global_cluster_members" { + description = "List of DocumentDB Clusters that are part of this global cluster" + value = module.primary_cluster.global_cluster_members +} + +# Primary cluster outputs +output "primary_cluster_endpoint" { + description = "The DNS address of the primary DocumentDB cluster" + value = module.primary_cluster.cluster_endpoint +} + +output "primary_cluster_reader_endpoint" { + description = "A read-only endpoint for the primary DocumentDB cluster" + value = module.primary_cluster.cluster_reader_endpoint +} + +output "primary_cluster_id" { + description = "The primary DocumentDB cluster identifier" + value = module.primary_cluster.cluster_id +} + +output "primary_secret_arn" { + description = "The ARN of the secret containing primary cluster credentials" + value = module.primary_cluster.secret_arn +} + +# Secondary cluster outputs +output "secondary_cluster_endpoint" { + description = "The DNS address of the secondary DocumentDB cluster" + value = module.secondary_cluster.cluster_endpoint +} + +output "secondary_cluster_reader_endpoint" { + description = "A read-only endpoint for the secondary DocumentDB cluster" + value = module.secondary_cluster.cluster_reader_endpoint +} + +output "secondary_cluster_id" { + description = "The secondary DocumentDB cluster identifier" + value = module.secondary_cluster.cluster_id +} + +# Connection information +output "connection_info" { + description = "Connection information for both clusters" + value = { + primary = { + endpoint = module.primary_cluster.cluster_endpoint + reader_endpoint = module.primary_cluster.cluster_reader_endpoint + port = module.primary_cluster.cluster_port + region = var.primary_region + } + secondary = { + endpoint = module.secondary_cluster.cluster_endpoint + reader_endpoint = module.secondary_cluster.cluster_reader_endpoint + port = module.secondary_cluster.cluster_port + region = var.secondary_region + } + } +} diff --git a/examples/global-cluster-multi-region/providers.tf b/examples/global-cluster-multi-region/providers.tf new file mode 100644 index 0000000..0f6b10b --- /dev/null +++ b/examples/global-cluster-multi-region/providers.tf @@ -0,0 +1,22 @@ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0, < 7.0" + } + } +} + +# Primary region provider +provider "aws" { + alias = "primary" + region = var.primary_region +} + +# Secondary region provider +provider "aws" { + alias = "secondary" + region = var.secondary_region +} diff --git a/examples/global-cluster-multi-region/terraform.tfvars b/examples/global-cluster-multi-region/terraform.tfvars new file mode 100644 index 0000000..d8dac38 --- /dev/null +++ b/examples/global-cluster-multi-region/terraform.tfvars @@ -0,0 +1,28 @@ +global_cluster_identifier = "global-docdb-cluster" + +primary_region = "us-east-1" +secondary_region = "us-east-2" + +primary_cluster_identifier = "primary-docdb-cluster" +secondary_cluster_identifier = "secondary-docdb-cluster" + +master_username = "docdbadmin" + +primary_instance_count = 1 +secondary_instance_count = 1 + +primary_instance_class = "db.r5.large" +secondary_instance_class = "db.r5.large" + +# Use existing VPC +primary_vpc_name = "arc-poc-vpc" + +backup_retention_period = 7 +deletion_protection = false +skip_final_snapshot = true + +enabled_cloudwatch_logs_exports = ["audit"] + +# Tags module configuration +environment = "dev" +project = "global-docdb" diff --git a/examples/global-cluster-multi-region/variables.tf b/examples/global-cluster-multi-region/variables.tf new file mode 100644 index 0000000..8ba8687 --- /dev/null +++ b/examples/global-cluster-multi-region/variables.tf @@ -0,0 +1,102 @@ +variable "environment" { + description = "Environment name" + type = string + default = "prod" +} + +variable "project" { + description = "Project name" + type = string + default = "global-docdb" +} + + +variable "global_cluster_identifier" { + description = "The global cluster identifier" + type = string + default = "global-docdb-cluster" +} + +variable "primary_region" { + description = "Primary region for the global cluster" + type = string + default = "us-east-1" +} + +variable "secondary_region" { + description = "Secondary region for the global cluster" + type = string + default = "us-west-2" +} + +variable "primary_cluster_identifier" { + description = "The primary cluster identifier" + type = string + default = "primary-docdb-cluster" +} + +variable "secondary_cluster_identifier" { + description = "The secondary cluster identifier" + type = string + default = "secondary-docdb-cluster" +} + +variable "master_username" { + description = "Username for the master DB user" + type = string + default = "docdbadmin" +} + +variable "primary_instance_count" { + description = "Number of instances in the primary cluster" + type = number + default = 2 +} + +variable "secondary_instance_count" { + description = "Number of instances in the secondary cluster" + type = number + default = 1 +} + +variable "primary_instance_class" { + description = "The instance class for primary cluster" + type = string + default = "db.r5.large" +} + +variable "secondary_instance_class" { + description = "The instance class for secondary cluster" + type = string + default = "db.r5.large" +} + + +variable "backup_retention_period" { + description = "The days to retain backups for" + type = number + default = 30 +} + +variable "deletion_protection" { + description = "A value that indicates whether the clusters have deletion protection enabled" + type = bool + default = true +} + +variable "enabled_cloudwatch_logs_exports" { + description = "List of log types to export to cloudwatch" + type = list(string) + default = ["audit", "profiler"] +} + +variable "skip_final_snapshot" { + description = "Skip final snapshot when destroying clusters" + type = bool + default = false +} + +variable "primary_vpc_name" { + description = "VPC name in primary region" + type = string +} diff --git a/examples/multi-az-cluster/.terraform.lock.hcl b/examples/multi-az-cluster/.terraform.lock.hcl new file mode 100644 index 0000000..f4248b9 --- /dev/null +++ b/examples/multi-az-cluster/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = ">= 5.0.0, ~> 5.0" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = ">= 3.0.0, >= 3.1.0" + hashes = [ + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/examples/multi-az-cluster/README.md b/examples/multi-az-cluster/README.md new file mode 100644 index 0000000..222aa1b --- /dev/null +++ b/examples/multi-az-cluster/README.md @@ -0,0 +1,133 @@ +# Multi-AZ DocumentDB Cluster Example + +This example demonstrates how to create a highly available DocumentDB cluster with multiple instances across different Availability Zones, enhanced monitoring, custom parameter groups, and production-ready security configurations. + +## What This Example Creates + +- DocumentDB cluster with 3 instances distributed across multiple AZs +- AWS Secrets Manager secret with auto-generated master password +- Customer-managed KMS key for encryption at rest and secrets encryption +- Custom DB cluster parameter group with TLS enforcement and audit logging +- DB subnet group spanning multiple AZs +- Security group with flexible access control (CIDR blocks and/or security groups) +- CloudWatch logs exports for audit and profiler logs +- Enhanced backup configuration with 30-day retention +- Deletion protection enabled for production safety + +## Prerequisites + +- Existing VPC with at least 3 subnets in different AZs for true multi-AZ deployment +- Appropriate IAM permissions to create DocumentDB, Secrets Manager, and KMS resources +- Terraform >= 1.3 +- AWS Provider >= 5.0 + + +## Usage + +1. Copy the example tfvars file: + ```bash + terraform.tfvars + ``` + +2. Edit `terraform.tfvars` with your specific values: + - Replace `subnet_ids` with your actual subnet IDs across different AZs + - Replace `vpc_id` with your VPC ID + - Replace `allowed_security_group_ids` with your application security groups + - Customize instance class and count based on your performance requirements + - Adjust backup retention and maintenance windows for your needs + +3. Initialize and apply: + ```bash + terraform init + terraform plan + terraform apply + ``` + +## High Availability Features + +- **Multi-AZ Deployment**: Instances distributed across multiple Availability Zones +- **Automatic Failover**: Primary instance failure triggers automatic failover to a reader +- **Read Scaling**: Multiple reader instances for read workload distribution +- **Enhanced Backup**: 30-day backup retention with point-in-time recovery +- **Monitoring**: CloudWatch logs for audit trails and performance profiling + +## Security Features + +- **TLS Enforcement**: All connections must use TLS encryption +- **Audit Logging**: All database operations are logged +- **Customer-Managed Encryption**: Both data and secrets encrypted with your KMS key +- **Network Isolation**: Access controlled via security groups +- **Secrets Management**: Credentials stored securely in AWS Secrets Manager +- **Deletion Protection**: Prevents accidental cluster deletion + + + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | +| [random](#requirement\_random) | >= 3.0 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [documentdb\_cluster](#module\_documentdb\_cluster) | ../../ | n/a | +| [tags](#module\_tags) | sourcefuse/arc-tags/aws | 1.2.5 | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks allowed to access the DocumentDB cluster | `list(string)` | `[]` | no | +| [allowed\_security\_group\_ids](#input\_allowed\_security\_group\_ids) | List of security group IDs allowed to access the DocumentDB cluster | `list(string)` | `[]` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `30` | no | +| [cluster\_identifier](#input\_cluster\_identifier) | The cluster identifier | `string` | `"multi-az-docdb-cluster"` | no | +| [db\_cluster\_parameter\_group\_family](#input\_db\_cluster\_parameter\_group\_family) | The DB cluster parameter group family | `string` | `"docdb4.0"` | no | +| [db\_cluster\_parameter\_group\_parameters](#input\_db\_cluster\_parameter\_group\_parameters) | A list of DB cluster parameters to apply |
list(object({
name = string
value = string
}))
|
[
{
"name": "tls",
"value": "enabled"
},
{
"name": "audit_logs",
"value": "enabled"
},
{
"name": "profiler",
"value": "enabled"
},
{
"name": "profiler_threshold_ms",
"value": "100"
}
]
| no | +| [deletion\_protection](#input\_deletion\_protection) | A value that indicates whether the DB cluster has deletion protection enabled | `bool` | `true` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to cloudwatch | `list(string)` |
[
"audit",
"profiler"
]
| no | +| [environment](#input\_environment) | Environment name | `string` | `"prod"` | no | +| [extra\_tags](#input\_extra\_tags) | Additional tags to apply to resources | `map(string)` | `{}` | no | +| [instance\_class](#input\_instance\_class) | The instance class to use | `string` | `"db.r5.large"` | no | +| [instance\_count](#input\_instance\_count) | Number of instances in the cluster | `number` | `3` | no | +| [kms\_key\_description](#input\_kms\_key\_description) | Description for the KMS key | `string` | `"DocumentDB cluster encryption key for multi-AZ cluster"` | no | +| [master\_username](#input\_master\_username) | Username for the master DB user | `string` | `"docdbadmin"` | no | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created | `string` | `"03:00-05:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur | `string` | `"sun:02:00-sun:03:00"` | no | +| [project](#input\_project) | Project name | `string` | `"multi-az-docdb"` | no | +| [secret\_name](#input\_secret\_name) | Name for the Secrets Manager secret | `string` | `"multi-az-docdb-credentials"` | no | +| [secret\_recovery\_window\_in\_days](#input\_secret\_recovery\_window\_in\_days) | Number of days that AWS Secrets Manager waits before it can delete the secret | `number` | `30` | no | +| [subnet\_ids](#input\_subnet\_ids) | List of VPC subnet IDs across multiple AZs | `list(string)` | n/a | yes | +| [tags](#input\_tags) | A map of tags to assign to the resource (legacy support) | `map(string)` |
{
"Environment": "prod",
"Project": "multi-az-docdb",
"Tier": "database"
}
| no | +| [vpc\_id](#input\_vpc\_id) | VPC ID where the security group will be created | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [cluster\_arn](#output\_cluster\_arn) | Amazon Resource Name (ARN) of the cluster | +| [cluster\_endpoint](#output\_cluster\_endpoint) | The DNS address of the DocumentDB instance | +| [cluster\_id](#output\_cluster\_id) | The DocumentDB cluster identifier | +| [cluster\_members](#output\_cluster\_members) | List of DocumentDB Instances that are a part of this cluster | +| [cluster\_port](#output\_cluster\_port) | The database port | +| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the DocumentDB cluster | +| [db\_cluster\_parameter\_group\_name](#output\_db\_cluster\_parameter\_group\_name) | The name of the DB cluster parameter group | +| [instance\_endpoints](#output\_instance\_endpoints) | List of DocumentDB instance endpoints | +| [instance\_ids](#output\_instance\_ids) | List of DocumentDB instance identifiers | +| [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the KMS key | +| [master\_username](#output\_master\_username) | The master username for the DB cluster | +| [secret\_arn](#output\_secret\_arn) | The ARN of the secret containing master credentials | +| [security\_group\_id](#output\_security\_group\_id) | The ID of the security group created for the DocumentDB cluster | + diff --git a/examples/multi-az-cluster/data.tf b/examples/multi-az-cluster/data.tf new file mode 100644 index 0000000..026f3fa --- /dev/null +++ b/examples/multi-az-cluster/data.tf @@ -0,0 +1,21 @@ +################################################################################ +## VPC and Subnet Lookups +################################################################################ +data "aws_vpc" "main" { + filter { + name = "tag:Name" + values = [var.vpc_name] + } +} + +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.main.id] + } + + filter { + name = "availability-zone" + values = ["us-east-1a", "us-east-1b"] + } +} diff --git a/examples/multi-az-cluster/locals.tf b/examples/multi-az-cluster/locals.tf new file mode 100644 index 0000000..2776ff4 --- /dev/null +++ b/examples/multi-az-cluster/locals.tf @@ -0,0 +1,26 @@ +locals { + security_group_data = { + create = true + description = "Security Group for docdb instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.main.cidr_block + from_port = 27017 + ip_protocol = "tcp" + to_port = 27017 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } +} diff --git a/examples/multi-az-cluster/main.tf b/examples/multi-az-cluster/main.tf new file mode 100644 index 0000000..d5c288d --- /dev/null +++ b/examples/multi-az-cluster/main.tf @@ -0,0 +1,59 @@ +module "tags" { + source = "sourcefuse/arc-tags/aws" + version = "1.2.5" + + environment = var.environment + project = var.project + +} + +module "documentdb_cluster" { + source = "../../" + + cluster_identifier = var.cluster_identifier + master_username = var.master_username + + instance_count = var.instance_count + instance_class = var.instance_class + + subnet_config = { + subnet_ids = data.aws_subnets.private.ids + } + vpc_id = data.aws_vpc.main.id + + security_group_data = local.security_group_data + + # Enable Secrets Manager integration + secret_config = { + create = true + name = null # Use auto-generated name with random suffix + recovery_window_in_days = var.secret_recovery_window_in_days + } + + # Enable KMS encryption + kms_config = { + create_key = true + description = var.kms_key_description + } + + # Enhanced backup configuration + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + + storage_encrypted = true + deletion_protection = var.deletion_protection + skip_final_snapshot = true + + # Enable CloudWatch logs + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + # Parameter group configuration + parameter_group_config = { + create = true + family = var.db_cluster_parameter_group_family + parameters = var.db_cluster_parameter_group_parameters + } + + tags = module.tags.tags +} diff --git a/examples/multi-az-cluster/outputs.tf b/examples/multi-az-cluster/outputs.tf new file mode 100644 index 0000000..b2d4c4c --- /dev/null +++ b/examples/multi-az-cluster/outputs.tf @@ -0,0 +1,64 @@ +output "cluster_endpoint" { + description = "The DNS address of the DocumentDB instance" + value = module.documentdb_cluster.cluster_endpoint +} + +output "cluster_reader_endpoint" { + description = "A read-only endpoint for the DocumentDB cluster" + value = module.documentdb_cluster.cluster_reader_endpoint +} + +output "cluster_id" { + description = "The DocumentDB cluster identifier" + value = module.documentdb_cluster.cluster_id +} + +output "cluster_arn" { + description = "Amazon Resource Name (ARN) of the cluster" + value = module.documentdb_cluster.cluster_arn +} + +output "cluster_port" { + description = "The database port" + value = module.documentdb_cluster.cluster_port +} + +output "cluster_members" { + description = "List of DocumentDB Instances that are a part of this cluster" + value = module.documentdb_cluster.cluster_members +} + +output "instance_ids" { + description = "List of DocumentDB instance identifiers" + value = module.documentdb_cluster.instance_ids +} + +output "instance_endpoints" { + description = "List of DocumentDB instance endpoints" + value = module.documentdb_cluster.instance_endpoints +} + +output "security_group_id" { + description = "The ID of the security group created for the DocumentDB cluster" + value = module.documentdb_cluster.security_group_id +} + +output "secret_arn" { + description = "The ARN of the secret containing master credentials" + value = module.documentdb_cluster.secret_arn +} + +output "kms_key_arn" { + description = "The Amazon Resource Name (ARN) of the KMS key" + value = module.documentdb_cluster.kms_key_arn +} + +output "db_cluster_parameter_group_name" { + description = "The name of the DB cluster parameter group" + value = module.documentdb_cluster.db_cluster_parameter_group_name +} + +output "master_username" { + description = "The master username for the DB cluster" + value = module.documentdb_cluster.master_username +} diff --git a/examples/multi-az-cluster/providers.tf b/examples/multi-az-cluster/providers.tf new file mode 100644 index 0000000..f05375e --- /dev/null +++ b/examples/multi-az-cluster/providers.tf @@ -0,0 +1,17 @@ +terraform { + required_version = "~> 1.3, < 2.0.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0, < 7.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.0" + } + } +} + +provider "aws" { + region = "us-east-1" +} diff --git a/examples/multi-az-cluster/terraform.tfvars b/examples/multi-az-cluster/terraform.tfvars new file mode 100644 index 0000000..600f988 --- /dev/null +++ b/examples/multi-az-cluster/terraform.tfvars @@ -0,0 +1,49 @@ +cluster_identifier = "multi-az-docdb-cluster" +master_username = "docdbadmin" + +# Use 3 instances across multiple AZs +instance_count = 3 +instance_class = "db.r5.large" + +# Secrets Manager configuration +# secret_name will be auto-generated as "${cluster_identifier}-credentials-${random_suffix}" +secret_recovery_window_in_days = 7 # Minimum allowed value + +# KMS configuration +kms_key_description = "DocumentDB cluster encryption key for multi-AZ cluster" + +# Backup configuration +backup_retention_period = 7 +preferred_backup_window = "03:00-05:00" +preferred_maintenance_window = "sun:02:00-sun:03:00" + +# Disable deletion protection for easier cleanup +deletion_protection = false + +# CloudWatch logs +enabled_cloudwatch_logs_exports = ["audit", "profiler"] + +# Parameter group configuration +db_cluster_parameter_group_family = "docdb4.0" +db_cluster_parameter_group_parameters = [ + { + name = "tls" + value = "enabled" + }, + { + name = "audit_logs" + value = "enabled" + }, + { + name = "profiler" + value = "enabled" + }, + { + name = "profiler_threshold_ms" + value = "100" + } +] + +# Tags +environment = "arc" +project = "multi-az-docdb" diff --git a/examples/multi-az-cluster/variables.tf b/examples/multi-az-cluster/variables.tf new file mode 100644 index 0000000..f658446 --- /dev/null +++ b/examples/multi-az-cluster/variables.tf @@ -0,0 +1,116 @@ +variable "cluster_identifier" { + description = "The cluster identifier" + type = string + default = "multi-az-docdb-cluster" +} + +variable "master_username" { + description = "Username for the master DB user" + type = string + default = "docdbadmin" +} + +variable "instance_count" { + description = "Number of instances in the cluster" + type = number + default = 3 +} + +variable "instance_class" { + description = "The instance class to use" + type = string + default = "db.r5.large" +} + + +variable "secret_recovery_window_in_days" { + description = "Number of days that AWS Secrets Manager waits before it can delete the secret" + type = number + default = 30 +} + +variable "kms_key_description" { + description = "Description for the KMS key" + type = string + default = "DocumentDB cluster encryption key for multi-AZ cluster" +} + +variable "backup_retention_period" { + description = "The days to retain backups for" + type = number + default = 30 +} + +variable "preferred_backup_window" { + description = "The daily time range during which automated backups are created" + type = string + default = "03:00-05:00" +} + +variable "preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur" + type = string + default = "sun:02:00-sun:03:00" +} + +variable "deletion_protection" { + description = "A value that indicates whether the DB cluster has deletion protection enabled" + type = bool + default = true +} + +variable "enabled_cloudwatch_logs_exports" { + description = "List of log types to export to cloudwatch" + type = list(string) + default = ["audit", "profiler"] +} + +variable "db_cluster_parameter_group_family" { + description = "The DB cluster parameter group family" + type = string + default = "docdb4.0" +} + +variable "db_cluster_parameter_group_parameters" { + description = "A list of DB cluster parameters to apply" + type = list(object({ + name = string + value = string + })) + default = [ + { + name = "tls" + value = "enabled" + }, + { + name = "audit_logs" + value = "enabled" + }, + { + name = "profiler" + value = "enabled" + }, + { + name = "profiler_threshold_ms" + value = "100" + } + ] +} + +variable "environment" { + description = "Environment name" + type = string + default = "prod" +} + +variable "project" { + description = "Project name" + type = string + default = "multi-az-docdb" +} + +variable "vpc_name" { + description = "Name of the VPC to use" + type = string + default = "arc-poc-vpc" +} diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..85fe389 --- /dev/null +++ b/locals.tf @@ -0,0 +1,41 @@ +locals { + # Cluster Configuration + cluster_identifier = var.cluster_identifier != null ? var.cluster_identifier : "${var.name_prefix}-${var.environment}" + + # Global Cluster Configuration + global_cluster_identifier = var.create_global_cluster ? ( + var.global_cluster_identifier != null ? var.global_cluster_identifier : "${var.name_prefix}-${var.environment}-global" + ) : null + + # Master Password Logic + master_password = var.master_password != null ? var.master_password : ( + var.secret_config.create && length(random_password.master) > 0 ? random_password.master[0].result : null + ) + + # KMS Key Configuration + kms_key_id = var.kms_config.key_id != null ? var.kms_config.key_id : ( + var.kms_config.create_key && length(module.kms) > 0 ? module.kms[0].key_arn : null + ) + + # Secrets Manager Configuration + secret_name = var.secret_config.name != null ? var.secret_config.name : "${var.cluster_identifier}-credentials-${random_id.secret_suffix.hex}" + + # Subnet Group Configuration + db_subnet_group_name = var.subnet_config.group_name != null ? var.subnet_config.group_name : ( + var.subnet_config.create_group ? "${var.name_prefix}-${var.environment}-subnet-group" : null + ) + + # Security Group Configuration + security_group_ids = concat( + var.security_group_ids, + var.create_security_group && length(module.security_group) > 0 ? [module.security_group[0].id] : [] + ) + + # Parameter Group Configuration + db_cluster_parameter_group_name = var.parameter_group_config.name != null ? var.parameter_group_config.name : ( + var.parameter_group_config.create ? "${var.name_prefix}-${var.environment}-cluster-pg" : null + ) + + # Event Subscription Configuration + event_subscription_name = var.event_subscription_config.name != null ? var.event_subscription_config.name : "${var.name_prefix}-${var.environment}-events" +} diff --git a/main.tf b/main.tf index 4f5fdfb..577b5a6 100644 --- a/main.tf +++ b/main.tf @@ -1,69 +1,345 @@ -################################################################################ -## defaults -################################################################################ -terraform { - required_version = "~> 1.3, < 2.0.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.0, < 6.0" +# Data source for current AWS account +data "aws_caller_identity" "current" {} + +# Random password for master user +resource "random_password" "master" { + count = var.secret_config.create && var.master_password == null ? 1 : 0 + length = 16 + special = true + override_special = "!#$%&*()-_=+[]{}<>:?" + min_lower = 1 + min_upper = 1 + min_numeric = 1 + min_special = 1 +} +resource "random_string" "suffix" { + length = 6 + upper = false + special = false +} + +resource "random_id" "secret_suffix" { + byte_length = 4 + keepers = { + cluster_identifier = var.cluster_identifier + } +} +# KMS Key using SourceFuse module +module "kms" { + count = var.kms_config.create_key ? 1 : 0 + source = "sourcefuse/arc-kms/aws" + version = "0.0.1" + + alias = "alias/${var.name_prefix}-${var.environment}-docdb-${random_string.suffix.result}" + description = var.kms_config.description + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "Enable IAM User Permissions" + Effect = "Allow" + Principal = { + AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" + } + Action = "kms:*" + Resource = "*" + } + ] + }) + tags = var.tags +} + +# Secrets Manager secret +resource "aws_secretsmanager_secret" "this" { + count = var.secret_config.create ? 1 : 0 + name = local.secret_name + description = var.secret_config.description + recovery_window_in_days = var.secret_config.recovery_window_in_days + kms_key_id = local.kms_key_id + force_overwrite_replica_secret = var.force_overwrite_replica_secret + + lifecycle { + create_before_destroy = true + } + + dynamic "replica" { + for_each = var.replica_region != null ? [1] : [] + content { + region = var.replica_region + kms_key_id = var.replica_kms_key_id } } + tags = var.tags +} + +resource "aws_secretsmanager_secret_version" "this" { + count = var.secret_config.create ? 1 : 0 + secret_id = aws_secretsmanager_secret.this[0].id + secret_string = jsonencode({ + username = var.master_username + password = local.master_password + engine = var.engine + host = aws_docdb_cluster.this.endpoint + port = var.port + dbname = var.database_name + }) + version_stages = var.secret_version_stages +} + +# DocumentDB Global Cluster +resource "aws_docdb_global_cluster" "this" { + count = var.create_global_cluster ? 1 : 0 + global_cluster_identifier = local.global_cluster_identifier + source_db_cluster_identifier = var.source_db_cluster_identifier + engine = var.engine + engine_version = var.engine_version + storage_encrypted = var.storage_encrypted + deletion_protection = var.deletion_protection + database_name = var.database_name } -module "doc_db_cluster" { - source = "cloudposse/documentdb-cluster/aws" - version = "0.24.0" - namespace = var.namespace - environment = var.environment - name = var.doc_db_cluster_name - cluster_size = var.cluster_size - master_username = var.master_username - instance_class = var.instance_class - db_port = var.db_port - vpc_id = var.vpc_id - subnet_ids = var.subnet_ids - zone_id = var.zone_id - apply_immediately = var.apply_immediately - auto_minor_version_upgrade = var.auto_minor_version_upgrade - allowed_security_groups = var.allowed_security_groups - allowed_cidr_blocks = var.allowed_cidr_blocks - snapshot_identifier = var.snapshot_identifier - retention_period = var.retention_period - preferred_backup_window = var.preferred_backup_window - preferred_maintenance_window = var.preferred_maintenance_window - cluster_parameters = var.cluster_parameters - cluster_family = var.cluster_family - engine = var.engine - engine_version = var.engine_version - storage_encrypted = var.storage_encrypted - kms_key_id = var.kms_key_id - skip_final_snapshot = var.skip_final_snapshot +# DB Subnet Group +resource "aws_docdb_subnet_group" "this" { + count = var.subnet_config.create_group ? 1 : 0 + name = local.db_subnet_group_name + description = var.db_subnet_group_description + subnet_ids = var.subnet_config.subnet_ids + tags = var.tags +} + +# Security Group +module "security_group" { + count = var.create_security_group ? 1 : 0 + source = "sourcefuse/arc-security-group/aws" + version = "0.0.2" + + name = "${var.name_prefix}-${var.environment}-sg" + description = "Security group for DocumentDB cluster" + vpc_id = var.vpc_id + ingress_rules = var.security_group_data.ingress_rules + egress_rules = var.security_group_data.egress_rules + + tags = var.tags +} + +# DB Cluster Parameter Group +resource "aws_docdb_cluster_parameter_group" "this" { + count = var.parameter_group_config.create ? 1 : 0 + family = var.parameter_group_config.family + name = local.db_cluster_parameter_group_name + description = var.db_cluster_parameter_group_description + tags = var.tags + + dynamic "parameter" { + for_each = var.parameter_group_config.parameters + content { + name = parameter.value.name + value = parameter.value.value + apply_method = lookup(parameter.value, "apply_method", "pending-reboot") + } + } +} + +# DocumentDB Event Subscription +resource "aws_docdb_event_subscription" "this" { + count = var.event_subscription_config.create ? 1 : 0 + name = local.event_subscription_name + sns_topic_arn = var.event_subscription_config.sns_topic_arn + source_type = var.event_subscription_config.source_type + source_ids = var.event_subscription_config.source_ids + event_categories = var.event_subscription_config.event_categories + enabled = var.event_subscription_config.enabled + tags = var.tags +} + +# DocumentDB Cluster +resource "aws_docdb_cluster" "this" { + # Basic Configuration + cluster_identifier = local.cluster_identifier + cluster_identifier_prefix = var.cluster_identifier_prefix + global_cluster_identifier = var.is_secondary_cluster ? var.existing_global_cluster_identifier : (var.create_global_cluster ? aws_docdb_global_cluster.this[0].id : null) + + # Engine Configuration + engine = var.engine + engine_version = var.engine_version + + # Authentication + master_username = var.is_secondary_cluster ? null : var.master_username + master_password = var.is_secondary_cluster || var.manage_master_user_password ? null : local.master_password + manage_master_user_password = var.is_secondary_cluster ? null : (var.manage_master_user_password ? true : null) + + + # Database Configuration + port = var.port + + # Backup Configuration + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier = var.final_snapshot_identifier + snapshot_identifier = var.snapshot_identifier + + # Maintenance Configuration + preferred_maintenance_window = var.preferred_maintenance_window + apply_immediately = var.apply_immediately + allow_major_version_upgrade = var.allow_major_version_upgrade + + # Security Configuration + storage_encrypted = var.storage_encrypted + kms_key_id = local.kms_key_id + deletion_protection = var.deletion_protection + + # Network Configuration + db_subnet_group_name = local.db_subnet_group_name + vpc_security_group_ids = local.security_group_ids + availability_zones = var.availability_zones + + # Parameter Groups + db_cluster_parameter_group_name = local.db_cluster_parameter_group_name + + # Logging Configuration enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - cluster_dns_name = var.cluster_dns_name - reader_dns_name = var.reader_dns_name - ssm_parameter_enabled = var.ssm_parameter_enabled - ssm_parameter_path_prefix = var.ssm_parameter_path_prefix - tags = var.tags + + tags = var.tags + + lifecycle { + ignore_changes = [ + master_password, + global_cluster_identifier, + snapshot_identifier + ] + } + + depends_on = [ + aws_docdb_subnet_group.this, + aws_docdb_cluster_parameter_group.this, + aws_docdb_global_cluster.this + ] } -//////////////// SSM VALUES //////////////////////////////////////// +# DocumentDB Cluster Instances +resource "aws_docdb_cluster_instance" "this" { + count = var.instance_count + identifier = var.instance_identifier_prefix != null ? "${var.instance_identifier_prefix}-${count.index + 1}" : "${local.cluster_identifier}-${count.index + 1}" + cluster_identifier = aws_docdb_cluster.this.id + + # Instance Configuration + instance_class = var.instance_class + engine = var.engine + + # Maintenance Configuration + apply_immediately = var.apply_immediately + auto_minor_version_upgrade = var.auto_minor_version_upgrade + preferred_maintenance_window = var.preferred_maintenance_window + + # Performance Configuration + promotion_tier = lookup(var.instance_promotion_tiers, count.index, 0) + + # Network Configuration + availability_zone = var.instance_availability_zones != null ? element(var.instance_availability_zones, count.index) : null + ca_cert_identifier = var.ca_cert_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + + tags = merge( + var.tags, + { + Name = var.instance_identifier_prefix != null ? "${var.instance_identifier_prefix}-${count.index + 1}" : "${local.cluster_identifier}-${count.index + 1}" + } + ) +} + +# CloudWatch Log Groups +resource "aws_cloudwatch_log_group" "audit" { + count = contains(var.enabled_cloudwatch_logs_exports, "audit") ? 1 : 0 + name = "/aws/docdb/${aws_docdb_cluster.this.cluster_identifier}/audit" + retention_in_days = var.cloudwatch_log_retention_in_days + kms_key_id = var.cloudwatch_log_kms_key_id + tags = var.tags +} + +resource "aws_cloudwatch_log_group" "profiler" { + count = contains(var.enabled_cloudwatch_logs_exports, "profiler") ? 1 : 0 + name = "/aws/docdb/${aws_docdb_cluster.this.cluster_identifier}/profiler" + retention_in_days = var.cloudwatch_log_retention_in_days + kms_key_id = var.cloudwatch_log_kms_key_id + tags = var.tags +} + +# CloudWatch Alarms +resource "aws_cloudwatch_metric_alarm" "cpu_utilization" { + count = var.alarm_config.create_alarms ? var.instance_count : 0 + alarm_name = "${aws_docdb_cluster_instance.this[count.index].identifier}-cpu-utilization" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = var.alarm_config.cpu.evaluation_periods + metric_name = "CPUUtilization" + namespace = "AWS/DocDB" + period = var.alarm_config.cpu.period + statistic = "Average" + threshold = var.alarm_config.cpu.threshold + alarm_description = "This metric monitors DocumentDB instance CPU utilization" + alarm_actions = var.alarm_config.alarm_actions + ok_actions = var.alarm_config.ok_actions + treat_missing_data = var.treat_missing_data + + dimensions = { + DBInstanceIdentifier = aws_docdb_cluster_instance.this[count.index].identifier + } + + tags = var.tags +} + +resource "aws_cloudwatch_metric_alarm" "database_connections" { + count = var.alarm_config.create_alarms ? var.instance_count : 0 + alarm_name = "${aws_docdb_cluster_instance.this[count.index].identifier}-database-connections" + comparison_operator = "GreaterThanThreshold" + evaluation_periods = var.alarm_config.connections.evaluation_periods + metric_name = "DatabaseConnections" + namespace = "AWS/DocDB" + period = var.alarm_config.connections.period + statistic = "Average" + threshold = var.alarm_config.connections.threshold + alarm_description = "This metric monitors DocumentDB instance database connections" + alarm_actions = var.alarm_config.alarm_actions + ok_actions = var.alarm_config.ok_actions + treat_missing_data = var.treat_missing_data + + dimensions = { + DBInstanceIdentifier = aws_docdb_cluster_instance.this[count.index].identifier + } + + tags = var.tags +} + +# IAM Role for Enhanced Monitoring +resource "aws_iam_role" "enhanced_monitoring" { + count = var.monitoring_interval > 0 && var.create_monitoring_role ? 1 : 0 + name = "${var.name_prefix}-${var.environment}-docdb-monitoring-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "monitoring.rds.amazonaws.com" + } + } + ] + }) -resource "aws_ssm_parameter" "documentdb_host" { - name = var.documentdb_host - type = "String" - value = module.doc_db_cluster.endpoint + tags = var.tags } -resource "aws_ssm_parameter" "documentdb_port" { - name = var.documentdb_port - type = "String" - value = var.db_port +resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { + count = var.monitoring_interval > 0 && var.create_monitoring_role ? 1 : 0 + role = aws_iam_role.enhanced_monitoring[0].name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" } -resource "aws_ssm_parameter" "documentdb_username" { - name = var.documentdb_username - type = "String" - value = module.doc_db_cluster.master_username +# Attach additional user-provided policies to default role +resource "aws_iam_role_policy_attachment" "additional" { + count = var.monitoring_interval > 0 && var.create_monitoring_role ? 1 : 0 + role = aws_iam_role.enhanced_monitoring[0].name + policy_arn = var.additional_policy_arns[count.index] } diff --git a/outputs.tf b/outputs.tf index a681ead..81ae36f 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,19 +1,311 @@ -output "cluster_name" { - value = module.doc_db_cluster.cluster_name - description = "DocumentDB Cluster Identifier" +output "global_cluster_arn" { + description = "Amazon Resource Name (ARN) of the global cluster" + value = var.create_global_cluster ? aws_docdb_global_cluster.this[0].arn : null } -output "arn" { - value = module.doc_db_cluster.arn - description = "Amazon Resource Name (ARN) of the DocumentDB cluster" +output "global_cluster_id" { + description = "The DocumentDB global cluster identifier" + value = var.create_global_cluster ? aws_docdb_global_cluster.this[0].id : null } -output "endpoint" { - value = module.doc_db_cluster.endpoint - description = "Endpoint of the DocumentDB cluster" +output "global_cluster_identifier" { + description = "The DocumentDB global cluster identifier" + value = var.create_global_cluster ? aws_docdb_global_cluster.this[0].global_cluster_identifier : null } -output "reader_endpoint" { - value = module.doc_db_cluster.reader_endpoint - description = "Read-only endpoint of the DocumentDB cluster, automatically load-balanced across replicas" +output "global_cluster_resource_id" { + description = "The DocumentDB Global Cluster Resource ID" + value = var.create_global_cluster ? aws_docdb_global_cluster.this[0].global_cluster_resource_id : null +} + +output "global_cluster_members" { + description = "List of DocumentDB Clusters that are part of this global cluster" + value = var.create_global_cluster ? aws_docdb_global_cluster.this[0].global_cluster_members : null +} + +output "cluster_arn" { + description = "Amazon Resource Name (ARN) of the cluster" + value = aws_docdb_cluster.this.arn +} + +output "cluster_id" { + description = "The DocumentDB cluster identifier" + value = aws_docdb_cluster.this.id +} + +output "cluster_identifier" { + description = "The DocumentDB cluster identifier" + value = aws_docdb_cluster.this.cluster_identifier +} + +output "cluster_endpoint" { + description = "The DNS address of the DocumentDB instance" + value = aws_docdb_cluster.this.endpoint +} + +output "cluster_reader_endpoint" { + description = "A read-only endpoint for the DocumentDB cluster, automatically load-balanced across replicas" + value = aws_docdb_cluster.this.reader_endpoint +} + +output "cluster_port" { + description = "The database port" + value = aws_docdb_cluster.this.port +} + +output "cluster_hosted_zone_id" { + description = "The Route53 Hosted Zone ID of the endpoint" + value = aws_docdb_cluster.this.hosted_zone_id +} + +output "cluster_resource_id" { + description = "The DocumentDB Cluster Resource ID" + value = aws_docdb_cluster.this.cluster_resource_id +} + +output "cluster_members" { + description = "List of DocumentDB Instances that are a part of this cluster" + value = aws_docdb_cluster.this.cluster_members +} + +output "instance_ids" { + description = "List of DocumentDB instance identifiers" + value = aws_docdb_cluster_instance.this[*].id +} + +output "instance_arns" { + description = "List of DocumentDB instance ARNs" + value = aws_docdb_cluster_instance.this[*].arn +} + +output "instance_endpoints" { + description = "List of DocumentDB instance endpoints" + value = aws_docdb_cluster_instance.this[*].endpoint +} + +output "db_subnet_group_name" { + description = "The name of the DB subnet group" + value = var.subnet_config.create_group ? aws_docdb_subnet_group.this[0].name : var.subnet_config.group_name +} + +output "db_cluster_parameter_group_name" { + description = "The name of the DB cluster parameter group" + value = var.parameter_group_config.create ? aws_docdb_cluster_parameter_group.this[0].name : var.parameter_group_config.name +} + +output "security_group_id" { + description = "The ID of the security group created for the DocumentDB cluster" + value = var.create_security_group ? module.security_group[0].id : null +} + +output "security_group_arn" { + description = "The ARN of the security group created for the DocumentDB cluster" + value = var.create_security_group ? module.security_group[0].id : null +} + +output "kms_key_id" { + description = "The globally unique identifier for the key" + value = var.kms_config.create_key ? module.kms[0].key_id : null +} + +output "kms_key_arn" { + description = "The Amazon Resource Name (ARN) of the key" + value = var.kms_config.create_key ? module.kms[0].key_arn : null +} + +output "secret_arn" { + description = "The ARN of the secret" + value = var.secret_config.create ? aws_secretsmanager_secret.this[0].arn : null +} + +output "secret_id" { + description = "The ID of the secret" + value = var.secret_config.create ? aws_secretsmanager_secret.this[0].id : null +} + +output "master_username" { + description = "The master username for the DB cluster" + value = var.master_username +} + +# Additional comprehensive outputs + +output "cluster_database_name" { + description = "The name of the database" + value = var.database_name +} + +output "cluster_engine" { + description = "The database engine" + value = aws_docdb_cluster.this.engine +} + +output "cluster_engine_version" { + description = "The database engine version" + value = aws_docdb_cluster.this.engine_version +} + +output "cluster_backup_retention_period" { + description = "The backup retention period" + value = aws_docdb_cluster.this.backup_retention_period +} + +output "cluster_preferred_backup_window" { + description = "The daily time range during which the backups happen" + value = aws_docdb_cluster.this.preferred_backup_window +} + +output "cluster_preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur" + value = aws_docdb_cluster.this.preferred_maintenance_window +} + +output "cluster_storage_encrypted" { + description = "Specifies whether the DB cluster is encrypted" + value = aws_docdb_cluster.this.storage_encrypted +} + +output "cluster_kms_key_id" { + description = "The ARN for the KMS encryption key" + value = aws_docdb_cluster.this.kms_key_id +} + +output "cluster_availability_zones" { + description = "The availability zones of the cluster" + value = aws_docdb_cluster.this.availability_zones +} + +output "cluster_vpc_security_group_ids" { + description = "List of VPC security groups associated to the cluster" + value = aws_docdb_cluster.this.vpc_security_group_ids +} + +output "cluster_enabled_cloudwatch_logs_exports" { + description = "List of log types to export to cloudwatch" + value = aws_docdb_cluster.this.enabled_cloudwatch_logs_exports +} + +output "cluster_deletion_protection" { + description = "Specifies whether the cluster has deletion protection enabled" + value = aws_docdb_cluster.this.deletion_protection +} + +output "instance_identifiers" { + description = "List of DocumentDB instance identifiers" + value = aws_docdb_cluster_instance.this[*].identifier +} + +output "instance_classes" { + description = "List of DocumentDB instance classes" + value = aws_docdb_cluster_instance.this[*].instance_class +} + +output "instance_availability_zones" { + description = "List of availability zones for the instances" + value = aws_docdb_cluster_instance.this[*].availability_zone +} + +output "instance_engines" { + description = "List of database engines for the instances" + value = aws_docdb_cluster_instance.this[*].engine +} + +output "instance_engine_versions" { + description = "List of database engine versions for the instances" + value = aws_docdb_cluster_instance.this[*].engine_version +} + +output "instance_ports" { + description = "List of database ports for the instances" + value = aws_docdb_cluster_instance.this[*].port +} + +output "instance_writers" { + description = "List indicating which instances are writers" + value = aws_docdb_cluster_instance.this[*].writer +} + +output "instance_promotion_tiers" { + description = "List of promotion tiers for the instances" + value = aws_docdb_cluster_instance.this[*].promotion_tier +} + +output "instance_ca_cert_identifiers" { + description = "List of CA certificate identifiers for the instances" + value = aws_docdb_cluster_instance.this[*].ca_cert_identifier +} + +output "instance_performance_insights_kms_key_ids" { + description = "List of KMS key identifiers for Performance Insights encryption" + value = aws_docdb_cluster_instance.this[*].performance_insights_kms_key_id +} + +output "db_parameter_group_name" { + description = "The name of the DB parameter group" + value = var.db_parameter_group_name +} + +output "db_parameter_group_arn" { + description = "The ARN of the DB parameter group" + value = null +} + +output "db_cluster_parameter_group_arn" { + description = "The ARN of the DB cluster parameter group" + value = var.parameter_group_config.create ? aws_docdb_cluster_parameter_group.this[0].arn : null +} + +output "db_subnet_group_arn" { + description = "The ARN of the DB subnet group" + value = var.subnet_config.create_group ? aws_docdb_subnet_group.this[0].arn : null +} + +output "event_subscription_arn" { + description = "The ARN of the DocumentDB event subscription" + value = var.event_subscription_config.create ? aws_docdb_event_subscription.this[0].arn : null +} + +output "event_subscription_id" { + description = "The ID of the DocumentDB event subscription" + value = var.event_subscription_config.create ? aws_docdb_event_subscription.this[0].id : null +} + +output "cloudwatch_log_group_audit_name" { + description = "The name of the CloudWatch log group for audit logs" + value = contains(var.enabled_cloudwatch_logs_exports, "audit") ? aws_cloudwatch_log_group.audit[0].name : null +} + +output "cloudwatch_log_group_profiler_name" { + description = "The name of the CloudWatch log group for profiler logs" + value = contains(var.enabled_cloudwatch_logs_exports, "profiler") ? aws_cloudwatch_log_group.profiler[0].name : null +} + +output "cloudwatch_log_group_audit_arn" { + description = "The ARN of the CloudWatch log group for audit logs" + value = contains(var.enabled_cloudwatch_logs_exports, "audit") ? aws_cloudwatch_log_group.audit[0].arn : null +} + +output "cloudwatch_log_group_profiler_arn" { + description = "The ARN of the CloudWatch log group for profiler logs" + value = contains(var.enabled_cloudwatch_logs_exports, "profiler") ? aws_cloudwatch_log_group.profiler[0].arn : null +} + +output "cloudwatch_alarm_cpu_arns" { + description = "List of ARNs for CPU utilization CloudWatch alarms" + value = var.alarm_config.create_alarms ? aws_cloudwatch_metric_alarm.cpu_utilization[*].arn : [] +} + +output "cloudwatch_alarm_connection_arns" { + description = "List of ARNs for database connection CloudWatch alarms" + value = var.alarm_config.create_alarms ? aws_cloudwatch_metric_alarm.database_connections[*].arn : [] +} + +output "enhanced_monitoring_role_arn" { + description = "The ARN of the enhanced monitoring IAM role" + value = var.monitoring_interval > 0 && var.create_monitoring_role ? aws_iam_role.enhanced_monitoring[0].arn : null +} + +output "enhanced_monitoring_role_name" { + description = "The name of the enhanced monitoring IAM role" + value = var.monitoring_interval > 0 && var.create_monitoring_role ? aws_iam_role.enhanced_monitoring[0].name : null } diff --git a/variables.tf b/variables.tf index 084d33a..2c500ef 100644 --- a/variables.tf +++ b/variables.tf @@ -1,206 +1,493 @@ - -####################################################################### -## shared -####################################################################### -variable "namespace" { +variable "cluster_identifier" { + description = "The cluster identifier. If omitted, Terraform will assign a random, unique identifier" type = string - description = "Namespace for the resources." + default = null } -variable "environment" { +variable "engine" { + description = "The name of the database engine to be used for this DB cluster" type = string - default = "" - description = "environment value, e.g 'prod', 'staging', 'dev', 'UAT'" + default = "docdb" + validation { + condition = var.engine == "docdb" + error_message = "Engine must be 'docdb' for DocumentDB clusters." + } } -####### documentdb cluster variables - -variable "doc_db_cluster_name" { - description = "Name of the DB cluster" +variable "engine_version" { + description = "The database engine version" type = string -} - -variable "cluster_size" { - description = "Number of DB instances to create in the cluster" - type = number + default = "4.0.0" } variable "master_username" { description = "Username for the master DB user" type = string + default = "docdbadmin" + validation { + condition = length(var.master_username) >= 1 && length(var.master_username) <= 63 + error_message = "Master username must be between 1 and 63 characters." + } } -variable "instance_class" { - description = "Instance class to use for the DB instances in the cluster" +variable "manage_master_user_password" { + description = "Set to true to allow RDS to manage the master user password in Secrets Manager" + type = bool + default = true +} + +variable "master_password" { + description = "Password for the master DB user. If not provided and create_secret is true, will be auto-generated" type = string + default = null + sensitive = true } -variable "db_port" { - description = "The port on which the DB accepts connections" +variable "backup_retention_period" { + description = "The days to retain backups for" type = number - default = 27017 + default = 7 + validation { + condition = var.backup_retention_period >= 1 && var.backup_retention_period <= 35 + error_message = "Backup retention period must be between 1 and 35 days." + } } -variable "vpc_id" { - description = "ID of the VPC to create the DB cluster in" +variable "preferred_backup_window" { + description = "The daily time range during which automated backups are created" type = string + default = "07:00-09:00" } -variable "subnet_ids" { - description = "List of subnet IDs to create the DB cluster in" - type = list(string) +variable "preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur" + type = string + default = "sun:05:00-sun:06:00" } -variable "zone_id" { +variable "skip_final_snapshot" { + description = "Determines whether a final DB snapshot is created before the DB cluster is deleted" + type = bool + default = false +} + +variable "final_snapshot_identifier" { + description = "The name of your final DB snapshot when this DB cluster is deleted" type = string - default = "" - description = "Route53 parent zone ID. If provided (not empty), the module will create sub-domain DNS records for the DocumentDB master and replicas" + default = null } variable "apply_immediately" { - type = bool description = "Specifies whether any cluster modifications are applied immediately, or during the next maintenance window" + type = bool default = true } variable "auto_minor_version_upgrade" { + description = "Indicates that minor engine upgrades will be applied automatically to the DB cluster during the maintenance window" type = bool - description = "Specifies whether any minor engine upgrades will be applied automatically to the DB instance during the maintenance window or not" default = true } -variable "allowed_security_groups" { +variable "storage_encrypted" { + description = "Specifies whether the DB cluster is encrypted" + type = bool + default = true +} + +variable "kms_config" { + description = "KMS configuration for DocumentDB encryption" + type = object({ + key_id = optional(string, null) + create_key = optional(bool, false) + description = optional(string, "DocumentDB cluster encryption key") + }) + default = {} +} + +variable "subnet_config" { + description = "Subnet configuration for DocumentDB cluster" + type = object({ + group_name = optional(string, null) + create_group = optional(bool, true) + subnet_ids = optional(list(string), []) + }) + default = {} + validation { + condition = length(var.subnet_config.subnet_ids) >= 2 || length(var.subnet_config.subnet_ids) == 0 + error_message = "At least 2 subnet IDs must be provided when specifying subnet_ids." + } +} + +variable "create_security_group" { + description = "Whether to create a security group for the DocumentDB cluster" + type = bool + default = true +} + +variable "vpc_id" { + description = "VPC ID where the security group will be created" + type = string + default = null +} + +variable "security_group_ids" { + description = "List of security group IDs to associate with the DocumentDB cluster" type = list(string) default = [] - description = "List of existing Security Groups to be allowed to connect to the DocumentDB cluster" } -variable "allowed_cidr_blocks" { + +variable "security_group_data" { + type = object({ + security_group_ids_to_attach = optional(list(string), []) + create = optional(bool, true) + description = optional(string, null) + ingress_rules = optional(list(object({ + description = optional(string, null) + cidr_block = optional(string, null) + source_security_group_id = optional(string, null) + from_port = number + ip_protocol = string + to_port = string + self = optional(bool, false) + })), []) + egress_rules = optional(list(object({ + description = optional(string, null) + cidr_block = optional(string, null) + destination_security_group_id = optional(string, null) + from_port = number + ip_protocol = string + to_port = string + prefix_list_id = optional(string, null) + })), []) + }) + description = "(optional) Security Group data" + default = { + create = false + } +} + + +variable "parameter_group_config" { + description = "DB cluster parameter group configuration" + type = object({ + name = optional(string, null) + create = optional(bool, false) + family = optional(string, "docdb4.0") + parameters = optional(list(object({ + name = string + value = string + })), []) + }) + default = {} +} + +variable "enabled_cloudwatch_logs_exports" { + description = "List of log types to export to cloudwatch" type = list(string) default = [] - description = "List of CIDR blocks to be allowed to connect to the DocumentDB cluster" + validation { + condition = alltrue([ + for log_type in var.enabled_cloudwatch_logs_exports : + contains(["audit", "profiler"], log_type) + ]) + error_message = "Enabled CloudWatch logs exports must be one of: audit, profiler." + } } -variable "snapshot_identifier" { - type = string - default = "" - description = "Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot" +variable "deletion_protection" { + description = "A value that indicates whether the DB cluster has deletion protection enabled" + type = bool + default = false } -variable "retention_period" { +variable "port" { + description = "The port on which the DB accepts connections" type = number - default = 5 - description = "Number of days to retain backups for" + default = 27017 } -variable "preferred_backup_window" { +variable "instance_count" { + description = "Number of instances in the cluster" + type = number + default = 1 + validation { + condition = var.instance_count >= 1 && var.instance_count <= 16 + error_message = "Instance count must be between 1 and 16." + } +} + +variable "instance_class" { + description = "The instance class to use" type = string - default = "07:00-09:00" - description = "Daily time range during which the backups happen" + default = "db.t3.medium" +} + +variable "secret_config" { + description = "Secrets Manager configuration for DocumentDB credentials" + type = object({ + create = optional(bool, false) + name = optional(string, null) + description = optional(string, "DocumentDB cluster master credentials") + recovery_window_in_days = optional(number, 7) + }) + default = {} + validation { + condition = var.secret_config.recovery_window_in_days >= 7 && var.secret_config.recovery_window_in_days <= 30 + error_message = "Secret recovery window must be between 7 and 30 days." + } +} + +variable "create_global_cluster" { + description = "Whether to create a DocumentDB Global Cluster" + type = bool + default = false } -variable "preferred_maintenance_window" { +variable "global_cluster_identifier" { + description = "The global cluster identifier" type = string - default = "Mon:22:00-Mon:23:00" - description = "The window to perform maintenance in. Syntax: `ddd:hh24:mi-ddd:hh24:mi`." + default = null } -variable "cluster_parameters" { - type = list(object({ - apply_method = string - name = string - value = string - })) - default = [] - description = "List of DB parameters to apply" +variable "source_db_cluster_identifier" { + description = "The identifier of the source cluster for global cluster" + type = string + default = null +} + + +variable "is_secondary_cluster" { + description = "Whether this cluster is a secondary cluster in a global cluster" + type = bool + default = false } -variable "cluster_family" { +variable "existing_global_cluster_identifier" { + description = "The identifier of an existing global cluster to join" type = string - default = "docdb3.6" - description = "The family of the DocumentDB cluster parameter group. For more details, see https://docs.aws.amazon.com/documentdb/latest/developerguide/db-cluster-parameter-group-create.html" + default = null } -variable "engine" { +variable "tags" { + description = "A map of tags to assign to the resource" + type = map(string) + default = {} +} + +variable "name_prefix" { + description = "Name prefix for resources" type = string default = "docdb" - description = "The name of the database engine to be used for this DB cluster. Defaults to `docdb`. Valid values: `docdb`" } -variable "engine_version" { +variable "environment" { + description = "Environment name" type = string - default = "3.6.0" - description = "The version number of the database engine to use" + default = "dev" } -variable "storage_encrypted" { +# Additional comprehensive variables for all DocumentDB features + +variable "cluster_identifier_prefix" { + description = "Creates a unique cluster identifier beginning with the specified prefix" + type = string + default = null +} + +variable "database_name" { + description = "The name of the database to create when the DB cluster is created" + type = string + default = null +} + +variable "copy_tags_to_snapshot" { + description = "Copy all Cluster tags to snapshots" type = bool - description = "Specifies whether the DB cluster is encrypted" - default = true + default = false } -variable "kms_key_id" { +variable "snapshot_identifier" { + description = "Specifies whether or not to create this cluster from a snapshot" type = string - description = "The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true`" - default = "" + default = null } -variable "skip_final_snapshot" { +variable "allow_major_version_upgrade" { + description = "Enable to allow major engine version upgrades when changing engine versions" type = bool - description = "Determines whether a final DB snapshot is created before the DB cluster is deleted" - default = true + default = false } -variable "enabled_cloudwatch_logs_exports" { +variable "availability_zones" { + description = "A list of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created" type = list(string) - description = "List of log types to export to cloudwatch. The following log types are supported: `audit`, `error`, `general`, `slowquery`" - default = [] + default = null } -variable "cluster_dns_name" { +variable "instance_identifier_prefix" { + description = "Creates a unique identifier beginning with the specified prefix" type = string - description = "Name of the cluster CNAME record to create in the parent DNS zone specified by `zone_id`. If left empty, the name will be auto-asigned using the format `master.var.name`" - default = "" + default = null } -variable "reader_dns_name" { - type = string - description = "Name of the reader endpoint CNAME record to create in the parent DNS zone specified by `zone_id`. If left empty, the name will be auto-asigned using the format `replicas.var.name`" - default = "" +variable "instance_promotion_tiers" { + description = "Map of instance index to promotion tier (0-15). Lower number = higher priority for promotion" + type = map(number) + default = {} + validation { + condition = alltrue([ + for tier in values(var.instance_promotion_tiers) : + tier >= 0 && tier <= 15 + ]) + error_message = "Promotion tier must be between 0 and 15." + } } -variable "ssm_parameter_enabled" { - description = "Whether to create an SSM parameter for the master password" +variable "monitoring_interval" { + description = "The interval for collecting enhanced monitoring metrics. Valid values: 0, 1, 5, 10, 15, 30, 60" + type = number + default = 0 + validation { + condition = contains([0, 1, 5, 10, 15, 30, 60], var.monitoring_interval) + error_message = "Monitoring interval must be one of: 0, 1, 5, 10, 15, 30, 60." + } +} + + +variable "create_monitoring_role" { + description = "Whether to create an IAM role for enhanced monitoring" type = bool - default = true + default = false } -variable "tags" { - type = map(string) - description = "Additional tags to apply to all resources" - default = {} +variable "instance_availability_zones" { + description = "List of availability zones for instances. If not specified, instances will be distributed across available AZs" + type = list(string) + default = null +} + +variable "ca_cert_identifier" { + description = "The identifier of the CA certificate for the DB instance" + type = string + default = null +} + +variable "db_parameter_group_name" { + description = "Name of the DB parameter group to associate with instances" + type = string + default = null } -variable "ssm_parameter_path_prefix" { + + +variable "db_subnet_group_description" { + description = "Description for the DB subnet group" type = string - default = "/arc/doc_db/master_password/" - description = "The path prefix for the created SSM parameter e.g. '/docdb/master-password/dev'. `ssm_parameter_enabled` must be set to `true` for this to take affect." + default = "DocumentDB subnet group" } -variable "documentdb_host" { +variable "db_cluster_parameter_group_description" { + description = "Description for the DB cluster parameter group" type = string - description = "The name for the DocumentDB host SSM parameter" - default = "/arc/doc_db/host" + default = "DocumentDB cluster parameter group" +} + +variable "force_overwrite_replica_secret" { + description = "Accepts boolean value to specify whether to overwrite a secret with the same name in the destination Region" + type = bool + default = false } -variable "documentdb_port" { +variable "replica_region" { + description = "Region for replicating the secret" type = string - description = "The name for the DocumentDB port SSM parameter" - default = "/arc/doc_db/port" + default = null } -variable "documentdb_username" { +variable "replica_kms_key_id" { + description = "KMS key ID for replica secret encryption" type = string - description = "The name for the DocumentDB username SSM parameter" - default = "/arc/doc_db/username" + default = null +} + +variable "secret_version_stages" { + description = "Specifies text data that you want to encrypt and store in this version of the secret" + type = list(string) + default = null +} + +variable "event_subscription_config" { + description = "Configuration for RDS event subscription" + type = object({ + create = optional(bool, false) + name = optional(string, null) + sns_topic_arn = optional(string, null) + enabled = optional(bool, true) + source_type = optional(string, "db-cluster") + source_ids = optional(list(string), []) + event_categories = optional(list(string), []) + }) + default = {} + validation { + condition = contains([ + "db-instance", "db-cluster", "db-parameter-group", + "db-security-group", "db-snapshot", "db-cluster-snapshot" + ], var.event_subscription_config.source_type) + error_message = "Event source type must be one of: db-instance, db-cluster, db-parameter-group, db-security-group, db-snapshot, db-cluster-snapshot." + } +} + +variable "cloudwatch_log_retention_in_days" { + description = "Specifies the number of days you want to retain log events in the specified log group" + type = number + default = 7 + validation { + condition = contains([ + 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653 + ], var.cloudwatch_log_retention_in_days) + error_message = "CloudWatch log retention must be a valid value." + } +} + +variable "cloudwatch_log_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data" + type = string + default = null +} + +variable "alarm_config" { + description = "CloudWatch alarm configuration for DocumentDB monitoring" + type = object({ + create_alarms = optional(bool, false) + cpu = optional(object({ + threshold = optional(number, 80) + evaluation_periods = optional(number, 2) + period = optional(number, 300) + }), {}) + connections = optional(object({ + threshold = optional(number, 80) + evaluation_periods = optional(number, 2) + period = optional(number, 300) + }), {}) + alarm_actions = optional(list(string), []) + ok_actions = optional(list(string), []) + }) + default = {} +} + +variable "treat_missing_data" { + description = "Sets how this alarm is to handle missing data points" + type = string + default = "missing" + validation { + condition = contains(["breaching", "notBreaching", "ignore", "missing"], var.treat_missing_data) + error_message = "Treat missing data must be one of: breaching, notBreaching, ignore, missing." + } +} +variable "additional_policy_arns" { + description = "List of additional IAM policy ARNs to attach to the Lambda role" + type = list(string) + default = [] } diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..674db6f --- /dev/null +++ b/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0, < 7.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.1" + } + } +}