Skip to content

Commit ea3a2b2

Browse files
authored
Merge pull request hashicorp#45020 from jackroberts-gh/f-aws-backup-lag-vault-kms-key-support
r/aws_backup_logically_air_gapped_vault: add encryption_key_arn attr
2 parents 628a7f0 + b30a437 commit ea3a2b2

File tree

5 files changed

+88
-15
lines changed

5 files changed

+88
-15
lines changed

.changelog/45020.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/aws_backup_logically_air_gapped_vault: Add `encryption_key_arn` argument
3+
```

internal/service/backup/logically_air_gapped_vault.go

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag"
3232
"github.com/hashicorp/terraform-provider-aws/internal/framework"
3333
fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
34+
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
3435
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
3536
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
3637
"github.com/hashicorp/terraform-provider-aws/names"
@@ -57,7 +58,15 @@ func (r *logicallyAirGappedVaultResource) Schema(ctx context.Context, request re
5758
response.Schema = schema.Schema{
5859
Attributes: map[string]schema.Attribute{
5960
names.AttrARN: framework.ARNAttributeComputedOnly(),
60-
names.AttrID: framework.IDAttribute(),
61+
"encryption_key_arn": schema.StringAttribute{
62+
CustomType: fwtypes.ARNType,
63+
Optional: true,
64+
Computed: true,
65+
PlanModifiers: []planmodifier.String{
66+
stringplanmodifier.RequiresReplace(),
67+
},
68+
},
69+
names.AttrID: framework.IDAttribute(),
6170
"max_retention_days": schema.Int64Attribute{
6271
Required: true,
6372
PlanModifiers: []planmodifier.Int64{
@@ -102,9 +111,9 @@ func (r *logicallyAirGappedVaultResource) Create(ctx context.Context, request re
102111

103112
conn := r.Meta().BackupClient(ctx)
104113

105-
name := data.BackupVaultName.ValueString()
106-
input := &backup.CreateLogicallyAirGappedBackupVaultInput{}
107-
response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...)
114+
name := fwflex.StringValueFromFramework(ctx, data.BackupVaultName)
115+
var input backup.CreateLogicallyAirGappedBackupVaultInput
116+
response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...)
108117
if response.Diagnostics.HasError() {
109118
return
110119
}
@@ -113,7 +122,7 @@ func (r *logicallyAirGappedVaultResource) Create(ctx context.Context, request re
113122
input.BackupVaultTags = getTagsIn(ctx)
114123
input.CreatorRequestId = aws.String(sdkid.UniqueId())
115124

116-
output, err := conn.CreateLogicallyAirGappedBackupVault(ctx, input)
125+
output, err := conn.CreateLogicallyAirGappedBackupVault(ctx, &input)
117126

118127
if err != nil {
119128
response.Diagnostics.AddError(fmt.Sprintf("creating Backup Logically Air Gapped Vault (%s)", name), err.Error())
@@ -123,15 +132,21 @@ func (r *logicallyAirGappedVaultResource) Create(ctx context.Context, request re
123132

124133
// Set values for unknowns.
125134
data.BackupVaultARN = fwflex.StringToFramework(ctx, output.BackupVaultArn)
126-
data.ID = fwflex.StringToFramework(ctx, output.BackupVaultName)
135+
data.ID = fwflex.StringValueToFramework(ctx, name)
127136

128-
if _, err := waitLogicallyAirGappedVaultCreated(ctx, conn, data.ID.ValueString(), r.CreateTimeout(ctx, data.Timeouts)); err != nil {
137+
vault, err := waitLogicallyAirGappedVaultCreated(ctx, conn, name, r.CreateTimeout(ctx, data.Timeouts))
138+
if err != nil {
129139
response.State.SetAttribute(ctx, path.Root(names.AttrID), data.ID) // Set 'id' so as to taint the resource.
130-
response.Diagnostics.AddError(fmt.Sprintf("waiting for Backup Logically Air Gapped Vault (%s) create", data.ID.ValueString()), err.Error())
140+
response.Diagnostics.AddError(fmt.Sprintf("waiting for Backup Logically Air Gapped Vault (%s) create", name), err.Error())
131141

132142
return
133143
}
134144

145+
response.Diagnostics.Append(fwflex.Flatten(ctx, vault, &data)...)
146+
if response.Diagnostics.HasError() {
147+
return
148+
}
149+
135150
response.Diagnostics.Append(response.State.Set(ctx, data)...)
136151
}
137152

@@ -144,7 +159,8 @@ func (r *logicallyAirGappedVaultResource) Read(ctx context.Context, request reso
144159

145160
conn := r.Meta().BackupClient(ctx)
146161

147-
output, err := findLogicallyAirGappedBackupVaultByName(ctx, conn, data.ID.ValueString())
162+
name := fwflex.StringValueFromFramework(ctx, data.ID)
163+
output, err := findLogicallyAirGappedBackupVaultByName(ctx, conn, name)
148164

149165
if tfresource.NotFound(err) {
150166
response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err))
@@ -154,7 +170,7 @@ func (r *logicallyAirGappedVaultResource) Read(ctx context.Context, request reso
154170
}
155171

156172
if err != nil {
157-
response.Diagnostics.AddError(fmt.Sprintf("reading Backup Logically Air Gapped Vault (%s)", data.ID.ValueString()), err.Error())
173+
response.Diagnostics.AddError(fmt.Sprintf("reading Backup Logically Air Gapped Vault (%s)", name), err.Error())
158174

159175
return
160176
}
@@ -177,8 +193,9 @@ func (r *logicallyAirGappedVaultResource) Delete(ctx context.Context, request re
177193

178194
conn := r.Meta().BackupClient(ctx)
179195

196+
name := fwflex.StringValueFromFramework(ctx, data.ID)
180197
input := backup.DeleteBackupVaultInput{
181-
BackupVaultName: fwflex.StringFromFramework(ctx, data.ID),
198+
BackupVaultName: aws.String(name),
182199
}
183200
_, err := conn.DeleteBackupVault(ctx, &input)
184201

@@ -187,7 +204,7 @@ func (r *logicallyAirGappedVaultResource) Delete(ctx context.Context, request re
187204
}
188205

189206
if err != nil {
190-
response.Diagnostics.AddError(fmt.Sprintf("deleting Backup Logically Air Gapped Vault (%s)", data.ID.ValueString()), err.Error())
207+
response.Diagnostics.AddError(fmt.Sprintf("deleting Backup Logically Air Gapped Vault (%s)", name), err.Error())
191208

192209
return
193210
}
@@ -197,6 +214,7 @@ type logicallyAirGappedVaultResourceModel struct {
197214
framework.WithRegionModel
198215
BackupVaultARN types.String `tfsdk:"arn"`
199216
BackupVaultName types.String `tfsdk:"name"`
217+
EncryptionKeyARN fwtypes.ARN `tfsdk:"encryption_key_arn"`
200218
ID types.String `tfsdk:"id"`
201219
MaxRetentionDays types.Int64 `tfsdk:"max_retention_days"`
202220
MinRetentionDays types.Int64 `tfsdk:"min_retention_days"`
@@ -245,7 +263,6 @@ func waitLogicallyAirGappedVaultCreated(ctx context.Context, conn *backup.Client
245263
}
246264

247265
outputRaw, err := stateConf.WaitForStateContext(ctx)
248-
249266
if output, ok := outputRaw.(*backup.DescribeBackupVaultOutput); ok {
250267
return output, err
251268
}

internal/service/backup/logically_air_gapped_vault_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010

1111
"github.com/aws/aws-sdk-go-v2/service/backup"
12+
"github.com/hashicorp/terraform-plugin-testing/compare"
1213
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
1314
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1415
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
@@ -88,6 +89,41 @@ func TestAccBackupLogicallyAirGappedVault_disappears(t *testing.T) {
8889
})
8990
}
9091

92+
func TestAccBackupLogicallyAirGappedVault_encryptionKeyARN(t *testing.T) {
93+
ctx := acctest.Context(t)
94+
var v backup.DescribeBackupVaultOutput
95+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
96+
resourceName := "aws_backup_logically_air_gapped_vault.test"
97+
kmsKeyResourceName := "aws_kms_key.test"
98+
99+
resource.ParallelTest(t, resource.TestCase{
100+
PreCheck: func() {
101+
acctest.PreCheck(ctx, t)
102+
acctest.PreCheckPartitionHasService(t, names.BackupEndpointID)
103+
testAccPreCheck(ctx, t)
104+
},
105+
ErrorCheck: acctest.ErrorCheck(t, names.BackupServiceID),
106+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
107+
CheckDestroy: testAccCheckLogicallyAirGappedVaultDestroy(ctx),
108+
Steps: []resource.TestStep{
109+
{
110+
Config: testAccLogicallyAirGappedVaultConfig_encryptionKeyARN(rName),
111+
ConfigStateChecks: []statecheck.StateCheck{
112+
statecheck.CompareValuePairs(resourceName, tfjsonpath.New("encryption_key_arn"), kmsKeyResourceName, tfjsonpath.New(names.AttrARN), compare.ValuesSame()),
113+
},
114+
Check: resource.ComposeTestCheckFunc(
115+
testAccCheckLogicallyAirGappedVaultExists(ctx, resourceName, &v),
116+
),
117+
},
118+
{
119+
ResourceName: resourceName,
120+
ImportState: true,
121+
ImportStateVerify: true,
122+
},
123+
},
124+
})
125+
}
126+
91127
func TestAccBackupLogicallyAirGappedVault_tags(t *testing.T) {
92128
ctx := acctest.Context(t)
93129
var v backup.DescribeBackupVaultOutput
@@ -202,6 +238,22 @@ resource "aws_backup_logically_air_gapped_vault" "test" {
202238
`, rName)
203239
}
204240

241+
func testAccLogicallyAirGappedVaultConfig_encryptionKeyARN(rName string) string {
242+
return fmt.Sprintf(`
243+
resource "aws_kms_key" "test" {
244+
description = %[1]q
245+
deletion_window_in_days = 7
246+
}
247+
248+
resource "aws_backup_logically_air_gapped_vault" "test" {
249+
name = %[1]q
250+
max_retention_days = 10
251+
min_retention_days = 7
252+
encryption_key_arn = aws_kms_key.test.arn
253+
}
254+
`, rName)
255+
}
256+
205257
func testAccLogicallyAirGappedVaultConfig_tags1(rName, tagKey1, tagValue1 string) string {
206258
return fmt.Sprintf(`
207259
resource "aws_backup_logically_air_gapped_vault" "test" {

internal/service/backup/vault.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ func findBackupVaultByName(ctx context.Context, conn *backup.Client, name string
218218
}
219219

220220
func findVaultByName(ctx context.Context, conn *backup.Client, name string) (*backup.DescribeBackupVaultOutput, error) {
221-
input := &backup.DescribeBackupVaultInput{
221+
input := backup.DescribeBackupVaultInput{
222222
BackupVaultName: aws.String(name),
223223
}
224224

225-
output, err := findVault(ctx, conn, input)
225+
output, err := findVault(ctx, conn, &input)
226226

227227
if err != nil {
228228
return nil, err

website/docs/r/backup_logically_air_gapped_vault.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This resource supports the following arguments:
3030
* `name` - (Required) Name of the Logically Air Gapped Backup Vault to create.
3131
* `max_retention_days` - (Required) Maximum retention period that the Logically Air Gapped Backup Vault retains recovery points.
3232
* `min_retention_days` - (Required) Minimum retention period that the Logically Air Gapped Backup Vault retains recovery points.
33+
* `encryption_key_arn` - (Optional) The AWS KMS key identifier (ARN) used to encrypt the backups in the logically air-gapped vault.
3334
* `tags` - (Optional) Metadata that you can assign to help organize the resources that you create. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
3435

3536
## Attribute Reference

0 commit comments

Comments
 (0)