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

lf/settings: Add parameters map argument to support CROSS_ACCOUNT_VERSION #39826

Merged
merged 10 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions .changelog/39826.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_lakeformation_data_lake_settings: Add `parameters` map argument enabling `CROSS_ACCOUNT_VERSION` to be set
```

```release-note:enhancement
data-source/aws_lakeformation_data_lake_settings: Add `parameters` map attribute to read `CROSS_ACCOUNT_VERSION`
```
77 changes: 57 additions & 20 deletions internal/service/lakeformation/data_lake_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ func ResourceDataLakeSettings() *schema.Resource {
},

Schema: map[string]*schema.Schema{
// admins
// allow_external_data_filtering
// allow_full_table_external_data_access
// authorized_session_tag_value_list
// catalog_id
// create_database_default_permissions
// create_table_default_permissions
// external_data_filtering_allow_list
// parameters
// read_only_admins
// trusted_resource_owners
"admins": {
Type: schema.TypeSet,
Computed: true,
Expand All @@ -48,15 +59,6 @@ func ResourceDataLakeSettings() *schema.Resource {
ValidateFunc: verify.ValidARN,
},
},
"read_only_admins": {
Type: schema.TypeSet,
Computed: true,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: verify.ValidARN,
},
},
"allow_external_data_filtering": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -135,6 +137,32 @@ func ResourceDataLakeSettings() *schema.Resource {
ValidateFunc: validPrincipal,
},
},
names.AttrParameters: {
Type: schema.TypeMap,
Computed: true,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
// In fresh account, with empty config, API returns map[CROSS_ACCOUNT_VERSION:1 SET_CONTEXT:TRUE] by default
if k == "parameters.SET_CONTEXT" && old == "TRUE" && new == "" {
return true
}
if k == "parameters.CROSS_ACCOUNT_VERSION" && old == "1" && new == "" {
return true
}

return old == new
},
},
"read_only_admins": {
Type: schema.TypeSet,
Computed: true,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: verify.ValidARN,
},
},
"trusted_resource_owners": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -164,14 +192,14 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
settings.DataLakeAdmins = expandDataLakeSettingsAdmins(v.(*schema.Set))
}

if v, ok := d.GetOk("read_only_admins"); ok {
settings.ReadOnlyAdmins = expandDataLakeSettingsAdmins(v.(*schema.Set))
}

if v, ok := d.GetOk("allow_external_data_filtering"); ok {
settings.AllowExternalDataFiltering = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("allow_full_table_external_data_access"); ok {
settings.AllowFullTableExternalDataAccess = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("authorized_session_tag_value_list"); ok {
settings.AuthorizedSessionTagValueList = flex.ExpandStringValueList(v.([]interface{}))
}
Expand All @@ -188,12 +216,16 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
settings.ExternalDataFilteringAllowList = expandDataLakeSettingsDataFilteringAllowList(v.(*schema.Set))
}

if v, ok := d.GetOk("trusted_resource_owners"); ok {
settings.TrustedResourceOwners = flex.ExpandStringValueList(v.([]interface{}))
if v, ok := d.GetOk(names.AttrParameters); ok {
settings.Parameters = flex.ExpandStringValueMap(v.(map[string]interface{}))
}

if v, ok := d.GetOk("allow_full_table_external_data_access"); ok {
settings.AllowFullTableExternalDataAccess = aws.Bool(v.(bool))
if v, ok := d.GetOk("read_only_admins"); ok {
settings.ReadOnlyAdmins = expandDataLakeSettingsAdmins(v.(*schema.Set))
}

if v, ok := d.GetOk("trusted_resource_owners"); ok {
settings.TrustedResourceOwners = flex.ExpandStringValueList(v.([]interface{}))
}

input.DataLakeSettings = settings
Expand Down Expand Up @@ -262,14 +294,15 @@ func resourceDataLakeSettingsRead(ctx context.Context, d *schema.ResourceData, m
settings := output.DataLakeSettings

d.Set("admins", flattenDataLakeSettingsAdmins(settings.DataLakeAdmins))
d.Set("read_only_admins", flattenDataLakeSettingsAdmins(settings.ReadOnlyAdmins))
d.Set("allow_external_data_filtering", settings.AllowExternalDataFiltering)
d.Set("allow_full_table_external_data_access", settings.AllowFullTableExternalDataAccess)
d.Set("authorized_session_tag_value_list", flex.FlattenStringValueList(settings.AuthorizedSessionTagValueList))
d.Set("create_database_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateDatabaseDefaultPermissions))
d.Set("create_table_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateTableDefaultPermissions))
d.Set("external_data_filtering_allow_list", flattenDataLakeSettingsDataFilteringAllowList(settings.ExternalDataFilteringAllowList))
d.Set(names.AttrParameters, flex.FlattenStringValueMap(settings.Parameters))
d.Set("read_only_admins", flattenDataLakeSettingsAdmins(settings.ReadOnlyAdmins))
d.Set("trusted_resource_owners", flex.FlattenStringValueList(settings.TrustedResourceOwners))
d.Set("allow_full_table_external_data_access", settings.AllowFullTableExternalDataAccess)

return diags
}
Expand All @@ -284,7 +317,11 @@ func resourceDataLakeSettingsDelete(ctx context.Context, d *schema.ResourceData,
CreateTableDefaultPermissions: make([]awstypes.PrincipalPermissions, 0),
DataLakeAdmins: make([]awstypes.DataLakePrincipal, 0),
ReadOnlyAdmins: make([]awstypes.DataLakePrincipal, 0),
TrustedResourceOwners: make([]string, 0),
Parameters: map[string]string{ // In fresh account, with empty config, API returns map[CROSS_ACCOUNT_VERSION:1 SET_CONTEXT:TRUE] by default
"CROSS_ACCOUNT_VERSION": "1",
"SET_CONTEXT": "TRUE",
},
TrustedResourceOwners: make([]string, 0),
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ func DataSourceDataLakeSettings() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"read_only_admins": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"allow_external_data_filtering": {
Type: schema.TypeBool,
Computed: true,
Expand Down Expand Up @@ -93,6 +88,16 @@ func DataSourceDataLakeSettings() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
names.AttrParameters: {
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"read_only_admins": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"trusted_resource_owners": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -132,14 +137,15 @@ func dataSourceDataLakeSettingsRead(ctx context.Context, d *schema.ResourceData,
settings := output.DataLakeSettings

d.Set("admins", flattenDataLakeSettingsAdmins(settings.DataLakeAdmins))
d.Set("read_only_admins", flattenDataLakeSettingsAdmins(settings.ReadOnlyAdmins))
d.Set("allow_external_data_filtering", settings.AllowExternalDataFiltering)
d.Set("allow_full_table_external_data_access", settings.AllowFullTableExternalDataAccess)
d.Set("authorized_session_tag_value_list", flex.FlattenStringValueList(settings.AuthorizedSessionTagValueList))
d.Set("create_database_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateDatabaseDefaultPermissions))
d.Set("create_table_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateTableDefaultPermissions))
d.Set("external_data_filtering_allow_list", flattenDataLakeSettingsDataFilteringAllowList(settings.ExternalDataFilteringAllowList))
d.Set(names.AttrParameters, flex.FlattenStringValueMap(settings.Parameters))
d.Set("read_only_admins", flattenDataLakeSettingsAdmins(settings.ReadOnlyAdmins))
d.Set("trusted_resource_owners", flex.FlattenStringyValueList(settings.TrustedResourceOwners))
d.Set("allow_full_table_external_data_access", settings.AllowFullTableExternalDataAccess)

return diags
}
74 changes: 74 additions & 0 deletions internal/service/lakeformation/data_lake_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,53 @@ func testAccDataLakeSettings_readOnlyAdmins(t *testing.T) {
})
}

func testAccDataLakeSettings_parameters(t *testing.T) {
ctx := acctest.Context(t)
resourceName := "aws_lakeformation_data_lake_settings.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.LakeFormationServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckDataLakeSettingsDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccDataLakeSettingsConfig_parametersEmpty(),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataLakeSettingsExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "parameters.%", acctest.Ct2), // In fresh account, with empty config, API returns map[CROSS_ACCOUNT_VERSION:1 SET_CONTEXT:TRUE]
resource.TestCheckResourceAttr(resourceName, "parameters.SET_CONTEXT", acctest.CtTrueCaps),
resource.TestCheckResourceAttr(resourceName, "parameters.CROSS_ACCOUNT_VERSION", acctest.Ct1),
),
},
{
Config: testAccDataLakeSettingsConfig_parameters("CROSS_ACCOUNT_VERSION", acctest.Ct3),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataLakeSettingsExists(ctx, resourceName),
// resource.TestCheckResourceAttr(resourceName, "parameters.%", acctest.Ct2), // this is 2 because SET_CONTEXT:TRUE is here but it's not important for the test and if AWS changes things and adds more parameters, this test would fail
resource.TestCheckResourceAttr(resourceName, "parameters.CROSS_ACCOUNT_VERSION", acctest.Ct3),
),
},
{
Config: testAccDataLakeSettingsConfig_parameters("CROSS_ACCOUNT_VERSION", acctest.Ct1),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataLakeSettingsExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "parameters.CROSS_ACCOUNT_VERSION", acctest.Ct1),
),
},
{
Config: testAccDataLakeSettingsConfig_parametersEmpty(),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataLakeSettingsExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "parameters.%", acctest.Ct2), // In fresh account, with empty config, API returns map[CROSS_ACCOUNT_VERSION:1 SET_CONTEXT:TRUE]
resource.TestCheckResourceAttr(resourceName, "parameters.SET_CONTEXT", acctest.CtTrueCaps),
resource.TestCheckResourceAttr(resourceName, "parameters.CROSS_ACCOUNT_VERSION", acctest.Ct1),
),
},
},
})
}

func testAccCheckDataLakeSettingsDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).LakeFormationClient(ctx)
Expand Down Expand Up @@ -240,3 +287,30 @@ resource "aws_lakeformation_data_lake_settings" "test" {
read_only_admins = [data.aws_iam_session_context.current.issuer_arn]
}
`

func testAccDataLakeSettingsConfig_parametersEmpty() string {
return `
data "aws_caller_identity" "current" {}

resource "aws_lakeformation_data_lake_settings" "test" {
catalog_id = data.aws_caller_identity.current.account_id

parameters = {
}
}
`
}

func testAccDataLakeSettingsConfig_parameters(key1, value1 string) string {
return fmt.Sprintf(`
data "aws_caller_identity" "current" {}

resource "aws_lakeformation_data_lake_settings" "test" {
catalog_id = data.aws_caller_identity.current.account_id

parameters = {
%[1]q = %[2]q
}
}
`, key1, value1)
}
1 change: 1 addition & 0 deletions internal/service/lakeformation/lakeformation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestAccLakeFormation_serial(t *testing.T) {
acctest.CtDisappears: testAccDataLakeSettings_disappears,
"withoutCatalogId": testAccDataLakeSettings_withoutCatalogID,
"readOnlyAdmins": testAccDataLakeSettings_readOnlyAdmins,
"parameters": testAccDataLakeSettings_parameters,
},
"DataCellsFilter": {
acctest.CtBasic: testAccDataCellsFilter_basic,
Expand Down
11 changes: 6 additions & 5 deletions website/docs/d/lakeformation_data_lake_settings.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ The following arguments are optional:
This data source exports the following attributes in addition to the arguments above:

* `admins` – List of ARNs of AWS Lake Formation principals (IAM users or roles).
* `read_only_admins` – List of ARNs of AWS Lake Formation principals (IAM users or roles) with only view access to the resources.
* `allow_external_data_filtering` - Whether to allow Amazon EMR clusters to access data managed by Lake Formation.
* `allow_full_table_external_data_access` - Whether to allow a third-party query engine to get data access credentials without session tags when a caller has full data access permissions.
* `authorized_session_tag_value_list` - Lake Formation relies on a privileged process secured by Amazon EMR or the third party integrator to tag the user's role while assuming it.
* `create_database_default_permissions` - Up to three configuration blocks of principal permissions for default create database permissions. Detailed below.
* `create_table_default_permissions` - Up to three configuration blocks of principal permissions for default create table permissions. Detailed below.
* `trusted_resource_owners` – List of the resource-owning account IDs that the caller's account can use to share their user access details (user ARNs).
* `allow_external_data_filtering` - Whether to allow Amazon EMR clusters to access data managed by Lake Formation.
* `external_data_filtering_allow_list` - A list of the account IDs of Amazon Web Services accounts with Amazon EMR clusters that are to perform data filtering.
* `authorized_session_tag_value_list` - Lake Formation relies on a privileged process secured by Amazon EMR or the third party integrator to tag the user's role while assuming it.
* `allow_full_table_external_data_access` - Whether to allow a third-party query engine to get data access credentials without session tags when a caller has full data access permissions.
* `parameters` - Key-value map of additional configuration. `CROSS_ACCOUNT_VERSION` will be set to values `"1"`, `"2"`, `"3"`, or `"4"`. `SET_CONTEXT` will also be returned with a value of `TRUE`. In a fresh account, prior to configuring, `CROSS_ACCOUNT_VERSION` is `"1"`.
* `read_only_admins` – List of ARNs of AWS Lake Formation principals (IAM users or roles) with only view access to the resources.
* `trusted_resource_owners` – List of the resource-owning account IDs that the caller's account can use to share their user access details (user ARNs).

### create_database_default_permissions

Expand Down
23 changes: 17 additions & 6 deletions website/docs/r/lakeformation_data_lake_settings.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,33 @@ resource "aws_lakeformation_data_lake_settings" "example" {
}
```

### Change Cross Account Version

```terraform
resource "aws_lakeformation_data_lake_settings" "example" {
parameters = {
"CROSS_ACCOUNT_VERSION" = "3"
}
}
```

## Argument Reference

The following arguments are optional:

* `admins` – (Optional) Set of ARNs of AWS Lake Formation principals (IAM users or roles).
* `read_only_admins` – (Optional) Set of ARNs of AWS Lake Formation principals (IAM users or roles) with only view access to the resources.
* `allow_external_data_filtering` - (Optional) Whether to allow Amazon EMR clusters to access data managed by Lake Formation.
* `allow_full_table_external_data_access` - (Optional) Whether to allow a third-party query engine to get data access credentials without session tags when a caller has full data access permissions.
* `authorized_session_tag_value_list` - (Optional) Lake Formation relies on a privileged process secured by Amazon EMR or the third party integrator to tag the user's role while assuming it.
* `catalog_id` – (Optional) Identifier for the Data Catalog. By default, the account ID.
* `create_database_default_permissions` - (Optional) Up to three configuration blocks of principal permissions for default create database permissions. Detailed below.
* `create_table_default_permissions` - (Optional) Up to three configuration blocks of principal permissions for default create table permissions. Detailed below.
* `trusted_resource_owners` – (Optional) List of the resource-owning account IDs that the caller's account can use to share their user access details (user ARNs).
* `allow_external_data_filtering` - (Optional) Whether to allow Amazon EMR clusters to access data managed by Lake Formation.
* `external_data_filtering_allow_list` - (Optional) A list of the account IDs of Amazon Web Services accounts with Amazon EMR clusters that are to perform data filtering.
* `authorized_session_tag_value_list` - (Optional) Lake Formation relies on a privileged process secured by Amazon EMR or the third party integrator to tag the user's role while assuming it.
* `allow_full_table_external_data_access` - (Optional) Whether to allow a third-party query engine to get data access credentials without session tags when a caller has full data access permissions.
* `parameters` - Key-value map of additional configuration. Valid values for the `CROSS_ACCOUNT_VERSION` key are `"1"`, `"2"`, `"3"`, or `"4"`. `SET_CONTEXT` is also returned with a value of `TRUE`. In a fresh account, prior to configuring, `CROSS_ACCOUNT_VERSION` is `"1"`. Destroying this resource sets the `CROSS_ACCOUNT_VERSION` to `"1"`.
* `read_only_admins` – (Optional) Set of ARNs of AWS Lake Formation principals (IAM users or roles) with only view access to the resources.
* `trusted_resource_owners` – (Optional) List of the resource-owning account IDs that the caller's account can use to share their user access details (user ARNs).

~> **NOTE:** Although optional, not including `admins`, `create_database_default_permissions`, `create_table_default_permissions`, and/or `trusted_resource_owners` results in the setting being cleared.
~> **NOTE:** Although optional, not including `admins`, `create_database_default_permissions`, `create_table_default_permissions`, `parameters`, and/or `trusted_resource_owners` results in the setting being cleared.

### create_database_default_permissions

Expand Down
Loading