diff --git a/README.md b/README.md index a25443c..b7b7a17 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Terraform module which creates AWS RDS Aurora resources. - Custom endpoints - RDS multi-AZ support (not Aurora) - Aurora Limitless +- Aurora DSQL cluster ## Usage @@ -205,6 +206,33 @@ module "cluster" { } ``` +## DSQL Multi Region Peered Clusters +```hcl +module "dsql_cluster_1" { + source = "../../modules/dsql" + + witness_region = "us-west-2" + create_cluster_peering = true + clusters = [module.dsql_cluster_2.arn] + + tags = { Name = "dsql-1" } +} + +module "dsql_cluster_2" { + source = "../../modules/dsql" + + witness_region = "us-west-2" + create_cluster_peering = true + clusters = [module.dsql_cluster_1.arn] + + tags = { Name = "dsql-2" } + + providers = { + aws = aws.region2 + } +} +``` + ## Examples - [Autoscaling](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/autoscaling): A PostgreSQL cluster with enhanced monitoring and autoscaling enabled @@ -215,6 +243,7 @@ module "cluster" { - [PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/postgresql): A simple PostgreSQL cluster - [S3 Import](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/s3-import): A MySQL cluster created from a Percona Xtrabackup stored in S3 - [Serverless](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/serverless): Serverless V1 and V2 (PostgreSQL and MySQL) +- [DSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/dsql): Multi region and single region DSQL clusters ## Documentation diff --git a/examples/dsql/README.md b/examples/dsql/README.md new file mode 100644 index 0000000..e381540 --- /dev/null +++ b/examples/dsql/README.md @@ -0,0 +1,59 @@ +# Aurora DSQL Cluster Example + +Configuration in this directory creates multi-region peered Aurora DSQL clusters and a single region Aurora DSQL cluster. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.100 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [dsql\_cluster\_1](#module\_dsql\_cluster\_1) | ../../modules/dsql | n/a | +| [dsql\_cluster\_2](#module\_dsql\_cluster\_2) | ../../modules/dsql | n/a | +| [dsql\_single\_region](#module\_dsql\_single\_region) | ../../modules/dsql | n/a | + +## Resources + +No resources. + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [dsql\_cluster\_1\_arn](#output\_dsql\_cluster\_1\_arn) | ARN of the cluster | +| [dsql\_cluster\_1\_encryption\_details](#output\_dsql\_cluster\_1\_encryption\_details) | Encryption configuration details for the DSQL cluster | +| [dsql\_cluster\_1\_identifier](#output\_dsql\_cluster\_1\_identifier) | Cluster identifier | +| [dsql\_cluster\_1\_multi\_region\_properties](#output\_dsql\_cluster\_1\_multi\_region\_properties) | Multi-region properties of the DSQL cluster | +| [dsql\_cluster\_1\_vpc\_endpoint\_service\_name](#output\_dsql\_cluster\_1\_vpc\_endpoint\_service\_name) | The DSQL cluster's VPC endpoint service name | +| [dsql\_cluster\_2\_arn](#output\_dsql\_cluster\_2\_arn) | ARN of the cluster | +| [dsql\_cluster\_2\_encryption\_details](#output\_dsql\_cluster\_2\_encryption\_details) | Encryption configuration details for the DSQL cluster | +| [dsql\_cluster\_2\_identifier](#output\_dsql\_cluster\_2\_identifier) | Cluster identifier | +| [dsql\_cluster\_2\_multi\_region\_properties](#output\_dsql\_cluster\_2\_multi\_region\_properties) | Multi-region properties of the DSQL cluster | +| [dsql\_cluster\_2\_vpc\_endpoint\_service\_name](#output\_dsql\_cluster\_2\_vpc\_endpoint\_service\_name) | The DSQL cluster's VPC endpoint service name | + diff --git a/examples/dsql/main.tf b/examples/dsql/main.tf new file mode 100644 index 0000000..c605446 --- /dev/null +++ b/examples/dsql/main.tf @@ -0,0 +1,63 @@ +provider "aws" { + region = local.region +} + +provider "aws" { + region = local.region2 + alias = "region2" +} + +locals { + name = "ex-${basename(path.cwd)}" + region = "us-east-1" + region2 = "us-east-2" + witness_region = "us-west-2" + + tags = { + Example = local.name + GithubRepo = "terraform-aws-rds-aurora" + GithubOrg = "terraform-aws-modules" + } +} + +################################################################################ +# RDS Aurora Module +################################################################################ + +module "dsql_cluster_1" { + source = "../../modules/dsql" + + deletion_protection_enabled = false + witness_region = local.witness_region + create_cluster_peering = true + clusters = [module.dsql_cluster_2.arn] + + timeouts = { + create = "1h" + } + + tags = merge(local.tags, { Name = local.name }) +} + +module "dsql_cluster_2" { + source = "../../modules/dsql" + + deletion_protection_enabled = false + witness_region = local.witness_region + create_cluster_peering = true + clusters = [module.dsql_cluster_1.arn] + + tags = merge(local.tags, { Name = local.name }) + + providers = { + aws = aws.region2 + } +} + +module "dsql_single_region" { + source = "../../modules/dsql" + + deletion_protection_enabled = false + + tags = merge(local.tags, { Name = "single-region" }) +} diff --git a/examples/dsql/outputs.tf b/examples/dsql/outputs.tf new file mode 100644 index 0000000..4fa8283 --- /dev/null +++ b/examples/dsql/outputs.tf @@ -0,0 +1,49 @@ +output "dsql_cluster_1_arn" { + description = "ARN of the cluster" + value = module.dsql_cluster_1.arn +} + +output "dsql_cluster_1_identifier" { + description = "Cluster identifier" + value = module.dsql_cluster_1.identifier +} + +output "dsql_cluster_1_encryption_details" { + description = "Encryption configuration details for the DSQL cluster" + value = module.dsql_cluster_1.encryption_details +} + +output "dsql_cluster_1_multi_region_properties" { + description = "Multi-region properties of the DSQL cluster" + value = module.dsql_cluster_1.multi_region_properties +} + +output "dsql_cluster_1_vpc_endpoint_service_name" { + description = "The DSQL cluster's VPC endpoint service name" + value = module.dsql_cluster_1.vpc_endpoint_service_name +} + +output "dsql_cluster_2_arn" { + description = "ARN of the cluster" + value = module.dsql_cluster_2.arn +} + +output "dsql_cluster_2_identifier" { + description = "Cluster identifier" + value = module.dsql_cluster_2.identifier +} + +output "dsql_cluster_2_encryption_details" { + description = "Encryption configuration details for the DSQL cluster" + value = module.dsql_cluster_2.encryption_details +} + +output "dsql_cluster_2_multi_region_properties" { + description = "Multi-region properties of the DSQL cluster" + value = module.dsql_cluster_2.multi_region_properties +} + +output "dsql_cluster_2_vpc_endpoint_service_name" { + description = "The DSQL cluster's VPC endpoint service name" + value = module.dsql_cluster_2.vpc_endpoint_service_name +} diff --git a/examples/dsql/variables.tf b/examples/dsql/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/dsql/versions.tf b/examples/dsql/versions.tf new file mode 100644 index 0000000..7aad8ab --- /dev/null +++ b/examples/dsql/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.100" + } + } +} diff --git a/modules/dsql/README.md b/modules/dsql/README.md new file mode 100644 index 0000000..0834266 --- /dev/null +++ b/modules/dsql/README.md @@ -0,0 +1,82 @@ +# DSQL Cluster + +Terraform sub-module which creates DSQL cluster and peering resources. + +## Usage + +See [DSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/dsql) directory for working examples to reference: + +```hcl +module "dsql_cluster_1" { + source = "../../modules/dsql" + + witness_region = "us-west-2" + create_cluster_peering = true + clusters = [module.dsql_cluster_2.arn] + + tags = { Name = "dsql-1" } +} + +module "dsql_cluster_2" { + source = "../../modules/dsql" + + witness_region = "us-west-2" + create_cluster_peering = true + clusters = [module.dsql_cluster_1.arn] + + tags = { Name = "dsql-2" } + + providers = { + aws = aws.region2 + } +} +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.100 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.100 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_dsql_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dsql_cluster) | resource | +| [aws_dsql_cluster_peering.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dsql_cluster_peering) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [clusters](#input\_clusters) | List of DSQL Cluster ARNs to be peered to this cluster | `list(string)` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects all resources) | `bool` | `true` | no | +| [create\_cluster\_peering](#input\_create\_cluster\_peering) | Whether to create cluster peering | `bool` | `false` | no | +| [deletion\_protection\_enabled](#input\_deletion\_protection\_enabled) | Whether deletion protection is enabled in this cluster | `bool` | `null` | no | +| [kms\_encryption\_key](#input\_kms\_encryption\_key) | The ARN of the AWS KMS key that encrypts data in the DSQL Cluster, or `AWS_OWNED_KMS_KEY` | `string` | `null` | no | +| [tags](#input\_tags) | A map of tags to be associated with the AWS DSQL Cluster resource | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Create timeout configuration for the cluster | `any` | `{}` | no | +| [witness\_region](#input\_witness\_region) | Witness region for the multi-region clusters. Setting this makes this cluster a multi-region cluster. Changing it recreates the cluster | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | ARN of the cluster | +| [encryption\_details](#output\_encryption\_details) | Encryption configuration details for the DSQL cluster | +| [identifier](#output\_identifier) | Cluster identifier | +| [multi\_region\_properties](#output\_multi\_region\_properties) | Multi-region properties of the DSQL cluster | +| [vpc\_endpoint\_service\_name](#output\_vpc\_endpoint\_service\_name) | The DSQL cluster's VPC endpoint service name | + diff --git a/modules/dsql/main.tf b/modules/dsql/main.tf new file mode 100644 index 0000000..450574c --- /dev/null +++ b/modules/dsql/main.tf @@ -0,0 +1,27 @@ +resource "aws_dsql_cluster" "this" { + count = var.create ? 1 : 0 + + deletion_protection_enabled = var.deletion_protection_enabled + kms_encryption_key = var.kms_encryption_key + + dynamic "multi_region_properties" { + for_each = var.witness_region != null ? [true] : [] + content { + witness_region = var.witness_region + } + } + + tags = var.tags +} + +resource "aws_dsql_cluster_peering" "this" { + count = var.create && var.create_cluster_peering ? 1 : 0 + + clusters = var.clusters + identifier = aws_dsql_cluster.this[0].identifier + witness_region = var.witness_region + + timeouts { + create = try(var.timeouts.create, null) + } +} diff --git a/modules/dsql/outputs.tf b/modules/dsql/outputs.tf new file mode 100644 index 0000000..d0831f5 --- /dev/null +++ b/modules/dsql/outputs.tf @@ -0,0 +1,24 @@ +output "arn" { + description = "ARN of the cluster" + value = try(aws_dsql_cluster.this[0].arn, null) +} + +output "identifier" { + description = "Cluster identifier" + value = try(aws_dsql_cluster.this[0].identifier, null) +} + +output "encryption_details" { + description = "Encryption configuration details for the DSQL cluster" + value = try(aws_dsql_cluster.this[0].encryption_details, null) +} + +output "multi_region_properties" { + description = "Multi-region properties of the DSQL cluster" + value = try(aws_dsql_cluster.this[0].multi_region_properties, null) +} + +output "vpc_endpoint_service_name" { + description = "The DSQL cluster's VPC endpoint service name" + value = try(aws_dsql_cluster.this[0].vpc_endpoint_service_name, null) +} diff --git a/modules/dsql/variables.tf b/modules/dsql/variables.tf new file mode 100644 index 0000000..ecf2ec3 --- /dev/null +++ b/modules/dsql/variables.tf @@ -0,0 +1,47 @@ +variable "create" { + description = "Whether cluster should be created (affects all resources)" + type = bool + default = true +} + +variable "deletion_protection_enabled" { + description = "Whether deletion protection is enabled in this cluster" + type = bool + default = null +} + +variable "kms_encryption_key" { + description = "The ARN of the AWS KMS key that encrypts data in the DSQL Cluster, or `AWS_OWNED_KMS_KEY`" + type = string + default = null +} + +variable "create_cluster_peering" { + description = "Whether to create cluster peering" + type = bool + default = false +} + +variable "clusters" { + description = "List of DSQL Cluster ARNs to be peered to this cluster" + type = list(string) + default = null +} + +variable "witness_region" { + description = "Witness region for the multi-region clusters. Setting this makes this cluster a multi-region cluster. Changing it recreates the cluster" + type = string + default = null +} + +variable "timeouts" { + description = "Create timeout configuration for the cluster" + type = any + default = {} +} + +variable "tags" { + description = "A map of tags to be associated with the AWS DSQL Cluster resource" + type = map(string) + default = {} +} diff --git a/modules/dsql/versions.tf b/modules/dsql/versions.tf new file mode 100644 index 0000000..7aad8ab --- /dev/null +++ b/modules/dsql/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.100" + } + } +}