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

Implement aws_secretsmanager_random_password data source #25704

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ func Provider() *schema.Provider {
"aws_secretsmanager_secret_rotation": secretsmanager.DataSourceSecretRotation(),
"aws_secretsmanager_secret_version": secretsmanager.DataSourceSecretVersion(),
"aws_secretsmanager_secrets": secretsmanager.DataSourceSecrets(),
"aws_secretsmanager_random_password": secretsmanager.DataSourceRandomPassword(),

"aws_serverlessapplicationrepository_application": serverlessrepo.DataSourceApplication(),

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

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
)

func DataSourceRandomPassword() *schema.Resource {
return &schema.Resource{
Read: dataSourceRandomPasswordRead,

Schema: map[string]*schema.Schema{
"exclude_characters": {
Type: schema.TypeString,
Optional: true,
},
"exclude_lowercase": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_numbers": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_punctuation": {
Type: schema.TypeBool,
Optional: true,
},
"exclude_uppercase": {
Type: schema.TypeBool,
Optional: true,
},
"include_space": {
Type: schema.TypeBool,
Optional: true,
},
"password_length": {
Type: schema.TypeInt,
Optional: true,
Default: 32,
},
"require_each_included_type": {
Type: schema.TypeBool,
Optional: true,
},
"random_password": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}

func dataSourceRandomPasswordRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).SecretsManagerConn

var excludeCharacters string
if v, ok := d.GetOk("exclude_characters"); ok {
excludeCharacters = v.(string)
}
var excludeLowercase bool
if v, ok := d.GetOk("exclude_lowercase"); ok {
excludeLowercase = v.(bool)
}
var excludeNumbers bool
if v, ok := d.GetOk("exclude_numbers"); ok {
excludeNumbers = v.(bool)
}
var excludePunctuation bool
if v, ok := d.GetOk("exclude_punctuation"); ok {
excludePunctuation = v.(bool)
}
var excludeUppercase bool
if v, ok := d.GetOk("exclude_uppercase"); ok {
excludeUppercase = v.(bool)
}
var includeSpace bool
if v, ok := d.GetOk("exclude_space"); ok {
includeSpace = v.(bool)
}
var passwordLength int64
if v, ok := d.GetOk("password_length"); ok {
passwordLength = int64(v.(int))
}
var requireEachIncludedType bool
if v, ok := d.GetOk("require_each_included_type"); ok {
requireEachIncludedType = v.(bool)
}

input := &secretsmanager.GetRandomPasswordInput{
ExcludeCharacters: aws.String(excludeCharacters),
ExcludeLowercase: aws.Bool(excludeLowercase),
ExcludeNumbers: aws.Bool(excludeNumbers),
ExcludePunctuation: aws.Bool(excludePunctuation),
ExcludeUppercase: aws.Bool(excludeUppercase),
IncludeSpace: aws.Bool(includeSpace),
PasswordLength: aws.Int64(passwordLength),
RequireEachIncludedType: aws.Bool(requireEachIncludedType),
}

log.Printf("[DEBUG] Reading Secrets Manager Get Random Password: %s", input)
output, err := conn.GetRandomPassword(input)
if err != nil {
return fmt.Errorf("error reading Secrets Manager Get Random Password: %w", err)
}

d.SetId(aws.StringValue(output.RandomPassword))
d.Set("random_password", output.RandomPassword)

return nil
}
107 changes: 107 additions & 0 deletions internal/service/secretsmanager/random_password_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package secretsmanager_test

import (
"fmt"
"testing"
"unicode"

"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccSecretsManagerRandomPasswordDataSource_basic(t *testing.T) {
datasourceName := "data.aws_secretsmanager_random_password.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRandomPasswordDataSourceConfig_basic(),
Check: resource.ComposeTestCheckFunc(
testAccRandomPasswordDataSource(datasourceName, 40),
),
},
},
})
}

func TestAccSecretsManagerRandomPasswordDataSource_exclude(t *testing.T) {
datasourceName := "data.aws_secretsmanager_random_password.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, secretsmanager.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRandomPasswordDataSourceConfig_exclude(),
Check: resource.ComposeTestCheckFunc(
func(s *terraform.State) error {
dataSource, ok := s.RootModule().Resources[datasourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", datasourceName)
}

if len(dataSource.Primary.Attributes["random_password"]) != 40 {
return fmt.Errorf(
"len(%s) != %d",
dataSource.Primary.Attributes["random_password"],
40,
)
}

for _, r := range dataSource.Primary.Attributes["random_password"] {
if !(unicode.IsLower(r) && unicode.IsLetter(r)) {
return fmt.Errorf("expected only lowercase letters")
}
}

return nil
},
),
},
},
})
}

func testAccRandomPasswordDataSource(datasourceName string, expectedLength int) resource.TestCheckFunc {
return func(s *terraform.State) error {
dataSource, ok := s.RootModule().Resources[datasourceName]
if !ok {
return fmt.Errorf("root module has no resource called %s", datasourceName)
}

if len(dataSource.Primary.Attributes["random_password"]) != expectedLength {
return fmt.Errorf(
"len(%s) != %d",
dataSource.Primary.Attributes["random_password"],
expectedLength,
)
}

return nil
}
}

func testAccRandomPasswordDataSourceConfig_basic() string {
return `
data "aws_secretsmanager_random_password" "test" {
password_length = 40
}
`
}

func testAccRandomPasswordDataSourceConfig_exclude() string {
return `
data "aws_secretsmanager_random_password" "test" {
password_length = 40
exclude_numbers = true
exclude_uppercase = true
exclude_punctuation = true
}
`
}
35 changes: 35 additions & 0 deletions website/docs/d/secretsmanager_random_password.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
subcategory: "Secrets Manager"
layout: "aws"
page_title: "AWS: aws_secretsmanager_random_password"
description: |-
Generate a random password
---

# Data Source: aws_secretsmanager_random_password

Generate a random password.

## Example Usage

```terraform
data "aws_secretsmanager_random_password" "test" {
password_length = 50
exclude_numbers = true
}
```

## Argument Reference

* `exclude_characters` - (Optional) A string of the characters that you don't want in the password.
* `exclude_lowercase` - (Optional) Specifies whether to exclude lowercase letters from the password.
* `exclude_numbers` - (Optional) Specifies whether to exclude numbers from the password.
* `exclude_punctuation` - (Optional) Specifies whether to exclude the following punctuation characters from the password: ``! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ .``
* `exclude_uppercase` - (Optional) Specifies whether to exclude uppercase letters from the password.
* `include_space` - (Optional) Specifies whether to include the space character.
* `password_length` - (Optional) The length of the password.
* `require_each_included_type` - (Optional) Specifies whether to include at least one upper and lowercase letter, one number, and one punctuation.

## Attributes Reference

* `random_password` - The random password.