Skip to content

Commit

Permalink
Merge pull request #7090 from ministryofjustice/apdpr4358/share-glue-…
Browse files Browse the repository at this point in the history
…resources-into-analytical-platform

MS037 - Role for Sharing into Analytical Platform
  • Loading branch information
julialawrence authored Jul 18, 2024
2 parents a5f70d3 + f96ce67 commit 8c5e63f
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,21 @@
"enable_cp_bodmis_k8s_secrets": false,
"enable_dbt_k8s_secrets": true,
"dpr_generic_athena_workgroup": true,
"analytics_generic_athena_workgroup": true
"analytics_generic_athena_workgroup": true,
"analytical_platform_share": [{
"target_account_name": "analytical-platform-data-production",
"target_account_id": "593291632749",
"data_locations": [
"dpr-structured-historical-preproduction"
],
"resource_shares": [{
"glue_database": "curated_prisons_history_preprod_dbt",
"glue_tables": [
"nomis_offender_course_attendances",
"nomis_offender_program_profiles"
]
}]
}]
},
"production": {
"project_short_id": "dpr",
Expand Down
11 changes: 9 additions & 2 deletions terraform/environments/digital-prison-reporting/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ data "aws_secretsmanager_secret_version" "dbt_secrets" {
}


# TLS Certificate for OIDC URL, DBT K8s Platform
# TLS Certificate for OIDC URL, DBT K8s Platform
data "tls_certificate" "dbt_analytics" {
url = "https://oidc.eks.eu-west-2.amazonaws.com/id/${jsondecode(data.aws_secretsmanager_secret_version.dbt_secrets.secret_string)["oidc_cluster_identifier"]}"
}
Expand All @@ -116,4 +116,11 @@ data "aws_secretsmanager_secret" "transfer_component_role_secret" {

data "aws_secretsmanager_secret_version" "transfer_component_role_secret_version" {
secret_id = data.aws_secretsmanager_secret.transfer_component_role_secret.id
}
}

# For Lakeformation Management

# Retrieves the source role of terraform's current caller identity
data "aws_iam_session_context" "current" {
arn = data.aws_caller_identity.current.arn
}
16 changes: 16 additions & 0 deletions terraform/environments/digital-prison-reporting/lake_formation.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource "aws_lakeformation_data_lake_settings" "lake_formation" {
admins = flatten([[for share in local.analytical_platform_share : aws_iam_role.analytical_platform_share_role[share.target_account_name].arn], data.aws_iam_session_context.current.issuer_arn])

# ref: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lakeformation_data_lake_settings#principal
create_database_default_permissions {
# These settings should replicate current behaviour: LakeFormation is Ignored
permissions = ["ALL"]
principal = "IAM_ALLOWED_PRINCIPALS"
}

create_table_default_permissions {
# These settings should replicate current behaviour: LakeFormation is Ignored
permissions = ["ALL"]
principal = "IAM_ALLOWED_PRINCIPALS"
}
}
11 changes: 7 additions & 4 deletions terraform/environments/digital-prison-reporting/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,14 @@ locals {
# CW Insights
enable_cw_insights = local.application_data.accounts[local.environment].setup_cw_insights

# Setup Athena Workgroups
# Setup Athena Workgroups
setup_dpr_generic_athena_workgroup = local.application_data.accounts[local.environment].dpr_generic_athena_workgroup
setup_analytics_generic_athena_workgroup = local.application_data.accounts[local.environment].analytics_generic_athena_workgroup

# Sonatype Secrets
setup_sonatype_secrets = local.application_data.accounts[local.environment].setup_sonatype_secrets

# Nomis Secrets PlaceHolder
# Nomis Secrets PlaceHolder
nomis_secrets_placeholder = {
db_name = "nomis"
password = "placeholder"
Expand All @@ -319,7 +319,7 @@ locals {
port = "1521"
}

# Bodmis Secrets PlaceHolder
# Bodmis Secrets PlaceHolder
bodmis_secrets_placeholder = {
db_name = "bodmis"
password = "placeholder"
Expand Down Expand Up @@ -373,7 +373,7 @@ locals {
cloud_platform_k8s_cluster_context = "placeholder"
}

# Analytics Platform, DBT Secrets
# Analytics Platform, DBT Secrets
enable_dbt_k8s_secrets = local.application_data.accounts[local.environment].enable_dbt_k8s_secrets
dbt_k8s_secrets_placeholder = {
oidc_cluster_identifier = "placeholder"
Expand All @@ -394,6 +394,9 @@ locals {
username = module.datamart.redshift_master_user
}

analytical_platform_share = can(local.application_data.accounts[local.environment].analytical_platform_share) ? { for share in local.application_data.accounts[local.environment].analytical_platform_share : share.target_account_name => share } : {}


all_tags = merge(
local.tags,
{
Expand Down
106 changes: 105 additions & 1 deletion terraform/environments/digital-prison-reporting/policy.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ data "aws_iam_policy_document" "glue-policy-data" {
type = "AWS"
}
}

statement {
# Required for cross-account sharing via LakeFormation if producer has existing Glue policy
# ref: https://docs.aws.amazon.com/lake-formation/latest/dg/hybrid-cross-account.html
effect = "Allow"

actions = [
"glue:ShareResource"
]

principals {
type = "Service"
identifiers = ["ram.amazonaws.com"]
}
resources = [
"arn:aws:glue:${local.current_account_region}:${local.current_account_id}:table/*/*",
"arn:aws:glue:${local.current_account_region}:${local.current_account_id}:database/*",
"arn:aws:glue:${local.current_account_region}:${local.current_account_id}:catalog"
]
}
}

# Resuse for all S3 read Only
Expand Down Expand Up @@ -412,7 +432,7 @@ resource "aws_iam_role_policy" "dmsvpcpolicy" {
EOF
}

### Iam User Role for AWS Redshift Spectrum,
### Iam User Role for AWS Redshift Spectrum,
resource "aws_iam_role" "redshift-spectrum-role" {
name = "${local.project}-redshift-spectrum-role"

Expand Down Expand Up @@ -714,3 +734,87 @@ resource "aws_iam_policy" "glue_catalog_readonly" {
description = "Glue Catalog Readonly Policy"
policy = data.aws_iam_policy_document.glue_catalog_readonly.json
}

# Analytical Platform Share Policy & Role

data "aws_iam_policy_document" "analytical_platform_share_policy" {
for_each = local.analytical_platform_share

statement {
effect = "Allow"
actions = [
"lakeformation:GrantPermissions",
"lakeformation:RevokePermissions",
"lakeformation:BatchGrantPermissions",
"lakeformation:BatchRevokePermissions",
"lakeformation:RegisterResource",
"lakeformation:DeregisterResource",
"lakeformation:ListPermissions"
]
resources = [
"arn:aws:lakeformation:${local.current_account_region}:${local.current_account_id}:catalog:${local.current_account_id}"
]
}

statement {
effect = "Allow"
actions = ["iam:PutRolePolicy"]
resources = [
"arn:aws:iam::${local.current_account_id}:role/*/AWSServiceRoleForLakeFormationDataAccess"
]
}

statement {
effect = "Allow"
actions = [
"ram:CreateResourceShare",
"ram:DeleteResourceShare"
]
resources = [
"arn:aws:ram:${local.current_account_region}:${local.current_account_id}:resource-share/*"
]
}

statement {
effect = "Allow"
actions = [
"glue:GetTable",
"glue:GetDatabase",
"glue:GetPartition"
]
resources = flatten([
for resource in each.value.resource_shares : [
"arn:aws:glue:${local.current_account_region}:${local.current_account_id}:database/${resource.glue_database}",
formatlist("arn:aws:glue:${local.current_account_region}:${local.current_account_id}:table/${resource.glue_database}/%s", resource.glue_tables),
"arn:aws:glue:${local.current_account_region}:${local.current_account_id}:catalog"
]
])
}
}

resource "aws_iam_role" "analytical_platform_share_role" {
for_each = local.analytical_platform_share

name = "${each.value.target_account_name}-share-role"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${each.value.target_account_id}:root"
}
Action = "sts:AssumeRole"
}
]
})
}

resource "aws_iam_role_policy" "analytical_platform_share_policy_attachment" {
for_each = local.analytical_platform_share

name = "${each.value.target_account_name}-share-policy"
role = aws_iam_role.analytical_platform_share_role[each.key].name
policy = data.aws_iam_policy_document.analytical_platform_share_policy[each.key].json
}

0 comments on commit 8c5e63f

Please sign in to comment.