Skip to content

Commit eb3d91f

Browse files
feat: support tls_ca and tls_certificate_key for mongodb connections
1 parent 2bcd6fa commit eb3d91f

File tree

3 files changed

+114
-8
lines changed

3 files changed

+114
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ FEATURES:
5353

5454
* Add support for `group_by` and `secondary_rate` on resource `vault_quota_rate_limit`. Requires Vault Enterprise 1.20.0+ ([#2476](https://github.com/hashicorp/terraform-provider-vault/pull/2476))
5555
* Add support for Transit CMAC endpoint ([#2488](https://github.com/hashicorp/terraform-provider-vault/pull/2488))
56+
* Add support `tls_ca` and `tls_certificate_key` for mongodb connections [#2482](https://github.com/hashicorp/terraform-provider-vault/pull/2482)
5657

5758
* Add new resource `vault_scep_auth_backend_role` to manage roles in a SCEP auth backend. [#2479](https://github.com/hashicorp/terraform-provider-vault/pull/2479).
5859
* Add new datasource and resource `vault_pki_secret_backend_config_scep` for PKI SCEP configuration. [#2487](https://github.com/hashicorp/terraform-provider-vault/pull/2487).

vault/resource_database_secret_backend_connection.go

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,10 @@ func getDatabaseSchema(typ schema.ValueType) schemaMap {
486486
ConflictsWith: util.CalculateConflictsWith(dbEngineInfluxDB.Name(), dbEngineTypes),
487487
},
488488
dbEngineMongoDB.name: {
489-
Type: typ,
490-
Optional: true,
491-
Description: "Connection parameters for the mongodb-database-plugin plugin.",
492-
Elem: connectionStringResource(&connectionStringConfig{
493-
includeUserPass: true,
494-
}),
489+
Type: typ,
490+
Optional: true,
491+
Description: "Connection parameters for the mongodb-database-plugin plugin.",
492+
Elem: mongodbConnectionStringResource(),
495493
MaxItems: 1,
496494
ConflictsWith: util.CalculateConflictsWith(dbEngineMongoDB.Name(), dbEngineTypes),
497495
},
@@ -942,6 +940,23 @@ func snowflakeConnectionStringResource() *schema.Resource {
942940

943941
r.Schema[consts.FieldPassword].Deprecated = "Snowflake is ending support for single-factor password authentication " +
944942
"by November 2025. Refer to the documentation for more information on migrating to key-pair authentication."
943+
return r
944+
}
945+
946+
func mongodbConnectionStringResource() *schema.Resource {
947+
r := connectionStringResource(&connectionStringConfig{
948+
includeUserPass: true,
949+
})
950+
r.Schema["tls_certificate_key"] = &schema.Schema{
951+
Type: schema.TypeString,
952+
Optional: true,
953+
Description: "x509 certificate for connecting to the database. This must be a PEM encoded version of the private key and the certificate combined.",
954+
}
955+
r.Schema["tls_ca"] = &schema.Schema{
956+
Type: schema.TypeString,
957+
Optional: true,
958+
Description: "x509 CA file for validating the certificate presented by the MongoDB server. Must be PEM encoded.",
959+
}
945960

946961
return r
947962
}
@@ -1017,7 +1032,7 @@ func getDatabaseAPIDataForEngine(engine *dbEngine, idx int, d *schema.ResourceDa
10171032
case dbEngineHana:
10181033
setDatabaseConnectionDataWithDisableEscaping(d, prefix, data)
10191034
case dbEngineMongoDB:
1020-
setDatabaseConnectionDataWithUserPass(d, prefix, data)
1035+
setMongoDBDatabaseConnectionData(d, prefix, data)
10211036
case dbEngineMongoDBAtlas:
10221037
setMongoDBAtlasDatabaseConnectionData(d, prefix, data)
10231038
case dbEngineMSSQL:
@@ -1281,6 +1296,31 @@ func getMySQLConnectionDetailsFromResponse(d *schema.ResourceData, prefix string
12811296
return result
12821297
}
12831298

1299+
func getMongoDBConnectionDetailsFromResponse(d *schema.ResourceData, prefix string, resp *api.Secret) map[string]interface{} {
1300+
result := getConnectionDetailsFromResponseWithUserPass(d, prefix, resp)
1301+
details := resp.Data["connection_details"]
1302+
data, ok := details.(map[string]interface{})
1303+
if !ok {
1304+
return nil
1305+
}
1306+
if v, ok := d.GetOk(prefix + "tls_certificate_key"); ok {
1307+
result["tls_certificate_key"] = v.(string)
1308+
} else {
1309+
if v, ok := data["tls_certificate_key"]; ok {
1310+
result["tls_certificate_key"] = v.(string)
1311+
}
1312+
}
1313+
if v, ok := d.GetOk(prefix + "tls_ca"); ok {
1314+
result["tls_ca"] = v.(string)
1315+
} else {
1316+
if v, ok := data["tls_ca"]; ok {
1317+
result["tls_ca"] = v.(string)
1318+
}
1319+
}
1320+
1321+
return result
1322+
}
1323+
12841324
func getRedisConnectionDetailsFromResponse(d *schema.ResourceData, prefix string, resp *api.Secret) map[string]interface{} {
12851325
details := resp.Data["connection_details"]
12861326
data, ok := details.(map[string]interface{})
@@ -1624,6 +1664,16 @@ func setMySQLDatabaseConnectionData(d *schema.ResourceData, prefix string, data
16241664
}
16251665
}
16261666

1667+
func setMongoDBDatabaseConnectionData(d *schema.ResourceData, prefix string, data map[string]interface{}) {
1668+
setDatabaseConnectionDataWithUserPass(d, prefix, data)
1669+
if v, ok := d.GetOk(prefix + "tls_certificate_key"); ok {
1670+
data["tls_certificate_key"] = v.(string)
1671+
}
1672+
if v, ok := d.GetOk(prefix + "tls_ca"); ok {
1673+
data["tls_ca"] = v.(string)
1674+
}
1675+
}
1676+
16271677
func setPostgresDatabaseConnectionData(d *schema.ResourceData, prefix string, data map[string]interface{}, meta interface{}) {
16281678
setDatabaseConnectionDataWithDisableEscaping(d, prefix, data)
16291679
setCloudDatabaseConnectionData(d, prefix, data, meta)
@@ -2138,7 +2188,7 @@ func getDBConnectionConfig(d *schema.ResourceData, engine *dbEngine, idx int,
21382188
case dbEngineHana:
21392189
result = getConnectionDetailsFromResponseWithDisableEscaping(d, prefix, resp)
21402190
case dbEngineMongoDB:
2141-
result = getConnectionDetailsFromResponseWithUserPass(d, prefix, resp)
2191+
result = getMongoDBConnectionDetailsFromResponse(d, prefix, resp)
21422192
case dbEngineMongoDBAtlas:
21432193
result = getConnectionDetailsMongoDBAtlas(d, prefix, resp)
21442194
case dbEngineMSSQL:

vault/resource_database_secret_backend_connection_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,38 @@ func TestAccDatabaseSecretBackendConnection_mongodb(t *testing.T) {
379379
})
380380
}
381381

382+
func TestAccDatabaseSecretBackendConnection_mongodb_tls(t *testing.T) {
383+
MaybeSkipDBTests(t, dbEngineMongoDB)
384+
385+
// TODO: make these fatal once we auto provision the required test infrastructure.
386+
values := testutil.SkipTestEnvUnset(t, "MONGODB_CA", "MONGODB_URL")
387+
tlsCa, connURL := values[0], values[1]
388+
389+
backend := acctest.RandomWithPrefix("tf-test-db")
390+
pluginName := dbEngineMongoDB.DefaultPluginName()
391+
name := acctest.RandomWithPrefix("db")
392+
resource.Test(t, resource.TestCase{
393+
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
394+
PreCheck: func() { testutil.TestAccPreCheck(t) },
395+
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
396+
Steps: []resource.TestStep{
397+
{
398+
Config: testAccDatabaseSecretBackendConnectionConfig_mongodb_tls(name, backend, connURL, tlsCa),
399+
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, pluginName,
400+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.#", "2"),
401+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.0", "dev"),
402+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.1", "prod"),
403+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "root_rotation_statements.#", "1"),
404+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "root_rotation_statements.0", "FOOBAR"),
405+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "verify_connection", "true"),
406+
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "mongodb.0.connection_url", connURL),
407+
resource.TestCheckResourceAttr("vault_database_secret_backend_connection.test", "mongodb.0.tls_ca", tlsCa+"\n"),
408+
),
409+
},
410+
},
411+
})
412+
}
413+
382414
func TestAccDatabaseSecretBackendConnection_mssql(t *testing.T) {
383415
MaybeSkipDBTests(t, dbEngineMSSQL)
384416

@@ -1701,6 +1733,29 @@ resource "vault_database_secret_backend_connection" "test" {
17011733
`, path, name, connURL)
17021734
}
17031735

1736+
func testAccDatabaseSecretBackendConnectionConfig_mongodb_tls(name, path, connURL, tlsCa string) string {
1737+
return fmt.Sprintf(`
1738+
resource "vault_mount" "db" {
1739+
path = "%s"
1740+
type = "database"
1741+
}
1742+
1743+
resource "vault_database_secret_backend_connection" "test" {
1744+
backend = vault_mount.db.path
1745+
name = "%s"
1746+
allowed_roles = ["dev", "prod"]
1747+
root_rotation_statements = ["FOOBAR"]
1748+
1749+
mongodb {
1750+
connection_url = "%s"
1751+
tls_ca = <<EOT
1752+
%s
1753+
EOT
1754+
}
1755+
}
1756+
`, path, name, connURL, tlsCa)
1757+
}
1758+
17041759
func testAccDatabaseSecretBackendConnectionConfig_mssql(name, path, pluginName string, parsedURL *url.URL, containedDB bool) string {
17051760
var config string
17061761
password, _ := parsedURL.User.Password()

0 commit comments

Comments
 (0)