Skip to content

Commit

Permalink
Merge pull request #39826 from hashicorp/f-lakeformation-lake-setting…
Browse files Browse the repository at this point in the history
…s-parameters

lf/settings: Add `parameters` map argument to support `CROSS_ACCOUNT_VERSION`
  • Loading branch information
YakDriver authored Oct 22, 2024
2 parents c90ccb5 + b819c25 commit bce1b18
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 38 deletions.
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
20 changes: 13 additions & 7 deletions internal/service/lakeformation/data_lake_settings_data_source.go
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

0 comments on commit bce1b18

Please sign in to comment.