diff --git a/README.md b/README.md index 57635a4..699f4d7 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,7 @@ Available targets: |------|------| | [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | | [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | +| [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | | [aws_db_proxy_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | | [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | @@ -322,6 +323,8 @@ Available targets: | [proxy\_endpoint](#output\_proxy\_endpoint) | Proxy endpoint | | [proxy\_iam\_role\_arn](#output\_proxy\_iam\_role\_arn) | The ARN of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | | [proxy\_id](#output\_proxy\_id) | Proxy ID | +| [proxy\_read\_endpoint\_arn](#output\_proxy\_read\_endpoint\_arn) | The read endpoint arn for the proxy | +| [proxy\_read\_endpoint\_name](#output\_proxy\_read\_endpoint\_name) | The read endpoint for the proxy | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, `target type` (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (`/`) | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB instance or Aurora DB cluster | diff --git a/docs/terraform.md b/docs/terraform.md index 889245c..37d4f52 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -25,6 +25,7 @@ |------|------| | [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | | [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | +| [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | | [aws_db_proxy_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | | [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | @@ -87,6 +88,8 @@ | [proxy\_endpoint](#output\_proxy\_endpoint) | Proxy endpoint | | [proxy\_iam\_role\_arn](#output\_proxy\_iam\_role\_arn) | The ARN of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | | [proxy\_id](#output\_proxy\_id) | Proxy ID | +| [proxy\_read\_endpoint\_arn](#output\_proxy\_read\_endpoint\_arn) | The read endpoint arn for the proxy | +| [proxy\_read\_endpoint\_name](#output\_proxy\_read\_endpoint\_name) | The read endpoint for the proxy | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, `target type` (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (`/`) | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB instance or Aurora DB cluster | diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 2775073..86aca2e 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -114,3 +114,13 @@ output "proxy_iam_role_arn" { value = module.rds_proxy.proxy_iam_role_arn description = "The ARN of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" } + +output "proxy_read_endpoint_name" { + value = module.rds_proxy.proxy_read_endpoint_name + description = "The read endpoint for the proxy" +} + +output "proxy_read_endpoint_arn" { + value = module.rds_proxy.proxy_read_endpoint_arn + description = "The read endpoint arn for the proxy" +} \ No newline at end of file diff --git a/main.tf b/main.tf index 214239c..b1dde33 100644 --- a/main.tf +++ b/main.tf @@ -63,3 +63,12 @@ resource "aws_db_proxy_target" "this" { db_proxy_name = join("", aws_db_proxy.this[*].name) target_group_name = join("", aws_db_proxy_default_target_group.this[*].name) } + +resource "aws_db_proxy_endpoint" "this" { + count = local.enabled ? 1 : 0 + + db_proxy_name = join("", aws_db_proxy.this[*].name) + db_proxy_endpoint_name = join("-", [join("", aws_db_proxy.this[*].name), "read-only"]) + vpc_subnet_ids = var.vpc_subnet_ids + target_role = "READ_ONLY" +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf index 2922f76..844443e 100644 --- a/outputs.tf +++ b/outputs.tf @@ -62,3 +62,13 @@ output "proxy_iam_role_arn" { value = local.iam_role_arn description = "The ARN of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" } + +output "proxy_read_endpoint_name" { + value = join("", aws_db_proxy_endpoint.this[*].endpoint) + description = "The read endpoint for the proxy" +} + +output "proxy_read_endpoint_arn" { + value = join("", aws_db_proxy_endpoint.this[*].arn) + description = "The read endpoint arn for the proxy" +} \ No newline at end of file diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 156e1b1..59985ab 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -1,97 +1,103 @@ package test import ( - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/terraform" - test_structure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/assert" - "os" - "strings" - "testing" + "os" + "strings" + "testing" + + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/terraform" + test_structure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/assert" ) func cleanup(t *testing.T, terraformOptions *terraform.Options, tempTestFolder string) { - terraform.Destroy(t, terraformOptions) - os.RemoveAll(tempTestFolder) + terraform.Destroy(t, terraformOptions) + os.RemoveAll(tempTestFolder) } // Test the Terraform module in examples/complete using Terratest. func TestExamplesComplete(t *testing.T) { - t.Parallel() - randID := strings.ToLower(random.UniqueId()) - attributes := []string{randID} - - rootFolder := "../../" - terraformFolderRelativeToRoot := "examples/complete" - varFiles := []string{"fixtures.us-east-2.tfvars"} - - tempTestFolder := test_structure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) - - terraformOptions := &terraform.Options{ - // The path to where our Terraform code is located - TerraformDir: tempTestFolder, - Upgrade: true, - // Variables to pass to our Terraform code using -var-file options - VarFiles: varFiles, - Vars: map[string]interface{}{ - "attributes": attributes, - }, - } - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer cleanup(t, terraformOptions, tempTestFolder) - - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors - terraform.InitAndApply(t, terraformOptions) - - // Run `terraform output` to get the value of an output variable - vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr") - // Verify we're getting back the outputs we expect - assert.Equal(t, "172.16.0.0/16", vpcCidr) - - // Run `terraform output` to get the value of an output variable - privateSubnetCidrs := terraform.OutputList(t, terraformOptions, "private_subnet_cidrs") - // Verify we're getting back the outputs we expect - assert.Equal(t, []string{"172.16.0.0/19", "172.16.32.0/19"}, privateSubnetCidrs) - - // Run `terraform output` to get the value of an output variable - publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs") - // Verify we're getting back the outputs we expect - assert.Equal(t, []string{"172.16.96.0/19", "172.16.128.0/19"}, publicSubnetCidrs) - - // Run `terraform output` to get the value of an output variable - instanceId := terraform.Output(t, terraformOptions, "instance_id") - // Verify we're getting back the outputs we expect - assert.Equal(t, "eg-test-rds-proxy-"+randID, instanceId) - - // Run `terraform output` to get the value of an output variable - optionGroupId := terraform.Output(t, terraformOptions, "option_group_id") - // We expect AWS to tack a uniquifier on to the end - assert.Contains(t, optionGroupId, "eg-test-rds-proxy-"+randID) - - // Run `terraform output` to get the value of an output variable - parameterGroupId := terraform.Output(t, terraformOptions, "parameter_group_id") - // We expect AWS to tack a uniquifier on to the end - assert.Contains(t, parameterGroupId, "eg-test-rds-proxy-"+randID) - - // Run `terraform output` to get the value of an output variable - subnetGroupId := terraform.Output(t, terraformOptions, "subnet_group_id") - // Verify we're getting back the outputs we expect - assert.Equal(t, "eg-test-rds-proxy-"+randID, subnetGroupId) - - // Run `terraform output` to get the value of an output variable - proxyId := terraform.Output(t, terraformOptions, "proxy_id") - // Verify we're getting back the outputs we expect - assert.Equal(t, "eg-test-rds-proxy-"+randID, proxyId) - - // Run `terraform output` to get the value of an output variable - proxyEndpoint := terraform.Output(t, terraformOptions, "proxy_endpoint") - // Verify we're getting back the outputs we expect - assert.Contains(t, proxyEndpoint, "eg-test-rds-proxy-"+randID) - - // Run `terraform output` to get the value of an output variable - proxyTargetEndpoint := terraform.Output(t, terraformOptions, "proxy_target_endpoint") - instanceAddress := terraform.Output(t, terraformOptions, "instance_address") - // Verify we're getting back the outputs we expect - assert.Equal(t, proxyTargetEndpoint, instanceAddress) + t.Parallel() + randID := strings.ToLower(random.UniqueId()) + attributes := []string{randID} + + rootFolder := "../../" + terraformFolderRelativeToRoot := "examples/complete" + varFiles := []string{"fixtures.us-east-2.tfvars"} + + tempTestFolder := test_structure.CopyTerraformFolderToTemp(t, rootFolder, terraformFolderRelativeToRoot) + + terraformOptions := &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: tempTestFolder, + Upgrade: true, + // Variables to pass to our Terraform code using -var-file options + VarFiles: varFiles, + Vars: map[string]interface{}{ + "attributes": attributes, + }, + } + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer cleanup(t, terraformOptions, tempTestFolder) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) + + // Run `terraform output` to get the value of an output variable + vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr") + // Verify we're getting back the outputs we expect + assert.Equal(t, "172.16.0.0/16", vpcCidr) + + // Run `terraform output` to get the value of an output variable + privateSubnetCidrs := terraform.OutputList(t, terraformOptions, "private_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.0.0/19", "172.16.32.0/19"}, privateSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.96.0/19", "172.16.128.0/19"}, publicSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + instanceId := terraform.Output(t, terraformOptions, "instance_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-rds-proxy-"+randID, instanceId) + + // Run `terraform output` to get the value of an output variable + optionGroupId := terraform.Output(t, terraformOptions, "option_group_id") + // We expect AWS to tack a uniquifier on to the end + assert.Contains(t, optionGroupId, "eg-test-rds-proxy-"+randID) + + // Run `terraform output` to get the value of an output variable + parameterGroupId := terraform.Output(t, terraformOptions, "parameter_group_id") + // We expect AWS to tack a uniquifier on to the end + assert.Contains(t, parameterGroupId, "eg-test-rds-proxy-"+randID) + + // Run `terraform output` to get the value of an output variable + subnetGroupId := terraform.Output(t, terraformOptions, "subnet_group_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-rds-proxy-"+randID, subnetGroupId) + + // Run `terraform output` to get the value of an output variable + proxyId := terraform.Output(t, terraformOptions, "proxy_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-rds-proxy-"+randID, proxyId) + + // Run `terraform output` to get the value of an output variable + proxyEndpoint := terraform.Output(t, terraformOptions, "proxy_endpoint") + // Verify we're getting back the outputs we expect + assert.Contains(t, proxyEndpoint, "eg-test-rds-proxy-"+randID) + + // Run `terraform output` to get the value of an output variable + proxyTargetEndpoint := terraform.Output(t, terraformOptions, "proxy_target_endpoint") + instanceAddress := terraform.Output(t, terraformOptions, "instance_address") + // Verify we're getting back the outputs we expect + assert.Equal(t, proxyTargetEndpoint, instanceAddress) + + // Run `terraform output` to get the value of an output variable + proxyTargetReadEndpoint := terraform.Output(t, terraformOptions, "proxy_read_endpoint_name") + assert.NotEmpty(t, proxyTargetReadEndpoint) + assert.Contains(t, proxyTargetReadEndpoint, "eg-test-rds-proxy-"+randID+"-read-only") }