diff --git a/README.md b/README.md
index 36de53f4f..b0969c998 100644
--- a/README.md
+++ b/README.md
@@ -222,12 +222,12 @@ Terraform acceptance tests are run using the command `make test-acceptance-tf`.
Additionally:
-| Env var | Value | Example value | needed for Acc tests of the following services |
-|---------------------------------------------|---------------------------------------------------------------------------------------------------------|----------------------------------------|------------------------------------------------|
-| `TF_ACC_ORGANIZATION_ID` | ID of the STACKIT test organization | `5353ccfa-a984-4b96-a71d-b863dd2b7087` | `authorization`, `iaas` |
-| `TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL` | Email of the STACKIT service account | `abc-serviceaccount@sa.stackit.cloud` | `authorization`, `resourcemanager` | |
-| `TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID` | Container ID of the project parent container (folder within an organization or the organization itself) | `organization-d2b7087` | `resourcemanager` |
-| `TF_ACC_TEST_PROJECT_PARENT_UUID` | UUID ID of the project parent container (folder within an organization or the organization itself) | `5353ccfa-a984-4b96-a71d-b863dd2b7087` | `resourcemanager` |
+| Env var | Value | Example value | needed for Acc tests of the following services |
+|---------------------------------------------|---------------------------------------------------------------------------------------------------------|----------------------------------------|--------------------------------------------------------------|
+| `TF_ACC_ORGANIZATION_ID` | ID of the STACKIT test organization | `5353ccfa-a984-4b96-a71d-b863dd2b7087` | `authorization`, `iaas` |
+| `TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_EMAIL` | Email of the STACKIT service account | `abc-serviceaccount@sa.stackit.cloud` | `authorization`, `iaas`, `resourcemanager`, `secretsmanager` |
+| `TF_ACC_TEST_PROJECT_PARENT_CONTAINER_ID` | Container ID of the project parent container (folder within an organization or the organization itself) | `organization-d2b7087` | `resourcemanager` |
+| `TF_ACC_TEST_PROJECT_PARENT_UUID` | UUID ID of the project parent container (folder within an organization or the organization itself) | `5353ccfa-a984-4b96-a71d-b863dd2b7087` | `resourcemanager` |
### Run Acceptance Tests of a single service
diff --git a/docs/data-sources/secretsmanager_instance.md b/docs/data-sources/secretsmanager_instance.md
index 7f8e903e7..1dfe066b9 100644
--- a/docs/data-sources/secretsmanager_instance.md
+++ b/docs/data-sources/secretsmanager_instance.md
@@ -31,4 +31,15 @@ data "stackit_secretsmanager_instance" "example" {
- `acls` (Set of String) The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`instance_id`".
+- `kms_key` (Attributes) The STACKIT-KMS key for secret encryption and decryption. (see [below for nested schema](#nestedatt--kms_key))
- `name` (String) Instance name.
+
+
+### Nested Schema for `kms_key`
+
+Read-Only:
+
+- `key_id` (String) UUID of the key within the STACKIT-KMS to use for the encryption.
+- `key_ring_id` (String) UUID of the keyring where the key is located within the STACKTI-KMS.
+- `key_version` (Number) Version of the key within the STACKIT-KMS to use for the encryption.
+- `service_account_email` (String) Service-Account linked to the Key within the STACKIT-KMS.
diff --git a/docs/resources/secretsmanager_instance.md b/docs/resources/secretsmanager_instance.md
index 8848b37de..0c5b67db0 100644
--- a/docs/resources/secretsmanager_instance.md
+++ b/docs/resources/secretsmanager_instance.md
@@ -37,8 +37,19 @@ import {
### Optional
- `acls` (Set of String) The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation
+- `kms_key` (Attributes) The STACKIT-KMS key for secret encryption and decryption. (see [below for nested schema](#nestedatt--kms_key))
### Read-Only
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`instance_id`".
- `instance_id` (String) ID of the Secrets Manager instance.
+
+
+### Nested Schema for `kms_key`
+
+Required:
+
+- `key_id` (String) UUID of the key within the STACKIT-KMS to use for the encryption.
+- `key_ring_id` (String) UUID of the keyring where the key is located within the STACKTI-KMS.
+- `key_version` (Number) Version of the key within the STACKIT-KMS to use for the encryption.
+- `service_account_email` (String) Service-Account linked to the Key within the STACKIT-KMS.
diff --git a/stackit/internal/services/secretsmanager/instance/datasource.go b/stackit/internal/services/secretsmanager/instance/datasource.go
index d17f40016..931c2c1fc 100644
--- a/stackit/internal/services/secretsmanager/instance/datasource.go
+++ b/stackit/internal/services/secretsmanager/instance/datasource.go
@@ -58,12 +58,17 @@ func (r *instanceDataSource) Configure(ctx context.Context, req datasource.Confi
// Schema defines the schema for the data source.
func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
descriptions := map[string]string{
- "main": "Secrets Manager instance data source schema. Must have a `region` specified in the provider configuration.",
- "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`instance_id`\".",
- "instance_id": "ID of the Secrets Manager instance.",
- "project_id": "STACKIT project ID to which the instance is associated.",
- "name": "Instance name.",
- "acls": "The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation",
+ "main": "Secrets Manager instance data source schema. Must have a `region` specified in the provider configuration.",
+ "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`instance_id`\".",
+ "instance_id": "ID of the Secrets Manager instance.",
+ "project_id": "STACKIT project ID to which the instance is associated.",
+ "name": "Instance name.",
+ "acls": "The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation",
+ "kms_key": "The STACKIT-KMS key for secret encryption and decryption.",
+ "kms_key.key_id": "UUID of the key within the STACKIT-KMS to use for the encryption.",
+ "kms_key.key_ring_id": "UUID of the keyring where the key is located within the STACKTI-KMS.",
+ "kms_key.key_version": "Version of the key within the STACKIT-KMS to use for the encryption.",
+ "kms_key.service_account_email": "Service-Account linked to the Key within the STACKIT-KMS.",
}
resp.Schema = schema.Schema{
@@ -98,6 +103,28 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
ElementType: types.StringType,
Computed: true,
},
+ "kms_key": schema.SingleNestedAttribute{
+ Description: descriptions["kms_key"],
+ Computed: true,
+ Attributes: map[string]schema.Attribute{
+ "key_id": schema.StringAttribute{
+ Description: descriptions["kms_key.key_id"],
+ Computed: true,
+ },
+ "key_ring_id": schema.StringAttribute{
+ Description: descriptions["kms_key.key_ring_id"],
+ Computed: true,
+ },
+ "key_version": schema.Int64Attribute{
+ Description: descriptions["kms_key.key_version"],
+ Computed: true,
+ },
+ "service_account_email": schema.StringAttribute{
+ Description: descriptions["kms_key.service_account_email"],
+ Computed: true,
+ },
+ },
+ },
},
}
}
diff --git a/stackit/internal/services/secretsmanager/instance/resource.go b/stackit/internal/services/secretsmanager/instance/resource.go
index cb56df6a2..d61021ca3 100644
--- a/stackit/internal/services/secretsmanager/instance/resource.go
+++ b/stackit/internal/services/secretsmanager/instance/resource.go
@@ -42,6 +42,14 @@ type Model struct {
ProjectId types.String `tfsdk:"project_id"`
Name types.String `tfsdk:"name"`
ACLs types.Set `tfsdk:"acls"`
+ KmsKey *KmsKeyModel `tfsdk:"kms_key"`
+}
+
+type KmsKeyModel struct {
+ KeyId types.String `tfsdk:"key_id"`
+ KeyRingId types.String `tfsdk:"key_ring_id"`
+ KeyVersion types.Int64 `tfsdk:"key_version"`
+ ServiceAccountEmail types.String `tfsdk:"service_account_email"`
}
// NewInstanceResource is a helper function to simplify the provider implementation.
@@ -77,12 +85,17 @@ func (r *instanceResource) Configure(ctx context.Context, req resource.Configure
// Schema defines the schema for the resource.
func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
descriptions := map[string]string{
- "main": "Secrets Manager instance resource schema. Must have a `region` specified in the provider configuration.",
- "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`instance_id`\".",
- "instance_id": "ID of the Secrets Manager instance.",
- "project_id": "STACKIT project ID to which the instance is associated.",
- "name": "Instance name.",
- "acls": "The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation",
+ "main": "Secrets Manager instance resource schema. Must have a `region` specified in the provider configuration.",
+ "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`instance_id`\".",
+ "instance_id": "ID of the Secrets Manager instance.",
+ "project_id": "STACKIT project ID to which the instance is associated.",
+ "name": "Instance name.",
+ "acls": "The access control list for this instance. Each entry is an IP or IP range that is permitted to access, in CIDR notation",
+ "kms_key": "The STACKIT-KMS key for secret encryption and decryption.",
+ "kms_key.key_id": "UUID of the key within the STACKIT-KMS to use for the encryption.",
+ "kms_key.key_ring_id": "UUID of the keyring where the key is located within the STACKTI-KMS.",
+ "kms_key.key_version": "Version of the key within the STACKIT-KMS to use for the encryption.",
+ "kms_key.service_account_email": "Service-Account linked to the Key within the STACKIT-KMS.",
}
resp.Schema = schema.Schema{
@@ -118,11 +131,9 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
},
},
"name": schema.StringAttribute{
- Description: descriptions["name"],
- Required: true,
- PlanModifiers: []planmodifier.String{
- stringplanmodifier.RequiresReplace(),
- },
+ Description: descriptions["name"],
+ Required: true,
+ PlanModifiers: []planmodifier.String{},
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
@@ -137,6 +148,28 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
),
},
},
+ "kms_key": schema.SingleNestedAttribute{
+ Description: descriptions["kms_key"],
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "key_id": schema.StringAttribute{
+ Description: descriptions["kms_key.key_id"],
+ Required: true,
+ },
+ "key_ring_id": schema.StringAttribute{
+ Description: descriptions["kms_key.key_ring_id"],
+ Required: true,
+ },
+ "key_version": schema.Int64Attribute{
+ Description: descriptions["kms_key.key_version"],
+ Required: true,
+ },
+ "service_account_email": schema.StringAttribute{
+ Description: descriptions["kms_key.service_account_email"],
+ Required: true,
+ },
+ },
+ },
},
}
}
@@ -284,6 +317,21 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "instance_id", instanceId)
+ // Generate API request body from model
+ payload, err := toUpdatePayload(&model)
+ if err != nil {
+ core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Creating API payload: %v", err))
+ return
+ }
+ // Update instance
+ err = r.client.UpdateInstance(ctx, projectId, instanceId).UpdateInstancePayload(*payload).Execute()
+ if err != nil {
+ core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Calling API: %v", err))
+ return
+ }
+
+ ctx = core.LogResponse(ctx)
+
var acls []string
if !(model.ACLs.IsNull() || model.ACLs.IsUnknown()) {
diags = model.ACLs.ElementsAs(ctx, &acls, false)
@@ -294,7 +342,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
}
// Update ACLs
- err := updateACLs(ctx, projectId, instanceId, acls, r.client)
+ err = updateACLs(ctx, projectId, instanceId, acls, r.client)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Updating ACLs: %v", err))
return
@@ -398,6 +446,15 @@ func mapFields(instance *secretsmanager.Instance, aclList *secretsmanager.ListAC
model.InstanceId = types.StringValue(instanceId)
model.Name = types.StringPointerValue(instance.Name)
+ if instance.KmsKey != nil {
+ model.KmsKey = &KmsKeyModel{
+ KeyId: types.StringPointerValue(instance.KmsKey.KeyId),
+ KeyRingId: types.StringPointerValue(instance.KmsKey.KeyRingId),
+ KeyVersion: types.Int64PointerValue(instance.KmsKey.KeyVersion),
+ ServiceAccountEmail: types.StringPointerValue(instance.KmsKey.ServiceAccountEmail),
+ }
+ }
+
err := mapACLs(aclList, model)
if err != nil {
return err
@@ -431,9 +488,41 @@ func toCreatePayload(model *Model) (*secretsmanager.CreateInstancePayload, error
if model == nil {
return nil, fmt.Errorf("nil model")
}
- return &secretsmanager.CreateInstancePayload{
+ payload := &secretsmanager.CreateInstancePayload{
+ Name: conversion.StringValueToPointer(model.Name),
+ }
+
+ if model.KmsKey != nil {
+ payload.KmsKey = &secretsmanager.KmsKeyPayload{
+ KeyId: conversion.StringValueToPointer(model.KmsKey.KeyId),
+ KeyRingId: conversion.StringValueToPointer(model.KmsKey.KeyRingId),
+ KeyVersion: conversion.Int64ValueToPointer(model.KmsKey.KeyVersion),
+ ServiceAccountEmail: conversion.StringValueToPointer(model.KmsKey.ServiceAccountEmail),
+ }
+ }
+
+ return payload, nil
+}
+
+func toUpdatePayload(model *Model) (*secretsmanager.UpdateInstancePayload, error) {
+ if model == nil {
+ return nil, fmt.Errorf("nil model")
+ }
+
+ payload := &secretsmanager.UpdateInstancePayload{
Name: conversion.StringValueToPointer(model.Name),
- }, nil
+ }
+
+ if model.KmsKey != nil {
+ payload.KmsKey = &secretsmanager.KmsKeyPayload{
+ KeyId: conversion.StringValueToPointer(model.KmsKey.KeyId),
+ KeyRingId: conversion.StringValueToPointer(model.KmsKey.KeyRingId),
+ KeyVersion: conversion.Int64ValueToPointer(model.KmsKey.KeyVersion),
+ ServiceAccountEmail: conversion.StringValueToPointer(model.KmsKey.ServiceAccountEmail),
+ }
+ }
+
+ return payload, nil
}
// updateACLs creates and deletes ACLs so that the instance's ACLs are the ones in the model
diff --git a/stackit/internal/services/secretsmanager/instance/resource_test.go b/stackit/internal/services/secretsmanager/instance/resource_test.go
index 39d2df834..6c821a025 100644
--- a/stackit/internal/services/secretsmanager/instance/resource_test.go
+++ b/stackit/internal/services/secretsmanager/instance/resource_test.go
@@ -141,6 +141,28 @@ func TestToCreatePayload(t *testing.T) {
},
true,
},
+ {
+ "with_kms_key",
+ &Model{
+ Name: types.StringValue("name"),
+ KmsKey: &KmsKeyModel{
+ KeyId: types.StringValue("kid"),
+ KeyRingId: types.StringValue("key-ring-id"),
+ KeyVersion: types.Int64Value(1),
+ ServiceAccountEmail: types.StringValue("service-account-email"),
+ },
+ },
+ &secretsmanager.CreateInstancePayload{
+ Name: utils.Ptr("name"),
+ KmsKey: &secretsmanager.KmsKeyPayload{
+ KeyId: utils.Ptr("kid"),
+ KeyRingId: utils.Ptr("key-ring-id"),
+ KeyVersion: utils.Ptr(int64(1)),
+ ServiceAccountEmail: utils.Ptr("service-account-email"),
+ },
+ },
+ true,
+ },
{
"null_fields_and_int_conversions",
&Model{
@@ -485,3 +507,84 @@ func TestUpdateACLs(t *testing.T) {
})
}
}
+
+func TestToUpdatePayload(t *testing.T) {
+ tests := []struct {
+ description string
+ input *Model
+ expected *secretsmanager.UpdateInstancePayload
+ isValid bool
+ }{
+ {
+ "default_values",
+ &Model{},
+ &secretsmanager.UpdateInstancePayload{},
+ true,
+ },
+ {
+ "simple_values",
+ &Model{
+ Name: types.StringValue("name"),
+ },
+ &secretsmanager.UpdateInstancePayload{
+ Name: utils.Ptr("name"),
+ },
+ true,
+ },
+ {
+ "with_kms_key",
+ &Model{
+ Name: types.StringValue("name"),
+ KmsKey: &KmsKeyModel{
+ KeyId: types.StringValue("kid"),
+ KeyRingId: types.StringValue("key-ring-id"),
+ KeyVersion: types.Int64Value(1),
+ ServiceAccountEmail: types.StringValue("service-account-email"),
+ },
+ },
+ &secretsmanager.UpdateInstancePayload{
+ Name: utils.Ptr("name"),
+ KmsKey: &secretsmanager.KmsKeyPayload{
+ KeyId: utils.Ptr("kid"),
+ KeyRingId: utils.Ptr("key-ring-id"),
+ KeyVersion: utils.Ptr(int64(1)),
+ ServiceAccountEmail: utils.Ptr("service-account-email"),
+ },
+ },
+ true,
+ },
+ {
+ "null_fields_and_int_conversions",
+ &Model{
+ Name: types.StringValue(""),
+ },
+ &secretsmanager.UpdateInstancePayload{
+ Name: utils.Ptr(""),
+ },
+ true,
+ },
+ {
+ "nil_model",
+ nil,
+ nil,
+ false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ output, err := toUpdatePayload(tt.input)
+ if !tt.isValid && err == nil {
+ t.Fatalf("Should have failed")
+ }
+ if tt.isValid && err != nil {
+ t.Fatalf("Should not have failed: %v", err)
+ }
+ if tt.isValid {
+ diff := cmp.Diff(output, tt.expected)
+ if diff != "" {
+ t.Fatalf("Data does not match: %s", diff)
+ }
+ }
+ })
+ }
+}
diff --git a/stackit/internal/services/secretsmanager/secretsmanager_acc_test.go b/stackit/internal/services/secretsmanager/secretsmanager_acc_test.go
index 16e6c1101..27c7c0e96 100644
--- a/stackit/internal/services/secretsmanager/secretsmanager_acc_test.go
+++ b/stackit/internal/services/secretsmanager/secretsmanager_acc_test.go
@@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/terraform"
core_config "github.com/stackitcloud/stackit-sdk-go/core/config"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
@@ -36,12 +37,14 @@ var testConfigVarsMin = config.Variables{
}
var testConfigVarsMax = config.Variables{
- "project_id": config.StringVariable(testutil.ProjectId),
- "instance_name": config.StringVariable("tf-acc-" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)),
- "user_description": config.StringVariable("tf-acc-" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)),
- "acl1": config.StringVariable("10.100.0.0/24"),
- "acl2": config.StringVariable("10.100.1.0/24"),
- "write_enabled": config.BoolVariable(true),
+ "project_id": config.StringVariable(testutil.ProjectId),
+ "instance_name": config.StringVariable("tf-acc-" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)),
+ "user_description": config.StringVariable("tf-acc-" + acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)),
+ "acl1": config.StringVariable("10.100.0.0/24"),
+ "acl2": config.StringVariable("10.100.1.0/24"),
+ "write_enabled": config.BoolVariable(true),
+ "service_account_mail": config.StringVariable(testutil.TestProjectServiceAccountEmail),
+ "use_kms_key": config.BoolVariable(true),
}
func configVarsInvalid(vars config.Variables) config.Variables {
@@ -52,6 +55,7 @@ func configVarsInvalid(vars config.Variables) config.Variables {
func configVarsMinUpdated() config.Variables {
tempConfig := maps.Clone(testConfigVarsMin)
+ tempConfig["instance_name"] = config.StringVariable(testutil.ConvertConfigVariable(tempConfig["instance_name"]) + "-updated")
tempConfig["write_enabled"] = config.BoolVariable(false)
return tempConfig
}
@@ -59,6 +63,7 @@ func configVarsMinUpdated() config.Variables {
func configVarsMaxUpdated() config.Variables {
tempConfig := maps.Clone(testConfigVarsMax)
tempConfig["write_enabled"] = config.BoolVariable(false)
+ tempConfig["use_kms_key"] = config.BoolVariable(false)
tempConfig["acl2"] = config.StringVariable("10.100.2.0/24")
return tempConfig
}
@@ -183,6 +188,12 @@ func TestAccSecretsManagerMin(t *testing.T) {
{
Config: resourceMinConfig,
ConfigVariables: configVarsMinUpdated(),
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PreApply: []plancheck.PlanCheck{
+ plancheck.ExpectResourceAction("stackit_secretsmanager_user.user", plancheck.ResourceActionUpdate),
+ plancheck.ExpectResourceAction("stackit_secretsmanager_instance.instance", plancheck.ResourceActionUpdate),
+ },
+ },
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance", "project_id", testutil.ConvertConfigVariable(configVarsMinUpdated()["project_id"])),
@@ -250,6 +261,24 @@ func TestAccSecretsManagerMax(t *testing.T) {
resource.TestCheckResourceAttr("stackit_secretsmanager_user.user", "write_enabled", testutil.ConvertConfigVariable(testConfigVarsMax["write_enabled"])),
resource.TestCheckResourceAttrSet("stackit_secretsmanager_user.user", "username"),
resource.TestCheckResourceAttrSet("stackit_secretsmanager_user.user", "password"),
+
+ // Instance with kms key
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "project_id", testutil.ConvertConfigVariable(testConfigVarsMax["project_id"])),
+ resource.TestCheckResourceAttrSet("stackit_secretsmanager_instance.instance_with_key", "instance_id"),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "name", testutil.ConvertConfigVariable(testConfigVarsMax["instance_name"])),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.#", "2"),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.0", testutil.ConvertConfigVariable(testConfigVarsMax["acl1"])),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.1", testutil.ConvertConfigVariable(testConfigVarsMax["acl2"])),
+ resource.TestCheckResourceAttrPair(
+ "stackit_secretsmanager_instance.instance_with_key", "kms_key.key_id",
+ "stackit_kms_key.key", "key_id",
+ ),
+ resource.TestCheckResourceAttrPair(
+ "stackit_secretsmanager_instance.instance_with_key", "kms_key.key_ring_id",
+ "stackit_kms_keyring.keyring", "keyring_id",
+ ),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "kms_key.key_version", "1"),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "kms_key.service_account_email", testutil.ConvertConfigVariable(testConfigVarsMax["service_account_mail"])),
),
},
// Data source
@@ -287,6 +316,24 @@ func TestAccSecretsManagerMax(t *testing.T) {
"stackit_secretsmanager_user.user", "username",
"data.stackit_secretsmanager_user.user", "username",
),
+
+ // Instance with kms key
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "project_id", testutil.ConvertConfigVariable(testConfigVarsMax["project_id"])),
+ resource.TestCheckResourceAttrSet("data.stackit_secretsmanager_instance.instance_with_key", "instance_id"),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "name", testutil.ConvertConfigVariable(testConfigVarsMax["instance_name"])),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "acls.#", "2"),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "acls.0", testutil.ConvertConfigVariable(testConfigVarsMax["acl1"])),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "acls.1", testutil.ConvertConfigVariable(testConfigVarsMax["acl2"])),
+ resource.TestCheckResourceAttrPair(
+ "data.stackit_secretsmanager_instance.instance_with_key", "kms_key.key_id",
+ "stackit_kms_key.key", "key_id",
+ ),
+ resource.TestCheckResourceAttrPair(
+ "data.stackit_secretsmanager_instance.instance_with_key", "kms_key.key_ring_id",
+ "stackit_kms_keyring.keyring", "keyring_id",
+ ),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "kms_key.key_version", "1"),
+ resource.TestCheckResourceAttr("data.stackit_secretsmanager_instance.instance_with_key", "kms_key.service_account_email", testutil.ConvertConfigVariable(testConfigVarsMax["service_account_mail"])),
),
},
// Import
@@ -307,6 +354,24 @@ func TestAccSecretsManagerMax(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
},
+ // Import
+ {
+ ConfigVariables: testConfigVarsMax,
+ ResourceName: "stackit_secretsmanager_instance.instance_with_key",
+ ImportStateIdFunc: func(s *terraform.State) (string, error) {
+ r, ok := s.RootModule().Resources["stackit_secretsmanager_instance.instance_with_key"]
+ if !ok {
+ return "", fmt.Errorf("couldn't find resource stackit_secretsmanager_instance.instance_with_key")
+ }
+ instanceId, ok := r.Primary.Attributes["instance_id"]
+ if !ok {
+ return "", fmt.Errorf("couldn't find attribute instance_id")
+ }
+ return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil
+ },
+ ImportState: true,
+ ImportStateVerify: true,
+ },
{
Config: resourceMaxConfig,
ConfigVariables: testConfigVarsMax,
@@ -336,6 +401,13 @@ func TestAccSecretsManagerMax(t *testing.T) {
{
Config: resourceMaxConfig,
ConfigVariables: configVarsMaxUpdated(),
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PreApply: []plancheck.PlanCheck{
+ plancheck.ExpectResourceAction("stackit_secretsmanager_user.user", plancheck.ResourceActionUpdate),
+ plancheck.ExpectResourceAction("stackit_secretsmanager_instance.instance", plancheck.ResourceActionUpdate),
+ plancheck.ExpectResourceAction("stackit_secretsmanager_instance.instance_with_key", plancheck.ResourceActionUpdate),
+ },
+ },
Check: resource.ComposeAggregateTestCheckFunc(
// Instance
resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance", "project_id", testutil.ConvertConfigVariable(configVarsMaxUpdated()["project_id"])),
@@ -359,6 +431,15 @@ func TestAccSecretsManagerMax(t *testing.T) {
resource.TestCheckResourceAttr("stackit_secretsmanager_user.user", "write_enabled", testutil.ConvertConfigVariable(configVarsMaxUpdated()["write_enabled"])),
resource.TestCheckResourceAttrSet("stackit_secretsmanager_user.user", "username"),
resource.TestCheckResourceAttrSet("stackit_secretsmanager_user.user", "password"),
+
+ // Instance with kms key
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "project_id", testutil.ConvertConfigVariable(configVarsMaxUpdated()["project_id"])),
+ resource.TestCheckResourceAttrSet("stackit_secretsmanager_instance.instance_with_key", "instance_id"),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "name", testutil.ConvertConfigVariable(configVarsMaxUpdated()["instance_name"])),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.#", "2"),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.0", testutil.ConvertConfigVariable(configVarsMaxUpdated()["acl1"])),
+ resource.TestCheckResourceAttr("stackit_secretsmanager_instance.instance_with_key", "acls.1", testutil.ConvertConfigVariable(configVarsMaxUpdated()["acl2"])),
+ resource.TestCheckNoResourceAttr("stackit_secretsmanager_instance.instance_with_key", "kms_key"),
),
},
// Deletion is done by the framework implicitly
diff --git a/stackit/internal/services/secretsmanager/testdata/resource-max.tf b/stackit/internal/services/secretsmanager/testdata/resource-max.tf
index deea23ba4..cb882a16a 100644
--- a/stackit/internal/services/secretsmanager/testdata/resource-max.tf
+++ b/stackit/internal/services/secretsmanager/testdata/resource-max.tf
@@ -4,6 +4,8 @@ variable "user_description" {}
variable "write_enabled" {}
variable "acl1" {}
variable "acl2" {}
+variable "service_account_mail" {}
+variable "use_kms_key" {}
resource "stackit_secretsmanager_instance" "instance" {
project_id = var.project_id
@@ -32,3 +34,41 @@ data "stackit_secretsmanager_user" "user" {
instance_id = stackit_secretsmanager_instance.instance.instance_id
user_id = stackit_secretsmanager_user.user.user_id
}
+
+# just needed for the test setup for secretsmanager with own keys
+resource "stackit_kms_keyring" "keyring" {
+ project_id = var.project_id
+ display_name = var.instance_name
+}
+
+# just needed for the test setup for secretsmanager with own keys
+resource "stackit_kms_key" "key" {
+ project_id = var.project_id
+ keyring_id = stackit_kms_keyring.keyring.keyring_id
+ display_name = var.instance_name
+ protection = "software"
+ algorithm = "aes_256_gcm"
+ purpose = "symmetric_encrypt_decrypt"
+}
+
+resource "stackit_secretsmanager_instance" "instance_with_key" {
+ project_id = var.project_id
+ name = var.instance_name
+ acls = [
+ var.acl1,
+ var.acl2,
+ ]
+
+ kms_key = var.use_kms_key ? {
+ key_id = stackit_kms_key.key.key_id
+ key_ring_id = stackit_kms_keyring.keyring.keyring_id
+ key_version = 1
+ service_account_email = var.service_account_mail
+ } : null
+}
+
+
+data "stackit_secretsmanager_instance" "instance_with_key" {
+ project_id = var.project_id
+ instance_id = stackit_secretsmanager_instance.instance_with_key.instance_id
+}