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

EM: Lakeformation for Cloud platform roles #9186

Open
wants to merge 66 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
a9b8f6f
add lake formation permissions to only see current changes
matt-heery Dec 24, 2024
d7bf568
fix: add acutal permissions and reference cols correctly
matt-heery Dec 24, 2024
649ea2b
d
matt-heery Dec 24, 2024
9583e50
no exclusions
matt-heery Dec 24, 2024
9c2c550
remove hidden columns
matt-heery Dec 24, 2024
55060bd
remove deleted
matt-heery Dec 24, 2024
8628844
remove select *
matt-heery Dec 24, 2024
69e59be
bad tf docs
matt-heery Dec 24, 2024
592c42b
forgot to press save
matt-heery Dec 24, 2024
cce7886
reference data filter
matt-heery Dec 24, 2024
0ba3cd4
allow to assume role
matt-heery Dec 24, 2024
ffa3331
update cloud platform policy
matt-heery Dec 24, 2024
57ec8c6
attach policy to role
matt-heery Dec 24, 2024
5547542
adding cadt bucket as the lakefromation resource
matt-heery Dec 24, 2024
b52e900
remove ;
matt-heery Dec 24, 2024
80ed84a
proper syntax
matt-heery Dec 24, 2024
0fd3ede
escape quotes
matt-heery Dec 24, 2024
6a7e7ba
TRUE
matt-heery Dec 24, 2024
91095b9
escape keyword
matt-heery Dec 24, 2024
f15575e
remove cols
matt-heery Dec 24, 2024
6f2f8ea
no excluded cols
matt-heery Dec 24, 2024
8082617
add a space
matt-heery Dec 24, 2024
fe1e529
exclude all cols
matt-heery Dec 24, 2024
1f6128d
remove list
matt-heery Dec 24, 2024
17ce8c6
glue
matt-heery Dec 24, 2024
9bfb9f5
database
matt-heery Dec 24, 2024
67b254d
describe
matt-heery Dec 24, 2024
5e8266d
add get table policy
matt-heery Dec 27, 2024
af4ec65
add de role as super admin
matt-heery Dec 27, 2024
1d22183
add starred databases
matt-heery Dec 27, 2024
1053dd9
all databases
matt-heery Dec 27, 2024
4e7fb1a
add modulisation of lake formation
matt-heery Dec 27, 2024
1656e49
update to key
matt-heery Dec 27, 2024
d7e7146
use single lf resource
matt-heery Dec 27, 2024
940756e
change ref
matt-heery Dec 27, 2024
51cf4fc
missing table
matt-heery Dec 27, 2024
60e4ee3
add lf resource de permissions
matt-heery Dec 27, 2024
39f53f0
add explicit table permissions
matt-heery Dec 27, 2024
6e3fa16
update config for not dev
matt-heery Dec 27, 2024
8086044
clean specials
matt-heery Dec 27, 2024
509b0d6
remove count
matt-heery Dec 27, 2024
f2c7a29
local.
matt-heery Dec 27, 2024
16f445b
empty life
matt-heery Dec 27, 2024
e86aced
parentheses
matt-heery Dec 27, 2024
c338a74
allowing a specials role as well
matt-heery Dec 30, 2024
b4a1921
add no filter
matt-heery Dec 30, 2024
dcbf095
update module to allow for no data filter
matt-heery Dec 30, 2024
332ddad
update filter with all rows wildcard
matt-heery Dec 30, 2024
62f8e3f
adding ap access
matt-heery Dec 30, 2024
4db5748
only for test for now
matt-heery Dec 30, 2024
196cb1e
for each
matt-heery Dec 30, 2024
8a53c31
remove needless secret
matt-heery Dec 30, 2024
039c0c3
remove optional args
matt-heery Dec 30, 2024
6803876
add module
matt-heery Dec 30, 2024
4f66b8b
updated config
matt-heery Dec 30, 2024
6a6c287
update to the correct env_
matt-heery Dec 30, 2024
07e04d9
select only
matt-heery Dec 30, 2024
8fd4712
sandbox
matt-heery Dec 30, 2024
9f11b60
remove dash
matt-heery Dec 30, 2024
0a5042d
add test assume role again
matt-heery Jan 2, 2025
f4b3345
fixes and removal of other bits
matt-heery Jan 2, 2025
08bfa50
random id
matt-heery Jan 2, 2025
e0a695f
fix: remove non-existent bit of code
matt-heery Jan 2, 2025
1a08673
terraform random provider
matt-heery Jan 2, 2025
39d11ad
update names and add AM tables infra
matt-heery Jan 2, 2025
1f3d493
update the specials set up
matt-heery Jan 2, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ module "cmt_front_end_assumable_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
version = "5.48.0"

trusted_role_arns = [
local.resolved-cloud-platform-iam-role
]
trusted_role_arns = flatten([
local.resolved-cloud-platform-iam-role,
data.aws_iam_roles.data_engineering_roles.arns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Learn something new everyday, I didn't realise flatten can work on singular variables too always thought it had to be put as a list of lists!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is a list of lists if not a list of items? ;)

])

create_role = true
role_requires_mfa = false
Expand All @@ -45,7 +46,27 @@ module "cmt_front_end_assumable_role" {
tags = local.tags
}

module "specials_cmt_front_end_assumable_role" {
#checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions
#checkov:skip=CKV_TF_2:Module registry does not support tags for versions
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
version = "5.48.0"

trusted_role_arns = flatten([
local.resolved-cloud-platform-iam-role,
data.aws_iam_roles.data_engineering_roles.arns
])

create_role = true
role_requires_mfa = false

role_name = "specials_cmt_read_emds_data_${local.environment_shorthand}"

tags = local.tags
}

# module "share_api_data_marts" {
# count = local.is-production ? 1 : 0
# #checkov:skip=CKV_TF_1:Module registry does not support commit hashes for versions
# #checkov:skip=CKV_TF_2:Module registry does not support tags for versions
# source = "github.com/ministryofjustice/terraform-aws-analytical-platform-lakeformation?ref=32525da937012178e430585ac5a00f05193f58eb"
Expand All @@ -67,3 +88,77 @@ module "cmt_front_end_assumable_role" {
# aws.destination = aws
# }
# }


data "aws_iam_policy_document" "standard_athena_access" {
statement {
actions = [
"athena:GetDataCatalog",
"athena:GetQueryExecution",
"athena:GetQueryResults",
"athena:GetWorkGroup",
"athena:StartQueryExecution",
"athena:StopQueryExecution"
]
resources = [
"arn:aws:athena:${data.aws_region.current.name}:${local.env_account_id}:*/*"
]
}
statement {
actions = [
"athena:ListWorkGroups"
]
resources = [
"*"
]
}
statement {
actions = ["lakeformation:GetDataAccess"]
resources = ["*"]
}
statement {
actions = [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts"
]
resources = [module.s3-athena-bucket.bucket.arn]
}
statement {
actions = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts"
]
resources = ["${module.s3-athena-bucket.bucket.arn}/*"]
}
statement {
effect = "Allow"
actions = [
"glue:GetDatabases",
"glue:GetDatabase",
"glue:GetTables",
"glue:GetTable"
]
resources = [
"arn:aws:glue:${data.aws_region.current.name}:${local.env_account_id}:catalog",
"arn:aws:glue:${data.aws_region.current.name}:${local.env_account_id}:database/staged_fms_${local.env_}dbt",
"arn:aws:glue:${data.aws_region.current.name}:${local.env_account_id}:table/staged_fms_${local.env_}dbt/*"
]
}
}

resource "aws_iam_policy" "standard_athena_access" {
name_prefix = "standard_athena_access"
description = "Standard permissions for Athena"
policy = data.aws_iam_policy_document.standard_athena_access.json
}

resource "aws_iam_role_policy_attachment" "standard_athena_access" {
policy_arn = aws_iam_policy.standard_athena_access.arn
role = module.cmt_front_end_assumable_role.iam_role_name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
locals {
env_ = "${local.environment_shorthand}_"
cap_dw_tables = local.is-production ? ["contact_history", "equipment_details", "event_history", "incident", "order_details", "services", "suspension_of_visits", "violations", "visit_details"] : []
am_tables = local.is-production ? ["am_contact_history", "am_equipment_details", "am_incident", "am_order_details", "am_services", "am_visit_details"] : []
}

resource "aws_lakeformation_resource" "data_bucket" {
arn = module.s3-create-a-derived-table-bucket.bucket.arn
}

module "share_current_version" {
count = local.is-test ? 1 : 0
source = "./modules/lakeformation"
table_filters = {
"account" = "__current=true"
}
role_arn = module.cmt_front_end_assumable_role.iam_role_arn
database_name = "staged_fms_${local.env_}dbt"
data_engineer_role_arn = try(one(data.aws_iam_roles.data_engineering_roles.arns))
data_bucket_lf_resource = aws_lakeformation_resource.data_bucket.arn
}

module "cap_dw_excluding_specials" {
for_each = toset(local.cap_dw_tables)
source = "./modules/lakeformation"
table_filters = {
(each.key) = "specials_flag=0"
}
role_arn = module.cmt_front_end_assumable_role.iam_role_arn
database_name = "historic_api_mart_historic_dev_dbt"
data_engineer_role_arn = try(one(data.aws_iam_roles.data_engineering_roles.arns))
data_bucket_lf_resource = aws_lakeformation_resource.data_bucket.arn
}

module "cap_dw_including_specials" {
for_each = toset(local.cap_dw_tables)
source = "./modules/lakeformation"
table_filters = {
(each.key) = ""
}
role_arn = module.specials_cmt_front_end_assumable_role.iam_role_arn
database_name = "historic_api_mart_historic_dev_dbt"
data_engineer_role_arn = try(one(data.aws_iam_roles.data_engineering_roles.arns))
data_bucket_lf_resource = aws_lakeformation_resource.data_bucket.arn
}

module "am_for_non_specials_role" {
for_each = toset(local.am_tables)
source = "./modules/lakeformation"
table_filters = {
(each.key) = ""
}
role_arn = module.cmt_front_end_assumable_role.iam_role_arn
database_name = "historic_api_mart_historic_dev_dbt"
data_engineer_role_arn = try(one(data.aws_iam_roles.data_engineering_roles.arns))
data_bucket_lf_resource = aws_lakeformation_resource.data_bucket.arn
}

module "am_for_specials_role" {
for_each = toset(local.am_tables)
source = "./modules/lakeformation"
table_filters = {
(each.key) = ""
}
role_arn = module.specials_cmt_front_end_assumable_role.iam_role_arn
database_name = "historic_api_mart_historic_dev_dbt"
data_engineer_role_arn = try(one(data.aws_iam_roles.data_engineering_roles.arns))
data_bucket_lf_resource = aws_lakeformation_resource.data_bucket.arn
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
data "aws_caller_identity" "current" {}

resource "aws_lakeformation_permissions" "data_engineering_permissions" {
permissions = ["ALL"]
principal = var.data_engineer_role_arn

database {
name = var.database_name
}
}

resource "random_id" "suffix" {
byte_length = 32
}

resource "aws_lakeformation_permissions" "data_engineering_table_permissions" {
for_each = var.table_filters
permissions = ["ALL"]
principal = var.data_engineer_role_arn

table {
database_name = var.database_name
name = each.key
}
}

resource "aws_lakeformation_permissions" "de_s3_bucket_permissions" {
principal = var.data_engineer_role_arn

permissions = ["DATA_LOCATION_ACCESS"]

data_location {
arn = var.data_bucket_lf_resource
}
}

resource "aws_lakeformation_permissions" "s3_bucket_permissions" {
principal = var.role_arn

permissions = ["DATA_LOCATION_ACCESS"]

data_location {
arn = var.data_bucket_lf_resource
}
}

resource "aws_lakeformation_data_cells_filter" "data_filter" {
for_each = tomap(var.table_filters)
table_data {
database_name = var.database_name
name = "filter-${each.key}-${random_id.suffix.hex}"
table_catalog_id = data.aws_caller_identity.current.account_id
table_name = each.key
column_wildcard {
excluded_column_names = []
}
dynamic "row_filter" {
for_each = each.value != "" ? [each.value] : []
content {
filter_expression = each.value
}
}
dynamic "row_filter" {
for_each = each.value == "" ? [each.value] : []
content {
all_rows_wildcard {}
}
}
}
}

resource "aws_lakeformation_permissions" "share_filtered_data_with_role" {
for_each = tomap(var.table_filters)
principal = var.role_arn
permissions = ["DESCRIBE", "SELECT"]
data_cells_filter {
database_name = var.database_name
table_name = each.key
table_catalog_id = data.aws_caller_identity.current.account_id
name = aws_lakeformation_data_cells_filter.data_filter[each.key].table_data[0].name
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
variable "table_filters" {
description = "Map of names of the tables and filters to apply"
type = map(string)
}

variable "database_name" {
description = "Name of the database the table belongs to"
type = string

}

variable "data_engineer_role_arn" {
description = "ARN of the DE role"
type = string
}

variable "data_bucket_lf_resource" {
description = "arn of the lake formation resource for the data bucket"
type = string
}

variable "role_arn" {
description = "Role to grant permissions to"
type = string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
required_version = ">= 1.0.1"
}
Loading