Skip to content

Commit 5f79c13

Browse files
authored
feat: Adds support for role_id in google_cloud_kms_config on mongodbatlas_encryption_at_rest resource and data source (#3636)
* implement role_id * docs and changelog * fix unit test * refactor checks * fix inconsistent result after apply null/empty string * docs notice * pr suggestion missing period
1 parent ae99fdc commit 5f79c13

File tree

11 files changed

+98
-0
lines changed

11 files changed

+98
-0
lines changed

.changelog/3636.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:enhancement
2+
resource/mongodbatlas_encryption_at_rest: Supports role_id in google_cloud_kms_config
3+
```
4+
5+
```release-note:enhancement
6+
data-source/mongodbatlas_encryption_at_rest: Supports role_id in google_cloud_kms_config
7+
```

docs/data-sources/encryption_at_rest.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ output "is_azure_encryption_at_rest_valid" {
106106
-> **NOTE:** It is possible to configure Atlas Encryption at Rest to communicate with Customer Managed Keys (Azure Key Vault or AWS KMS) over private network interfaces (Azure Private Link or AWS PrivateLink). This requires enabling the `azure_key_vault_config.require_private_networking` or the `aws_kms_config.require_private_networking` attribute, together with the configuration of the `mongodbatlas_encryption_at_rest_private_endpoint` resource. Please review the `mongodbatlas_encryption_at_rest_private_endpoint` resource for details.
107107

108108
### Configuring encryption at rest using customer key management in GCP
109+
For authentication, you must provide either serviceAccountKey (static credentials) or roleId (service-account–based authentication). Once roleId is configured, serviceAccountKey is no longer supported.
110+
109111
```terraform
110112
resource "mongodbatlas_encryption_at_rest" "test" {
111113
project_id = var.atlas_project_id
@@ -181,6 +183,7 @@ Read-Only:
181183

182184
- `enabled` (Boolean) Flag that indicates whether someone enabled encryption at rest for the specified project. To disable encryption at rest using customer key management and remove the configuration details, pass only this parameter with a value of `false`.
183185
- `key_version_resource_id` (String, Sensitive) Resource path that displays the key version resource ID for your Google Cloud KMS.
186+
- `role_id` (String) Unique 24-hexadecimal digit string that identifies the Google Cloud Provider Access Role that MongoDB Cloud uses to access the Google Cloud KMS.
184187
- `service_account_key` (String, Sensitive) JavaScript Object Notation (JSON) object that contains the Google Cloud Key Management Service (KMS). Format the JSON as a string and not as an object.
185188
- `valid` (Boolean) Flag that indicates whether the Google Cloud Key Management Service (KMS) encryption key can encrypt and decrypt data.
186189

docs/resources/encryption_at_rest.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ Please review the [`mongodbatlas_encryption_at_rest_private_endpoint` resource d
134134

135135

136136
### Configuring encryption at rest using customer key management in GCP
137+
For authentication, you must provide either serviceAccountKey (static credentials) or roleId (service-account–based authentication). Once roleId is configured, serviceAccountKey is no longer supported.
138+
137139
```terraform
138140
resource "mongodbatlas_encryption_at_rest" "test" {
139141
project_id = var.atlas_project_id
@@ -210,6 +212,7 @@ Optional:
210212

211213
- `enabled` (Boolean) Flag that indicates whether someone enabled encryption at rest for the specified project. To disable encryption at rest using customer key management and remove the configuration details, pass only this parameter with a value of `false`.
212214
- `key_version_resource_id` (String, Sensitive) Resource path that displays the key version resource ID for your Google Cloud KMS.
215+
- `role_id` (String) Unique 24-hexadecimal digit string that identifies the Google Cloud Provider Access Role that MongoDB Cloud uses to access the Google Cloud KMS.
213216
- `service_account_key` (String, Sensitive) JavaScript Object Notation (JSON) object that contains the Google Cloud Key Management Service (KMS). Format the JSON as a string and not as an object.
214217

215218
Read-Only:

internal/service/encryptionatrest/data_source_schema.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ func DataSourceSchema(ctx context.Context) schema.Schema {
128128
Computed: true,
129129
MarkdownDescription: "Flag that indicates whether the Google Cloud Key Management Service (KMS) encryption key can encrypt and decrypt data.",
130130
},
131+
"role_id": schema.StringAttribute{
132+
Computed: true,
133+
MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the Google Cloud Provider Access Role that MongoDB Cloud uses to access the Google Cloud KMS.",
134+
},
131135
},
132136
Computed: true,
133137
MarkdownDescription: "Details that define the configuration of Encryption at Rest using Google Cloud Key Management Service (KMS).",

internal/service/encryptionatrest/model.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func NewTFGcpKmsConfigItem(gcpKms *admin.GoogleCloudKMS) *TFGcpKmsConfigModel {
102102
KeyVersionResourceID: types.StringValue(gcpKms.GetKeyVersionResourceID()),
103103
ServiceAccountKey: conversion.StringNullIfEmpty(gcpKms.GetServiceAccountKey()),
104104
Valid: types.BoolPointerValue(gcpKms.Valid),
105+
RoleID: conversion.StringNullIfEmpty(gcpKms.GetRoleId()),
105106
}
106107
}
107108

@@ -134,6 +135,7 @@ func NewAtlasGcpKms(tfGcpKmsConfigSlice []TFGcpKmsConfigModel) *admin.GoogleClou
134135
Enabled: v.Enabled.ValueBoolPointer(),
135136
ServiceAccountKey: v.ServiceAccountKey.ValueStringPointer(),
136137
KeyVersionResourceID: v.KeyVersionResourceID.ValueStringPointer(),
138+
RoleId: v.RoleID.ValueStringPointer(),
137139
}
138140
}
139141

internal/service/encryptionatrest/model_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ var (
7676
Enabled: &enabled,
7777
KeyVersionResourceID: &keyVersionResourceID,
7878
ServiceAccountKey: &serviceAccountKey,
79+
RoleId: &roleID,
7980
}
8081
TfGcpKmsConfigModel = encryptionatrest.TFGcpKmsConfigModel{
8182
Enabled: types.BoolValue(enabled),
8283
KeyVersionResourceID: types.StringValue(keyVersionResourceID),
8384
ServiceAccountKey: types.StringValue(serviceAccountKey),
85+
RoleID: types.StringValue(roleID),
8486
}
8587
EncryptionAtRest = &admin.EncryptionAtRest{
8688
AwsKms: AWSKMSConfiguration,

internal/service/encryptionatrest/resource.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ type TFAzureKeyVaultConfigModel struct {
8787
type TFGcpKmsConfigModel struct {
8888
ServiceAccountKey types.String `tfsdk:"service_account_key"`
8989
KeyVersionResourceID types.String `tfsdk:"key_version_resource_id"`
90+
RoleID types.String `tfsdk:"role_id"`
9091
Enabled types.Bool `tfsdk:"enabled"`
9192
Valid types.Bool `tfsdk:"valid"`
9293
}
@@ -259,6 +260,10 @@ func (r *encryptionAtRestRS) Schema(ctx context.Context, req resource.SchemaRequ
259260
Computed: true,
260261
MarkdownDescription: "Flag that indicates whether the Google Cloud Key Management Service (KMS) encryption key can encrypt and decrypt data.",
261262
},
263+
"role_id": schema.StringAttribute{
264+
Optional: true,
265+
MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the Google Cloud Provider Access Role that MongoDB Cloud uses to access the Google Cloud KMS.",
266+
},
262267
},
263268
},
264269
},

internal/service/encryptionatrest/resource_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,32 @@ func TestAccEncryptionAtRest_basicGCP(t *testing.T) {
215215
})
216216
}
217217

218+
func TestAccEncryptionAtRest_basicGCPWithRole(t *testing.T) {
219+
acc.SkipTestForCI(t) // needs GCP configuration
220+
221+
var (
222+
projectID = os.Getenv("MONGODB_ATLAS_PROJECT_ID")
223+
224+
googleCloudKms = admin.GoogleCloudKMS{
225+
Enabled: conversion.Pointer(true),
226+
RoleId: conversion.StringPtr(os.Getenv("GCP_ROLE_ID")),
227+
KeyVersionResourceID: conversion.StringPtr(os.Getenv("GCP_KEY_VERSION_RESOURCE_ID")),
228+
}
229+
)
230+
231+
resource.Test(t, resource.TestCase{
232+
PreCheck: func() { acc.PreCheck(t); acc.PreCheckGCPEnvWithRole(t) },
233+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
234+
CheckDestroy: acc.EARDestroy,
235+
Steps: []resource.TestStep{
236+
{
237+
Config: configGoogleCloudKmsWithRole(projectID, &googleCloudKms, true),
238+
Check: checkEARResourceGCPWithRole(projectID),
239+
},
240+
},
241+
})
242+
}
243+
218244
func TestAccEncryptionAtRestWithRole_basicAWS(t *testing.T) {
219245
acc.SkipTestForCI(t) // needs AWS configuration. This test case is similar to TestAccEncryptionAtRest_basicAWS except that it creates it's own AWS resources such as IAM roles, cloud provider access, etc so we don't need to run this in CI but may be used for local testing.
220246

@@ -516,6 +542,25 @@ func configGoogleCloudKms(projectID string, google *admin.GoogleCloudKMS, useDat
516542
return config
517543
}
518544

545+
func configGoogleCloudKmsWithRole(projectID string, google *admin.GoogleCloudKMS, useDatasource bool) string {
546+
config := fmt.Sprintf(`
547+
resource "mongodbatlas_encryption_at_rest" "test" {
548+
project_id = "%s"
549+
550+
google_cloud_kms_config {
551+
enabled = %t
552+
role_id = "%s"
553+
key_version_resource_id = "%s"
554+
}
555+
}
556+
`, projectID, *google.Enabled, google.GetRoleId(), google.GetKeyVersionResourceID())
557+
558+
if useDatasource {
559+
return fmt.Sprintf(`%s %s`, config, acc.EARDatasourceConfig())
560+
}
561+
return config
562+
}
563+
519564
func testAccMongoDBAtlasEncryptionAtRestConfigAwsKmsWithRole(projectID, awsIAMRoleName, awsIAMRolePolicyName, awsKeyName string, awsEar *admin.AWSKMSConfiguration) string {
520565
test := fmt.Sprintf(`
521566
locals {
@@ -620,3 +665,19 @@ func checkEARResourceAWS(projectID string, enabledForSearchNodes bool, awsKmsAtt
620665
acc.EARCheckResourceAttr(datasourceName, "aws_kms_config.", awsKmsAttrMap),
621666
)
622667
}
668+
669+
func checkEARResourceGCPWithRole(projectID string) resource.TestCheckFunc {
670+
return resource.ComposeAggregateTestCheckFunc(
671+
acc.CheckEARExists(resourceName),
672+
resource.TestCheckResourceAttr(resourceName, "project_id", projectID),
673+
resource.TestCheckResourceAttr(resourceName, "google_cloud_kms_config.0.role_id", os.Getenv("GCP_ROLE_ID")),
674+
resource.TestCheckResourceAttr(resourceName, "google_cloud_kms_config.0.enabled", "true"),
675+
resource.TestCheckResourceAttr(resourceName, "google_cloud_kms_config.0.valid", "true"),
676+
resource.TestCheckResourceAttrSet(resourceName, "google_cloud_kms_config.0.key_version_resource_id"),
677+
678+
resource.TestCheckResourceAttr(datasourceName, "project_id", projectID),
679+
resource.TestCheckResourceAttr(datasourceName, "google_cloud_kms_config.enabled", "true"),
680+
resource.TestCheckResourceAttr(datasourceName, "google_cloud_kms_config.valid", "true"),
681+
resource.TestCheckResourceAttrSet(datasourceName, "google_cloud_kms_config.key_version_resource_id"),
682+
)
683+
}

internal/testutil/acc/pre_check.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ func PreCheckGPCEnv(tb testing.TB) {
155155
}
156156
}
157157

158+
func PreCheckGCPEnvWithRole(tb testing.TB) {
159+
tb.Helper()
160+
if os.Getenv("GCP_ROLE_ID") == "" || os.Getenv("GCP_KEY_VERSION_RESOURCE_ID") == "" {
161+
tb.Fatal("`GCP_ROLE_ID` and `GCP_KEY_VERSION_RESOURCE_ID` must be set for acceptance testing")
162+
}
163+
}
164+
158165
func PreCheckPeeringEnvAWS(tb testing.TB) {
159166
tb.Helper()
160167
if os.Getenv("AWS_ACCOUNT_ID") == "" ||

templates/data-sources/encryption_at_rest.md.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
-> **NOTE:** It is possible to configure Atlas Encryption at Rest to communicate with Customer Managed Keys (Azure Key Vault or AWS KMS) over private network interfaces (Azure Private Link or AWS PrivateLink). This requires enabling the `azure_key_vault_config.require_private_networking` or the `aws_kms_config.require_private_networking` attribute, together with the configuration of the `mongodbatlas_encryption_at_rest_private_endpoint` resource. Please review the `mongodbatlas_encryption_at_rest_private_endpoint` resource for details.
2626

2727
### Configuring encryption at rest using customer key management in GCP
28+
For authentication, you must provide either serviceAccountKey (static credentials) or roleId (service-account–based authentication). Once roleId is configured, serviceAccountKey is no longer supported.
29+
2830
```terraform
2931
resource "mongodbatlas_encryption_at_rest" "test" {
3032
project_id = var.atlas_project_id

0 commit comments

Comments
 (0)