-
Notifications
You must be signed in to change notification settings - Fork 9.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20877 from kamilturek/f-data_source_aws_iam_users
New Data Source: aws_iam_users
- Loading branch information
Showing
5 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-data-source | ||
aws_iam_users | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/iam" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
) | ||
|
||
func dataSourceAwsIAMUsers() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsIAMUsersRead, | ||
Schema: map[string]*schema.Schema{ | ||
"arns": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"name_regex": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringIsValidRegExp, | ||
}, | ||
"names": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"path_prefix": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsIAMUsersRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).iamconn | ||
|
||
input := &iam.ListUsersInput{} | ||
|
||
if v, ok := d.GetOk("path_prefix"); ok { | ||
input.PathPrefix = aws.String(v.(string)) | ||
} | ||
|
||
var results []*iam.User | ||
|
||
err := conn.ListUsersPages(input, func(page *iam.ListUsersOutput, lastPage bool) bool { | ||
if page == nil { | ||
return !lastPage | ||
} | ||
|
||
for _, user := range page.Users { | ||
if user == nil { | ||
continue | ||
} | ||
|
||
if v, ok := d.GetOk("name_regex"); ok && !regexp.MustCompile(v.(string)).MatchString(aws.StringValue(user.UserName)) { | ||
continue | ||
} | ||
|
||
results = append(results, user) | ||
} | ||
|
||
return !lastPage | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading IAM users: %w", err) | ||
} | ||
|
||
d.SetId(meta.(*AWSClient).region) | ||
|
||
var arns, names []string | ||
|
||
for _, r := range results { | ||
names = append(names, aws.StringValue(r.UserName)) | ||
arns = append(arns, aws.StringValue(r.Arn)) | ||
} | ||
|
||
if err := d.Set("names", names); err != nil { | ||
return fmt.Errorf("error setting names: %w", err) | ||
} | ||
|
||
if err := d.Set("arns", arns); err != nil { | ||
return fmt.Errorf("error setting arns: %w", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/iam" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
) | ||
|
||
func TestAccAWSIAMUsersDataSource_nameRegex(t *testing.T) { | ||
dataSourceName := "data.aws_iam_users.test" | ||
rCount := strconv.Itoa(acctest.RandIntRange(1, 4)) | ||
rName := acctest.RandomWithPrefix("tf-acc-test") | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, iam.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSIAMUsersConfigDataSource_nameRegex(rCount, rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(dataSourceName, "names.#", rCount), | ||
resource.TestCheckResourceAttr(dataSourceName, "arns.#", rCount), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSIAMUsersDataSource_pathPrefix(t *testing.T) { | ||
dataSourceName := "data.aws_iam_users.test" | ||
rCount := strconv.Itoa(acctest.RandIntRange(1, 4)) | ||
rName := acctest.RandomWithPrefix("tf-acc-test") | ||
rPathPrefix := acctest.RandomWithPrefix("tf-acc-path") | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, iam.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSIAMUsersConfigDataSource_pathPrefix(rCount, rName, rPathPrefix), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(dataSourceName, "names.#", rCount), | ||
resource.TestCheckResourceAttr(dataSourceName, "arns.#", rCount), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSIAMUsersDataSource_nonExistentNameRegex(t *testing.T) { | ||
dataSourceName := "data.aws_iam_users.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, iam.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSIAMUsersConfigDataSource_nonExistentNameRegex, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(dataSourceName, "names.#", "0"), | ||
resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSIAMUsersDataSource_nonExistentPathPrefix(t *testing.T) { | ||
dataSourceName := "data.aws_iam_users.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
ErrorCheck: testAccErrorCheck(t, iam.EndpointsID), | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSIAMUsersConfigDataSource_nonExistentPathPrefix, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(dataSourceName, "names.#", "0"), | ||
resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccAWSIAMUsersConfigDataSource_nameRegex(rCount, rName string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_iam_user" "test" { | ||
count = %[1]q | ||
name = "%[2]s-${count.index}-user" | ||
tags = { | ||
Seed = %[2]q | ||
} | ||
} | ||
data "aws_iam_users" "test" { | ||
name_regex = "${aws_iam_user.test[0].tags["Seed"]}-.*-user" | ||
} | ||
`, rCount, rName) | ||
} | ||
|
||
func testAccAWSIAMUsersConfigDataSource_pathPrefix(rCount, rName, rPathPrefix string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_iam_user" "test" { | ||
count = %[1]q | ||
name = "%[2]s-${count.index}-user" | ||
path = "/%[3]s/" | ||
} | ||
data "aws_iam_users" "test" { | ||
path_prefix = aws_iam_user.test[0].path | ||
} | ||
`, rCount, rName, rPathPrefix) | ||
} | ||
|
||
const testAccAWSIAMUsersConfigDataSource_nonExistentNameRegex = ` | ||
data "aws_iam_users" "test" { | ||
name_regex = "dne-regex" | ||
} | ||
` | ||
|
||
const testAccAWSIAMUsersConfigDataSource_nonExistentPathPrefix = ` | ||
data "aws_iam_users" "test" { | ||
path_prefix = "/dne/path" | ||
} | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
--- | ||
subcategory: "IAM" | ||
layout: "aws" | ||
page_title: "AWS: aws_iam_users" | ||
description: |- | ||
Get information about a set of IAM Users. | ||
--- | ||
|
||
# Data Source: aws_iam_users | ||
|
||
Use this data source to get the ARNs and Names of IAM Users. | ||
|
||
## Example Usage | ||
|
||
### All users in an account | ||
|
||
```terraform | ||
data "aws_iam_users" "users" {} | ||
``` | ||
|
||
### Users filtered by name regex | ||
|
||
Users whose username contains `abc` | ||
|
||
```terraform | ||
data "aws_iam_users" "users" { | ||
name_regex = ".*abc.*" | ||
} | ||
``` | ||
|
||
### Users filtered by path prefix | ||
|
||
```terraform | ||
data "aws_iam_users" "users" { | ||
path_prefix = "/custom-path" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `name_regex` - (Optional) A regex string to apply to the IAM users list returned by AWS. This allows more advanced filtering not supported from the AWS API. | ||
This filtering is done locally on what AWS returns, and could have a performance impact if the result is large. It is recommended to combine this with other | ||
options to narrow down the list AWS returns. | ||
* `path_prefix` - (Optional) The path prefix for filtering the results. For example, the prefix `/division_abc/subdivision_xyz/` gets all users whose path starts with `/division_abc/subdivision_xyz/`. If it is not included, it defaults to a slash (`/`), listing all users. For more details, check out [list-users in the AWS CLI reference][1]. | ||
|
||
## Attributes Reference | ||
|
||
* `arns` - Set of ARNs of the matched IAM users. | ||
* `names` - Set of Names of the matched IAM users. | ||
|
||
[1]: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/list-users.html |