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

Add data sources aws_organizations_organizational_unit_child_accounts and aws_organizations_organizational_unit_descendant_accounts #24350

Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
117439f
Add data source aws_organizations_accounts
ebi-yade Apr 6, 2021
8e415e6
Create the documentation of data.aws_organizations_accounts
ebi-yade Apr 13, 2021
4de0df9
Fix indent
ebi-yade Apr 13, 2021
807e19d
Finalize aws_organizations_accounts data source
Oct 8, 2021
a753b82
Merge pull request #1 from mikeroll/f-aws_organizations_accounts
ebi-yade Oct 9, 2021
4dc5ac0
Add ou child accounts data source
ahublersos Apr 18, 2022
c031035
Add ou descendant accounts data source
ahublersos Apr 18, 2022
6d99fba
formatting
ahublersos Apr 20, 2022
4a005dd
Fix timestamp type
ahublersos Apr 20, 2022
31f5446
Fix replace ou variable with new accounts var
ahublersos Apr 20, 2022
5daad8a
convert time type to string
ahublersos Apr 20, 2022
0f10c5a
add new data sources to provider.go
ahublersos Apr 20, 2022
e56398d
update test emails
ahublersos Apr 20, 2022
2ff0fa1
Add documentation
ahublersos Apr 20, 2022
43378bd
remove dupe flatten_accounts function
ahublersos Apr 21, 2022
ae84fd7
remove commented out declaration
ahublersos Apr 21, 2022
a80fe83
rename data source files
ahublersos Apr 21, 2022
d42f207
add checks for each account in acc test
ahublersos Apr 21, 2022
2e4bf84
Use random email addresses in acc test
ahublersos Apr 21, 2022
d83b451
pass random addresses to test config
ahublersos Apr 21, 2022
2ed63ed
formatting
ahublersos Apr 21, 2022
a642996
add fmt package
ahublersos Apr 21, 2022
fed8328
correct test config function name
ahublersos Apr 21, 2022
489e4e7
Update child account tests to use random email.
ahublersos Apr 21, 2022
db483f9
Add changelog
ahublersos Apr 21, 2022
ddd0741
Remove joined_timestamp and joined_method attributes
ahublersos Oct 19, 2022
d127c46
remove duplicate flattenAccounts
ahublersos Oct 19, 2022
96690bd
Providers to ProtoV5ProviderFactories
ahublersos Oct 21, 2022
3566e6a
Revert "Merge pull request #1 from mikeroll/f-aws_organizations_accou…
ewbankkit Feb 16, 2023
be0f383
Revert "Fix indent"
ewbankkit Feb 16, 2023
58b1b8b
Revert "Create the documentation of data.aws_organizations_accounts"
ewbankkit Feb 16, 2023
3539b05
Revert "Add data source aws_organizations_accounts"
ewbankkit Feb 16, 2023
997e8f4
Merge commit '3539b0500cd7ed3384abc9aad157af8ec36ef032' into HEAD
ewbankkit Feb 16, 2023
dd82cfe
Merge branch 'main' into HEAD
ewbankkit Feb 16, 2023
eb00c80
d/aws_organizations_organizational_unit_child_accounts: Convert to 'W…
ewbankkit Feb 16, 2023
2864842
d/aws_organizations_organizational_units: Add 'findOUsForParent'.
ewbankkit Feb 16, 2023
ae7f32a
d/aws_organizations_organizational_unit_child_accounts: Add 'findAcco…
ewbankkit Feb 16, 2023
09cda9e
d/aws_organizations_organizational_unit_descendant_accounts: Convert …
ewbankkit Feb 16, 2023
0b91321
Fix semgrep 'ci.semgrep.migrate.aws-api-context'.
ewbankkit Feb 16, 2023
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
7 changes: 7 additions & 0 deletions .changelog/24350.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:new-data-source
aws_organizations_organizational_unit_child_accounts
```

```release-note:new-data-source
aws_organizations_organizational_unit_descendant_accounts
```
12 changes: 7 additions & 5 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,13 @@ func New(ctx context.Context) (*schema.Provider, error) {

"aws_opensearch_domain": opensearch.DataSourceDomain(),

"aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(),
"aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(),
"aws_organizations_organization": organizations.DataSourceOrganization(),
"aws_organizations_organizational_units": organizations.DataSourceOrganizationalUnits(),
"aws_organizations_resource_tags": organizations.DataSourceResourceTags(),
"aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(),
"aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(),
"aws_organizations_organization": organizations.DataSourceOrganization(),
"aws_organizations_organizational_units": organizations.DataSourceOrganizationalUnits(),
"aws_organizations_organizational_unit_child_accounts": organizations.DataSourceOrganizationalUnitChildAccounts(),
"aws_organizations_organizational_unit_descendant_accounts": organizations.DataSourceOrganizationalUnitDescendantAccounts(),
"aws_organizations_resource_tags": organizations.DataSourceResourceTags(),

"aws_outposts_asset": outposts.DataSourceOutpostAsset(),
"aws_outposts_assets": outposts.DataSourceOutpostAssets(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package organizations

import (
"context"

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

func DataSourceOrganizationalUnitChildAccounts() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourceOrganizationalUnitChildAccountsRead,

Schema: map[string]*schema.Schema{
"accounts": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"email": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"parent_id": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func dataSourceOrganizationalUnitChildAccountsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).OrganizationsConn()

parentID := d.Get("parent_id").(string)
accounts, err := findAccountsForParent(ctx, conn, parentID)

if err != nil {
return sdkdiag.AppendErrorf(diags, "listing Organizations Accounts for parent (%s): %s", parentID, err)
}

d.SetId(parentID)

if err := d.Set("accounts", flattenAccounts(accounts)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting accounts: %s", err)
}

return diags
}

func findAccountsForParent(ctx context.Context, conn *organizations.Organizations, id string) ([]*organizations.Account, error) {
input := &organizations.ListAccountsForParentInput{
ParentId: aws.String(id),
}
var output []*organizations.Account

err := conn.ListAccountsForParentPages(input, func(page *organizations.ListAccountsForParentOutput, lastPage bool) bool {
output = append(output, page.Accounts...)

return !lastPage
})

if err != nil {
return nil, err
}

return output, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package organizations_test

import (
"testing"

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

func testAccOrganizationalUnitChildAccountsDataSource_basic(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_organizations_organizational_unit_child_accounts.test"

resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
acctest.PreCheckOrganizationManagementAccount(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, organizations.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccOrganizationalUnitChildAccountsDataSourceConfig_basic,
Check: resource.ComposeTestCheckFunc(
acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "accounts.#", "0"),
),
},
},
})
}

const testAccOrganizationalUnitChildAccountsDataSourceConfig_basic = `
data "aws_organizations_organization" "current" {}

data "aws_organizations_organizational_unit_child_accounts" "test" {
parent_id = data.aws_organizations_organization.current.roots[0].id
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package organizations

import (
"context"

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

func DataSourceOrganizationalUnitDescendantAccounts() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourceOrganizationalUnitDescendantAccountsRead,

Schema: map[string]*schema.Schema{
"accounts": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"email": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"parent_id": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func dataSourceOrganizationalUnitDescendantAccountsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).OrganizationsConn()

parentID := d.Get("parent_id").(string)
accounts, err := findAllAccountsForParentAndBelow(ctx, conn, parentID)

if err != nil {
return sdkdiag.AppendErrorf(diags, "listing Organizations Accounts for parent (%s) and descendants: %s", parentID, err)
}

d.SetId(parentID)

if err := d.Set("accounts", flattenAccounts(accounts)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting accounts: %s", err)
}

return diags
}

// findAllAccountsForParent recurses down an OU tree, returning all accounts at the specified parent and below.
func findAllAccountsForParentAndBelow(ctx context.Context, conn *organizations.Organizations, id string) ([]*organizations.Account, error) {
var output []*organizations.Account

accounts, err := findAccountsForParent(ctx, conn, id)

if err != nil {
return nil, err
}

output = append(output, accounts...)

ous, err := findOUsForParent(ctx, conn, id)

if err != nil {
return nil, err
}

for _, ou := range ous {
accounts, err = findAllAccountsForParentAndBelow(ctx, conn, aws.StringValue(ou.Id))

if err != nil {
return nil, err
}

output = append(output, accounts...)
}

return output, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package organizations_test

import (
"fmt"
"testing"

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

func testAccOrganizationalUnitDescendantAccountsDataSource_basic(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
topOUDataSourceName := "data.aws_organizations_organizational_unit_descendant_accounts.current"
newOU1DataSourceName := "data.aws_organizations_organizational_unit_descendant_accounts.test0"
newOU2DataSourceName := "data.aws_organizations_organizational_unit_descendant_accounts.test1"

resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
acctest.PreCheckOrganizationManagementAccount(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, organizations.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccOrganizationalUnitDescendantAccountsDataSourceConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
acctest.CheckResourceAttrGreaterThanValue(topOUDataSourceName, "accounts.#", "0"),
resource.TestCheckResourceAttr(newOU1DataSourceName, "accounts.#", "0"),
resource.TestCheckResourceAttr(newOU2DataSourceName, "accounts.#", "0"),
),
},
},
})
}

func testAccOrganizationalUnitDescendantAccountsDataSourceConfig_basic(rName string) string {
return fmt.Sprintf(`
data "aws_organizations_organization" "current" {}

resource "aws_organizations_organizational_unit" "test0" {
name = "%[1]s-0"
parent_id = data.aws_organizations_organization.current.roots[0].id
}

resource "aws_organizations_organizational_unit" "test1" {
name = "%[1]s-1"
parent_id = aws_organizations_organizational_unit.test0.id
}

data "aws_organizations_organizational_unit_descendant_accounts" "current" {
parent_id = data.aws_organizations_organization.current.roots[0].id

depends_on = [aws_organizations_organizational_unit.test0, aws_organizations_organizational_unit.test1]
}

data "aws_organizations_organizational_unit_descendant_accounts" "test0" {
parent_id = aws_organizations_organizational_unit.test0.id

depends_on = [aws_organizations_organizational_unit.test1]
}

data "aws_organizations_organizational_unit_descendant_accounts" "test1" {
parent_id = aws_organizations_organizational_unit.test1.id
}
`, rName)
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,32 +48,39 @@ func dataSourceOrganizationalUnitsRead(ctx context.Context, d *schema.ResourceDa
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).OrganizationsConn()

parent_id := d.Get("parent_id").(string)
parentID := d.Get("parent_id").(string)
children, err := findOUsForParent(ctx, conn, parentID)

params := &organizations.ListOrganizationalUnitsForParentInput{
ParentId: aws.String(parent_id),
if err != nil {
return sdkdiag.AppendErrorf(diags, "listing Organizations Organization Units for parent (%s): %s", parentID, err)
}

var children []*organizations.OrganizationalUnit
d.SetId(parentID)

err := conn.ListOrganizationalUnitsForParentPagesWithContext(ctx, params,
func(page *organizations.ListOrganizationalUnitsForParentOutput, lastPage bool) bool {
children = append(children, page.OrganizationalUnits...)
if err := d.Set("children", FlattenOrganizationalUnits(children)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting children: %s", err)
}

return !lastPage
})
return diags
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "listing Organizations Organization Units for parent (%s): %s", parent_id, err)
func findOUsForParent(ctx context.Context, conn *organizations.Organizations, id string) ([]*organizations.OrganizationalUnit, error) {
input := &organizations.ListOrganizationalUnitsForParentInput{
ParentId: aws.String(id),
}
var output []*organizations.OrganizationalUnit

d.SetId(parent_id)
err := conn.ListOrganizationalUnitsForParentPagesWithContext(ctx, input, func(page *organizations.ListOrganizationalUnitsForParentOutput, lastPage bool) bool {
output = append(output, page.OrganizationalUnits...)

if err := d.Set("children", FlattenOrganizationalUnits(children)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting children: %s", err)
return !lastPage
})

if err != nil {
return nil, err
}

return diags
return output, nil
}

func FlattenOrganizationalUnits(ous []*organizations.OrganizationalUnit) []map[string]interface{} {
Expand Down
Loading