Skip to content

Commit

Permalink
Merge pull request #6277 from saravanan30erd/issue-6054
Browse files Browse the repository at this point in the history
Issue #6054 Add name_prefix attribute to aws_secretsmanager_secret
  • Loading branch information
bflad authored Oct 26, 2018
2 parents f128401 + 0a17b4d commit 45df614
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 7 deletions.
28 changes: 24 additions & 4 deletions aws/resource_aws_secretsmanager_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,20 @@ func resourceAwsSecretsManagerSecret() *schema.Resource {
Optional: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name_prefix"},
ValidateFunc: validateSecretManagerSecretName,
},
"name_prefix": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"name"},
ValidateFunc: validateSecretManagerSecretNamePrefix,
},
"policy": {
Type: schema.TypeString,
Expand Down Expand Up @@ -92,9 +103,18 @@ func resourceAwsSecretsManagerSecret() *schema.Resource {
func resourceAwsSecretsManagerSecretCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).secretsmanagerconn

var secretName string
if v, ok := d.GetOk("name"); ok {
secretName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
secretName = resource.PrefixedUniqueId(v.(string))
} else {
secretName = resource.UniqueId()
}

input := &secretsmanager.CreateSecretInput{
Description: aws.String(d.Get("description").(string)),
Name: aws.String(d.Get("name").(string)),
Name: aws.String(secretName),
}

if v, ok := d.GetOk("kms_key_id"); ok && v.(string) != "" {
Expand Down
36 changes: 36 additions & 0 deletions aws/resource_aws_secretsmanager_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,34 @@ func TestAccAwsSecretsManagerSecret_Basic(t *testing.T) {
})
}

func TestAccAwsSecretsManagerSecret_withNamePrefix(t *testing.T) {
var secret secretsmanager.DescribeSecretOutput
rName := "tf-acc-test-"
resourceName := "aws_secretsmanager_secret.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsSecretsManagerSecretDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsSecretsManagerSecretConfig_withNamePrefix(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSecretsManagerSecretExists(resourceName, &secret),
resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile(fmt.Sprintf("^arn:[^:]+:secretsmanager:[^:]+:[^:]+:secret:%s.+$", rName))),
resource.TestMatchResourceAttr(resourceName, "name", regexp.MustCompile(fmt.Sprintf("^%s", rName))),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"recovery_window_in_days", "name_prefix"},
},
},
})
}

func TestAccAwsSecretsManagerSecret_Description(t *testing.T) {
var secret secretsmanager.DescribeSecretOutput
rName := acctest.RandomWithPrefix("tf-acc-test")
Expand Down Expand Up @@ -495,6 +523,14 @@ resource "aws_secretsmanager_secret" "test" {
`, rName)
}

func testAccAwsSecretsManagerSecretConfig_withNamePrefix(rName string) string {
return fmt.Sprintf(`
resource "aws_secretsmanager_secret" "test" {
name_prefix = "%s"
}
`, rName)
}

func testAccAwsSecretsManagerSecretConfig_KmsKeyID(rName string) string {
return fmt.Sprintf(`
resource "aws_kms_key" "test1" {
Expand Down
27 changes: 27 additions & 0 deletions aws/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -2014,6 +2014,19 @@ func validateLbTargetGroupName(v interface{}, k string) (ws []string, errors []e
return
}

func validateSecretManagerSecretName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z/_+=.@-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters and /_+=.@- special characters are allowed in %q", k))
}
if len(value) > 512 {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than 512 characters", k))
}
return
}

func validateLbTargetGroupNamePrefix(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
prefixMaxLength := 32 - resource.UniqueIDSuffixLength
Expand All @@ -2031,3 +2044,17 @@ func validateLbTargetGroupNamePrefix(v interface{}, k string) (ws []string, erro
}
return
}

func validateSecretManagerSecretNamePrefix(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z/_+=.@-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters and /_+=.@- special characters are allowed in %q", k))
}
prefixMaxLength := 512 - resource.UniqueIDSuffixLength
if len(value) > prefixMaxLength {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than %d characters", k, prefixMaxLength))
}
return
}
54 changes: 52 additions & 2 deletions aws/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2890,7 +2890,6 @@ func TestValidateLbTargetGroupName(t *testing.T) {
ErrCount: 1,
},
}

for _, tc := range cases {
_, errors := validateLbTargetGroupName(tc.Value, "aws_lb_target_group")
if len(errors) != tc.ErrCount {
Expand All @@ -2917,11 +2916,62 @@ func TestValidateLbTargetGroupNamePrefix(t *testing.T) {
ErrCount: 1,
},
}

for _, tc := range cases {
_, errors := validateLbTargetGroupNamePrefix(tc.Value, "aws_lb_target_group")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS LB Target Group Name to trigger a validation error for %q", tc.Value)
}
}
}

func TestValidateSecretManagerSecretName(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{
Value: "testing123!",
ErrCount: 1,
},
{
Value: "testing 123",
ErrCount: 1,
},
{
Value: randomString(513),
ErrCount: 1,
},
}
for _, tc := range cases {
_, errors := validateSecretManagerSecretName(tc.Value, "aws_secretsmanager_secret")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS Secretsmanager Secret Name to not trigger a validation error for %q", tc.Value)
}
}
}

func TestValidateSecretManagerSecretNamePrefix(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
{
Value: "testing123!",
ErrCount: 1,
},
{
Value: "testing 123",
ErrCount: 1,
},
{
Value: randomString(512),
ErrCount: 1,
},
}
for _, tc := range cases {
_, errors := validateSecretManagerSecretNamePrefix(tc.Value, "aws_secretsmanager_secret")
if len(errors) != tc.ErrCount {
t.Fatalf("Expected the AWS Secretsmanager Secret Name to not trigger a validation error for %q", tc.Value)
}
}
}
3 changes: 2 additions & 1 deletion website/docs/r/secretsmanager_secret.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ resource "aws_secretsmanager_secret" "rotation-example" {

The following arguments are supported:

* `name` - (Required) Specifies the friendly name of the new secret. The secret name can consist of uppercase letters, lowercase letters, digits, and any of the following characters: `/_+=.@-` Spaces are not permitted.
* `name` - (Optional) Specifies the friendly name of the new secret. The secret name can consist of uppercase letters, lowercase letters, digits, and any of the following characters: `/_+=.@-` Conflicts with `name_prefix`.
* `name_prefix` - (Optional) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
* `description` - (Optional) A description of the secret.
* `kms_key_id` - (Optional) Specifies the ARN or alias of the AWS KMS customer master key (CMK) to be used to encrypt the secret values in the versions stored in this secret. If you don't specify this value, then Secrets Manager defaults to using the AWS account's default CMK (the one named `aws/secretsmanager`). If the default KMS CMK with that name doesn't yet exist, then AWS Secrets Manager creates it for you automatically the first time.
* `policy` - (Optional) A valid JSON document representing a [resource policy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-based-policies.html). For more information about building AWS IAM policy documents with Terraform, see the [AWS IAM Policy Document Guide](/docs/providers/aws/guides/iam-policy-documents.html).
Expand Down

0 comments on commit 45df614

Please sign in to comment.