From 346d166692ee590e7c6c9f1f7db17c1037dcbc1f Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 22:20:33 +1000 Subject: [PATCH 1/7] added account data source and tests --- .../service/account/account_data_source.go | 100 ++++++++++++++++++ .../account/account_data_source_test.go | 79 ++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 internal/service/account/account_data_source.go create mode 100644 internal/service/account/account_data_source_test.go diff --git a/internal/service/account/account_data_source.go b/internal/service/account/account_data_source.go new file mode 100644 index 000000000000..3287594864d6 --- /dev/null +++ b/internal/service/account/account_data_source.go @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package account + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/account" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + "github.com/hashicorp/terraform-provider-aws/internal/smerr" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource("aws_account_account", name="Account") +func newAccountDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceAccount{}, nil +} + +const ( + DSNameAccount = "Account Data Source" +) + +type dataSourceAccount struct { + framework.DataSourceWithModel[dataSourceAccountModel] +} + +func (d *dataSourceAccount) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "account_created_date": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + names.AttrAccountID: schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "account_name": schema.StringAttribute{ + Computed: true, + }, + }, + } +} + +func (d *dataSourceAccount) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().AccountClient(ctx) + + // TIP: -- 2. Fetch the config + var data dataSourceAccountModel + smerr.EnrichAppend(ctx, &resp.Diagnostics, req.Config.Get(ctx, &data)) + if resp.Diagnostics.HasError() { + return + } + + out, err := findAccountInformation(ctx, conn, data.AccountID.ValueString()) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID) + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, flex.Flatten(ctx, out, &data, flex.WithFieldNamePrefix("Account")), smerr.ID) + if resp.Diagnostics.HasError() { + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, resp.State.Set(ctx, &data), smerr.ID) +} + +type dataSourceAccountModel struct { + AccountCreatedDate timetypes.RFC3339 `tfsdk:"account_created_date"` + AccountID types.String `tfsdk:"account_id"` + AccountName types.String `tfsdk:"account_name"` +} + +func findAccountInformation(ctx context.Context, conn *account.Client, accountID string) (*account.GetAccountInformationOutput, error) { + input := account.GetAccountInformationInput{} + if accountID != "" { + input.AccountId = aws.String(accountID) + } + + output, err := conn.GetAccountInformation(ctx, &input) + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} diff --git a/internal/service/account/account_data_source_test.go b/internal/service/account/account_data_source_test.go new file mode 100644 index 000000000000..61941a381180 --- /dev/null +++ b/internal/service/account/account_data_source_test.go @@ -0,0 +1,79 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package account_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func testAccAccountDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + dataSourceName := "data.aws_account_account.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.AccountServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccAccountDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, names.AttrAccountID), + resource.TestCheckResourceAttrSet(dataSourceName, "account_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "account_created_date"), + ), + }, + }, + }) +} + +func testAccAccountDataSource_accountID(t *testing.T) { + ctx := acctest.Context(t) + dataSourceName := "data.aws_account_account.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckAlternateAccount(t) + acctest.PreCheckOrganizationManagementAccount(ctx, t) + acctest.PreCheckOrganizationsEnabledServicePrincipal(ctx, t, "account.amazonaws.com") + }, + ErrorCheck: acctest.ErrorCheck(t, names.AccountServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5FactoriesAlternate(ctx, t), + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccAccountDataSourceConfig_organization(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, names.AttrAccountID), + resource.TestCheckResourceAttrSet(dataSourceName, "account_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "account_created_date"), + ), + }, + }, + }) +} + +func testAccAccountDataSourceConfig_basic() string { + return ` +data "aws_account_account" "test" {} +` +} + +func testAccAccountDataSourceConfig_organization() string { + return acctest.ConfigCompose(acctest.ConfigAlternateAccountProvider(), ` +data "aws_caller_identity" "test" { + provider = "awsalternate" +} + +data "aws_account_account" "test" { + account_id = data.aws_caller_identity.test.account_id +} +`) +} From fbfd73a8445973c7ccd79c9ad2a00ab2246bf92f Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 22:21:14 +1000 Subject: [PATCH 2/7] make gen and serial test updated --- internal/service/account/account_test.go | 4 ++++ internal/service/account/service_package_gen.go | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/internal/service/account/account_test.go b/internal/service/account/account_test.go index dfd976db9bd5..9ce43d4d6832 100644 --- a/internal/service/account/account_test.go +++ b/internal/service/account/account_test.go @@ -13,6 +13,10 @@ func TestAccAccount_serial(t *testing.T) { t.Parallel() testCases := map[string]map[string]func(t *testing.T){ + "Account": { + "dataSourceBasic": testAccAccountDataSource_basic, + "dataSourceAccountID": testAccAccountDataSource_accountID, + }, "AlternateContact": { acctest.CtBasic: testAccAlternateContact_basic, acctest.CtDisappears: testAccAlternateContact_disappears, diff --git a/internal/service/account/service_package_gen.go b/internal/service/account/service_package_gen.go index e2b4451fd74f..86ad6ac855fd 100644 --- a/internal/service/account/service_package_gen.go +++ b/internal/service/account/service_package_gen.go @@ -20,6 +20,12 @@ type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.ServicePackageFrameworkDataSource { return []*inttypes.ServicePackageFrameworkDataSource{ + { + Factory: newAccountDataSource, + TypeName: "aws_account_account", + Name: "Account", + Region: unique.Make(inttypes.ResourceRegionDisabled()), + }, { Factory: newPrimaryContactDataSource, TypeName: "aws_account_primary_contact", From a4d8cdea24e56ca7f1b00464e4e9fa02e73bc4d6 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 22:21:41 +1000 Subject: [PATCH 3/7] added documentation --- website/docs/d/account_account.html.markdown | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 website/docs/d/account_account.html.markdown diff --git a/website/docs/d/account_account.html.markdown b/website/docs/d/account_account.html.markdown new file mode 100644 index 000000000000..201332a2a3b0 --- /dev/null +++ b/website/docs/d/account_account.html.markdown @@ -0,0 +1,41 @@ +--- +subcategory: "Account Management" +layout: "aws" +page_title: "AWS: aws_account_account" +description: |- + Provides details about an AWS Account. +--- + +# Data Source: aws_account_account + +Provides the account information about an AWS Account. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_account_account" "example" { +} +``` + +### Organization Management Account Usage + +```terraform +data "aws_account_account" "example" { + account_id = "123456789000" +} +``` + +## Argument Reference + +The following arguments are optional: + +* `account_id` - (Optional) The ID of the target account when managing member accounts. The caller must be an identity in the organization's management account or a delegated administrator account. It will return current user's account by default if omitted. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `account_name` - The name of the account. +* `account_created_date` - The date and time the account was created. From 334b9cbd22a2ccc65eb93afc20289f13d65b0d90 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 22:21:53 +1000 Subject: [PATCH 4/7] added changelog --- .changelog/44085.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/44085.txt diff --git a/.changelog/44085.txt b/.changelog/44085.txt new file mode 100644 index 000000000000..06fd1f2acf19 --- /dev/null +++ b/.changelog/44085.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_account_account +``` \ No newline at end of file From 081c052ff142bbf9735c91538ea94b548a2c3ce2 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 23:00:07 +1000 Subject: [PATCH 5/7] added semgrep exceptions --- internal/service/account/account_data_source.go | 8 ++------ internal/service/account/account_data_source_test.go | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/internal/service/account/account_data_source.go b/internal/service/account/account_data_source.go index 3287594864d6..e724bbb8cb1b 100644 --- a/internal/service/account/account_data_source.go +++ b/internal/service/account/account_data_source.go @@ -20,14 +20,10 @@ import ( ) // @FrameworkDataSource("aws_account_account", name="Account") -func newAccountDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { +func newAccountDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { // nosemgrep:ci.account-in-func-name return &dataSourceAccount{}, nil } -const ( - DSNameAccount = "Account Data Source" -) - type dataSourceAccount struct { framework.DataSourceWithModel[dataSourceAccountModel] } @@ -80,7 +76,7 @@ type dataSourceAccountModel struct { AccountName types.String `tfsdk:"account_name"` } -func findAccountInformation(ctx context.Context, conn *account.Client, accountID string) (*account.GetAccountInformationOutput, error) { +func findAccountInformation(ctx context.Context, conn *account.Client, accountID string) (*account.GetAccountInformationOutput, error) { // nosemgrep:ci.account-in-func-name input := account.GetAccountInformationInput{} if accountID != "" { input.AccountId = aws.String(accountID) diff --git a/internal/service/account/account_data_source_test.go b/internal/service/account/account_data_source_test.go index 61941a381180..fafc1ef4de67 100644 --- a/internal/service/account/account_data_source_test.go +++ b/internal/service/account/account_data_source_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -func testAccAccountDataSource_basic(t *testing.T) { +func testAccAccountDataSource_basic(t *testing.T) { // nosemgrep:ci.account-in-func-name ctx := acctest.Context(t) dataSourceName := "data.aws_account_account.test" @@ -33,7 +33,7 @@ func testAccAccountDataSource_basic(t *testing.T) { }) } -func testAccAccountDataSource_accountID(t *testing.T) { +func testAccAccountDataSource_accountID(t *testing.T) { // nosemgrep:ci.account-in-func-name ctx := acctest.Context(t) dataSourceName := "data.aws_account_account.test" From 5a7455cdb16290371a643a3deddf046254ffa111 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 23:05:01 +1000 Subject: [PATCH 6/7] one more semgrep exception --- internal/service/account/account_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/account/account_data_source_test.go b/internal/service/account/account_data_source_test.go index fafc1ef4de67..8d5ed51333a7 100644 --- a/internal/service/account/account_data_source_test.go +++ b/internal/service/account/account_data_source_test.go @@ -60,7 +60,7 @@ func testAccAccountDataSource_accountID(t *testing.T) { // nosemgrep:ci.account- }) } -func testAccAccountDataSourceConfig_basic() string { +func testAccAccountDataSourceConfig_basic() string { // nosemgrep:ci.account-in-func-name return ` data "aws_account_account" "test" {} ` From cbce3c26478e4e74b37e95fd4914e0c9867d7271 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Fri, 29 Aug 2025 23:17:05 +1000 Subject: [PATCH 7/7] one more semgrep exception --- internal/service/account/account_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/account/account_data_source_test.go b/internal/service/account/account_data_source_test.go index 8d5ed51333a7..7c60e566597e 100644 --- a/internal/service/account/account_data_source_test.go +++ b/internal/service/account/account_data_source_test.go @@ -66,7 +66,7 @@ data "aws_account_account" "test" {} ` } -func testAccAccountDataSourceConfig_organization() string { +func testAccAccountDataSourceConfig_organization() string { // nosemgrep:ci.account-in-func-name return acctest.ConfigCompose(acctest.ConfigAlternateAccountProvider(), ` data "aws_caller_identity" "test" { provider = "awsalternate"