Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resource: aws_memorydb_subnet_group #22256

Merged
merged 4 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/22256.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_memorydb_subnet_group
```
3 changes: 3 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/service/mediaconvert"
"github.com/hashicorp/terraform-provider-aws/internal/service/mediapackage"
"github.com/hashicorp/terraform-provider-aws/internal/service/mediastore"
"github.com/hashicorp/terraform-provider-aws/internal/service/memorydb"
"github.com/hashicorp/terraform-provider-aws/internal/service/meta"
"github.com/hashicorp/terraform-provider-aws/internal/service/mq"
"github.com/hashicorp/terraform-provider-aws/internal/service/mwaa"
Expand Down Expand Up @@ -1375,6 +1376,8 @@ func Provider() *schema.Provider {
"aws_media_store_container": mediastore.ResourceContainer(),
"aws_media_store_container_policy": mediastore.ResourceContainerPolicy(),

"aws_memorydb_subnet_group": memorydb.ResourceSubnetGroup(),

"aws_mq_broker": mq.ResourceBroker(),
"aws_mq_configuration": mq.ResourceConfiguration(),

Expand Down
40 changes: 40 additions & 0 deletions internal/service/memorydb/find.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package memorydb

import (
"context"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/memorydb"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func FindSubnetGroupByName(ctx context.Context, conn *memorydb.MemoryDB, name string) (*memorydb.SubnetGroup, error) {
input := memorydb.DescribeSubnetGroupsInput{
SubnetGroupName: aws.String(name),
}

output, err := conn.DescribeSubnetGroupsWithContext(ctx, &input)

if tfawserr.ErrCodeEquals(err, memorydb.ErrCodeSubnetGroupNotFoundFault) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil || len(output.SubnetGroups) == 0 || output.SubnetGroups[0] == nil {
return nil, tfresource.NewEmptyResultError(input)
}

if count := len(output.SubnetGroups); count > 1 {
return nil, tfresource.NewTooManyResultsError(count, input)
}

return output.SubnetGroups[0], nil
}
4 changes: 4 additions & 0 deletions internal/service/memorydb/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsOp=ListTags -ListTagsOutTagsElem=TagList -ServiceTagsSlice -UpdateTags
// ONLY generate directives and package declaration! Do not add anything else to this file.

package memorydb
216 changes: 216 additions & 0 deletions internal/service/memorydb/subnet_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package memorydb

import (
"context"
"log"
"regexp"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/memorydb"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func ResourceSubnetGroup() *schema.Resource {
return &schema.Resource{
CreateContext: resourceSubnetGroupCreate,
ReadContext: resourceSubnetGroupRead,
UpdateContext: resourceSubnetGroupUpdate,
DeleteContext: resourceSubnetGroupDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

CustomizeDiff: verify.SetTagsDiff,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name_prefix"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 255),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]*[a-z0-9]$`),
"Only lowercase alphanumeric characters and hyphens allowed. The name may not end with a hyphen."),
),
},
"name_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name"},
ValidateFunc: validation.All(
validation.StringLenBetween(1, 255-resource.UniqueIDSuffixLength),
validation.StringDoesNotMatch(
regexp.MustCompile(`[-][-]`),
"The name may not contain two consecutive hyphens."),
validation.StringMatch(
// Similar to ElastiCache, MemoryDB normalises names to lowercase.
regexp.MustCompile(`^[a-z0-9-]+$`),
"Only lowercase alphanumeric characters and hyphens allowed."),
),
},
"subnet_ids": {
Type: schema.TypeSet,
Required: true,
MinItems: 1,
Elem: &schema.Schema{Type: schema.TypeString},
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"vpc_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceSubnetGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).MemoryDBConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

name := create.Name(d.Get("name").(string), d.Get("name_prefix").(string))
input := &memorydb.CreateSubnetGroupInput{
Description: aws.String(d.Get("description").(string)),
SubnetGroupName: aws.String(name),
SubnetIds: flex.ExpandStringSet(d.Get("subnet_ids").(*schema.Set)),
Tags: Tags(tags.IgnoreAWS()),
}

log.Printf("[DEBUG] Creating MemoryDB Subnet Group: %s", input)
_, err := conn.CreateSubnetGroupWithContext(ctx, input)

if err != nil {
return diag.Errorf("error creating MemoryDB Subnet Group (%s): %s", name, err)
}

d.SetId(name)

return resourceSubnetGroupRead(ctx, d, meta)
}

func resourceSubnetGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).MemoryDBConn

if d.HasChangesExcept("tags", "tags_all") {
input := &memorydb.UpdateSubnetGroupInput{
Description: aws.String(d.Get("description").(string)),
SubnetGroupName: aws.String(d.Id()),
SubnetIds: flex.ExpandStringSet(d.Get("subnet_ids").(*schema.Set)),
}

log.Printf("[DEBUG] Updating MemoryDB Subnet Group: %s", input)
_, err := conn.UpdateSubnetGroupWithContext(ctx, input)

if err != nil {
return diag.Errorf("error updating MemoryDB Subnet Group (%s): %s", d.Id(), err)
}
}

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return diag.Errorf("error updating MemoryDB Subnet Group (%s) tags: %s", d.Id(), err)
}
}

return resourceSubnetGroupRead(ctx, d, meta)
}

func resourceSubnetGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).MemoryDBConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

group, err := FindSubnetGroupByName(ctx, conn, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] MemoryDB Subnet Group (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return diag.Errorf("error reading MemoryDB Subnet Group (%s): %s", d.Id(), err)
}

var subnetIds []*string
for _, subnet := range group.Subnets {
subnetIds = append(subnetIds, subnet.Identifier)
}

d.Set("arn", group.ARN)
d.Set("description", group.Description)
d.Set("subnet_ids", flex.FlattenStringSet(subnetIds))
d.Set("name", group.Name)
d.Set("name_prefix", create.NamePrefixFromName(aws.StringValue(group.Name)))
d.Set("vpc_id", group.VpcId)

tags, err := ListTags(conn, d.Get("arn").(string))

if err != nil {
return diag.Errorf("error listing tags for MemoryDB Subnet Group (%s): %s", d.Id(), err)
}

tags = tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return diag.Errorf("error setting tags for MemoryDB Subnet Group (%s): %s", d.Id(), err)
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return diag.Errorf("error setting tags_all for MemoryDB Subnet Group (%s): %s", d.Id(), err)
}

return nil
}

func resourceSubnetGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).MemoryDBConn

log.Printf("[DEBUG] Deleting MemoryDB Subnet Group: (%s)", d.Id())
_, err := conn.DeleteSubnetGroupWithContext(ctx, &memorydb.DeleteSubnetGroupInput{
SubnetGroupName: aws.String(d.Id()),
})

if tfawserr.ErrCodeEquals(err, memorydb.ErrCodeSubnetGroupNotFoundFault) {
return nil
}

if err != nil {
return diag.Errorf("error deleting MemoryDB Subnet Group (%s): %s", d.Id(), err)
}

return nil
}
Loading