diff --git a/deployer/commands/generate/billing/importers.py b/deployer/commands/generate/billing/importers.py index deb0ce61f5..f1f5add55d 100644 --- a/deployer/commands/generate/billing/importers.py +++ b/deployer/commands/generate/billing/importers.py @@ -16,7 +16,6 @@ def build_gcp_query(cluster: dict, service_id=None): Returns: string: query string - """ """ """ bq = cluster["gcp"]["billing"]["bigquery"] diff --git a/docs/helper-programs/generate-hub-features-table.py b/docs/helper-programs/generate-hub-features-table.py index 8e7e1e1e5c..e7b4f275e5 100644 --- a/docs/helper-programs/generate-hub-features-table.py +++ b/docs/helper-programs/generate-hub-features-table.py @@ -155,6 +155,11 @@ def parse_terraform_value_files_for_features(terraform_config): hub_cloud_permissions = terraform_config.get("hub_cloud_permissions", None) if hub_cloud_permissions: for hub_slug, permissions in hub_cloud_permissions.items(): + # The permission object doesn't have the same structure in AWS + # as for GCP currently, and requestor_pays is only available for + # GCP currently. The logic below works, but needs an update if + # GCP aligns with the same structure as AWS, or if + # requestor_pays config is added for AWS. features[hub_slug] = { "user_buckets": True, "requestor_pays": permissions.get("requestor_pays", False), diff --git a/terraform/aws/bucket-access.tf b/terraform/aws/bucket-access.tf new file mode 100644 index 0000000000..85d914619e --- /dev/null +++ b/terraform/aws/bucket-access.tf @@ -0,0 +1,150 @@ +/* + Creates one aws_s3_bucket_policy per bucket - there can't be more than one as + they otherwise replace each other when applied. + + The bucket policies grant bucket specific permissions to specific IAM Roles + based on them having `bucket_admin_access` or `bucket_readonly_access` + referencing the bucket via `var.hub_cloud_permissions`. +*/ + +locals { + /* + The bucket_role_actions local variable defined below is a list of objects + generated from `var.hub_cloud_permissions` roles and their respective + bucket_admin_access and bucket_readonly_access lists. + + If for example `var.hub_cloud_permissions` is: + + hub_cloud_permissions: + staging: + user-sa: + bucket_admin_access: [scratch-staging] + sciencecore: + user-sa: + bucket_admin_access: [scratch-sciencecore] + bucket_readonly_access: [persistent-sciencecore] + admin-sa: + bucket_admin_access: [scratch-sciencecore, persistent-sciencecore] + + Then, the `local.bucket_role_actions` will look like below, with one list + item for each element in all `bucket_admin/readonly_access` lists: + + bucket_role_actions: + - bucket: scratch-staging + role: staging + actions: ["s3:*"] + - bucket: scratch-sciencecore + role: sciencecore + actions: ["s3:*"] + - bucket: scratch-sciencecore + role: sciencecore-admin-sa + actions: ["s3:*"] + - bucket: persistent-sciencecore + role: sciencecore + actions: ["s3:ListBucket", "s3:GetObject", "s3:GetObjectVersion"] + - bucket: persistent-sciencecore + role: sciencecore + actions: ["s3:*"] + */ + bucket_role_actions = flatten([ + for hub, hub_value in var.hub_cloud_permissions : [ + for role, role_value in hub_value : flatten([ + [ + for bucket in role_value.bucket_admin_access : { + bucket = bucket + // role should match the id set in irsa.tf + role = role == "user-sa" ? hub : "${hub}-${role}" + actions = ["s3:*"] + } + ], + [ + for bucket in role_value.bucket_readonly_access : { + bucket = bucket + // role should match the id set in irsa.tf + role = role == "user-sa" ? hub : "${hub}-${role}" + actions = [ + "s3:ListBucket", + "s3:GetObject", + "s3:GetObjectVersion", + ] + } + ], + ]) + ] + ]) +} + +locals { + /* + The `local.bucket_role_actions_lists` variable defined below is reprocessing + `local.bucket_role_actions` to a dictionary with one key per bucket with + associated permissions. + + Below is an example value `local.bucket_role_actions_lists` could take. This + example value is aligned with the example value for + `var.hub_cloud_permissions` and `local.bucket_role_actions` in the code + block above. + + bucket_role_actions_lists: + scratch-staging: + - bucket: scratch-staging + role: staging + actions: ["s3:*"] + scratch-sciencecore: + - bucket: scratch-sciencecore + role: sciencecore + actions: ["s3:*"] + - bucket: scratch-sciencecore + role: sciencecore-admin-sa + actions: ["s3:*"] + persistent-sciencecore: + - bucket: persistent-sciencecore + role: sciencecore + actions: ["s3:ListBucket", "s3:GetObject", "s3:GetObjectVersion"] + - bucket: persistent-sciencecore + role: sciencecore + actions: ["s3:*"] + */ + bucket_role_actions_lists = { + for bucket, _ in var.user_buckets : + bucket => [for bra in local.bucket_role_actions : bra if bra.bucket == bucket] + // Filter out user_buckets not mentioned in hub_cloud_permissions + if length([for bra in local.bucket_role_actions : bra if bra.bucket == bucket]) != 0 + } +} + + + +data "aws_iam_policy_document" "bucket_policy" { + for_each = local.bucket_role_actions_lists + + // Only one policy document can be declared per bucket, so we provide multiple + // "statement" in this policy. + dynamic "statement" { + for_each = { for index, bra in each.value : "${bra.bucket}.${bra.role}" => bra } + + content { + effect = "Allow" + actions = statement.value.actions + principals { + type = "AWS" + identifiers = [ + aws_iam_role.irsa_role[statement.value.role].arn + ] + } + resources = [ + # Grant access only to the bucket and its contents + aws_s3_bucket.user_buckets[statement.value.bucket].arn, + "${aws_s3_bucket.user_buckets[statement.value.bucket].arn}/*", + ] + } + } +} + +// There can only be one of these per bucket, if more are defined they will end +// up replacing each other without terraform indicating there is trouble. +resource "aws_s3_bucket_policy" "user_bucket_access" { + for_each = local.bucket_role_actions_lists + bucket = aws_s3_bucket.user_buckets[each.key].id + policy = data.aws_iam_policy_document.bucket_policy[each.key].json +} diff --git a/terraform/aws/buckets.tf b/terraform/aws/buckets.tf index 2b1c7244d5..6d17c45229 100644 --- a/terraform/aws/buckets.tf +++ b/terraform/aws/buckets.tf @@ -1,7 +1,6 @@ resource "aws_s3_bucket" "user_buckets" { for_each = var.user_buckets bucket = lower("${var.cluster_name}-${each.key}") - } resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" { @@ -36,44 +35,6 @@ resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" { } } -locals { - # Nested for loop, thanks to https://www.daveperrett.com/articles/2021/08/19/nested-for-each-with-terraform/ - bucket_permissions = distinct(flatten([ - for hub_name, permissions in var.hub_cloud_permissions : [ - for bucket_name in permissions.bucket_admin_access : { - hub_name = hub_name - bucket_name = bucket_name - } - ] - ])) -} - -data "aws_iam_policy_document" "bucket_access" { - for_each = { for bp in local.bucket_permissions : "${bp.hub_name}.${bp.bucket_name}" => bp } - statement { - effect = "Allow" - actions = ["s3:*"] - principals { - type = "AWS" - identifiers = [ - aws_iam_role.irsa_role[each.value.hub_name].arn - ] - } - resources = [ - # Grant access only to the bucket and its contents - aws_s3_bucket.user_buckets[each.value.bucket_name].arn, - "${aws_s3_bucket.user_buckets[each.value.bucket_name].arn}/*" - ] - } -} - -resource "aws_s3_bucket_policy" "user_bucket_access" { - - for_each = { for bp in local.bucket_permissions : "${bp.hub_name}.${bp.bucket_name}" => bp } - bucket = aws_s3_bucket.user_buckets[each.value.bucket_name].id - policy = data.aws_iam_policy_document.bucket_access[each.key].json -} - output "buckets" { value = { for b, _ in var.user_buckets : b => aws_s3_bucket.user_buckets[b].id } description = <<-EOT diff --git a/terraform/aws/irsa.tf b/terraform/aws/irsa.tf index c79f09b17d..672e2180d4 100644 --- a/terraform/aws/irsa.tf +++ b/terraform/aws/irsa.tf @@ -1,20 +1,41 @@ -data "aws_caller_identity" "current" {} +/* + This file provides resources _per hub and role_. Each role is tied to a + specific k8s ServiceAccount allowed to assume the role. + + - Role - for use by k8s ServiceAccount (user-sa, admin-sa) + - Policy - if extra_iam_policy is declared + - RolePolicyAttachment - if extra_iam_policy is declared +*/ +data "aws_caller_identity" "current" {} data "aws_partition" "current" {} -resource "aws_iam_role" "irsa_role" { - for_each = var.hub_cloud_permissions - name = "${var.cluster_name}-${each.key}" - assume_role_policy = data.aws_iam_policy_document.irsa_role_assume[each.key].json + +locals { + # Nested for loop, thanks to https://www.daveperrett.com/articles/2021/08/19/nested-for-each-with-terraform/ + hub_to_role_mapping = flatten([ + for hub, hub_value in var.hub_cloud_permissions : [ + for ksa_name, cloud_permissions in hub_value : { + // Most hubs only use `user-sa`, so we use just the hub name for the IAM + // role for user-sa. `user-sa` was also the only service account supported + // for a long time, so this special casing reduces the amount of work + // we needed to do to introduce other service accounts. + iam_role_name = ksa_name == "user-sa" ? hub : "${hub}-${ksa_name}" + hub = hub + ksa_name = ksa_name + cloud_permissions = cloud_permissions + } + ] + ]) } -data "aws_iam_policy_document" "irsa_role_assume" { - for_each = var.hub_cloud_permissions - statement { - effect = "Allow" +data "aws_iam_policy_document" "irsa_role_assume" { + for_each = { for index, hr in local.hub_to_role_mapping : hr.iam_role_name => hr } + statement { + effect = "Allow" actions = ["sts:AssumeRoleWithWebIdentity"] principals { @@ -28,29 +49,41 @@ data "aws_iam_policy_document" "irsa_role_assume" { test = "StringEquals" variable = "${replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")}:sub" values = [ - "system:serviceaccount:${each.key}:user-sa" + "system:serviceaccount:${each.value.hub}:${each.value.ksa_name}" ] } } } +resource "aws_iam_role" "irsa_role" { + for_each = { for index, hr in local.hub_to_role_mapping : hr.iam_role_name => hr } + name = "${var.cluster_name}-${each.key}" + + assume_role_policy = data.aws_iam_policy_document.irsa_role_assume[each.key].json +} + + + resource "aws_iam_policy" "extra_user_policy" { - for_each = { for hub_name, value in var.hub_cloud_permissions : hub_name => value if value.extra_iam_policy != "" } - name = "${var.cluster_name}-${each.key}-extra-user-policy" + for_each = { for index, hr in local.hub_to_role_mapping : hr.iam_role_name => hr if hr.cloud_permissions.extra_iam_policy != "" } + name = "${var.cluster_name}-${each.key}-extra-user-policy" + description = "Extra permissions granted to users on hub ${each.key} on ${var.cluster_name}" - policy = each.value.extra_iam_policy + policy = each.value.cloud_permissions.extra_iam_policy } resource "aws_iam_role_policy_attachment" "extra_user_policy" { - for_each = { for hub_name, value in var.hub_cloud_permissions : hub_name => value if value.extra_iam_policy != "" } + for_each = { for index, hr in local.hub_to_role_mapping : hr.iam_role_name => hr if hr.cloud_permissions.extra_iam_policy != "" } role = aws_iam_role.irsa_role[each.key].name policy_arn = aws_iam_policy.extra_user_policy[each.key].arn } + + output "kubernetes_sa_annotations" { value = { - for k, v in var.hub_cloud_permissions : - k => "eks.amazonaws.com/role-arn: ${aws_iam_role.irsa_role[k].arn}" + for index, hr in local.hub_to_role_mapping : + hr.iam_role_name => "eks.amazonaws.com/role-arn: ${aws_iam_role.irsa_role[hr.iam_role_name].arn}" } description = <<-EOT Annotations to apply to userServiceAccount in each hub to enable cloud permissions for them. diff --git a/terraform/aws/projects/2i2c-aws-us.tfvars b/terraform/aws/projects/2i2c-aws-us.tfvars index a9a3a0cf3d..38c20188d6 100644 --- a/terraform/aws/projects/2i2c-aws-us.tfvars +++ b/terraform/aws/projects/2i2c-aws-us.tfvars @@ -31,30 +31,36 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "dask-staging" : { - bucket_admin_access : ["scratch-dask-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-dask-staging"], + }, }, "showcase" : { - bucket_admin_access : [ - "scratch-researchdelight", - "persistent-showcase" - ], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : [ + "scratch-researchdelight", + "persistent-showcase", + ], + }, }, "ncar-cisl" : { - bucket_admin_access : ["scratch-ncar-cisl"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-ncar-cisl"], + }, }, "go-bgc" : { - bucket_admin_access : ["scratch-go-bgc"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-go-bgc"], + }, }, "itcoocean" : { - bucket_admin_access : ["scratch-itcoocean"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-itcoocean"], + }, }, } diff --git a/terraform/aws/projects/bican.tfvars b/terraform/aws/projects/bican.tfvars index 0b0c92785b..5411d6f659 100644 --- a/terraform/aws/projects/bican.tfvars +++ b/terraform/aws/projects/bican.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/catalystproject-africa.tfvars b/terraform/aws/projects/catalystproject-africa.tfvars index 728f18a381..daf6ec5bd2 100644 --- a/terraform/aws/projects/catalystproject-africa.tfvars +++ b/terraform/aws/projects/catalystproject-africa.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/dandi.tfvars b/terraform/aws/projects/dandi.tfvars index a66677c70b..eb70b296b5 100644 --- a/terraform/aws/projects/dandi.tfvars +++ b/terraform/aws/projects/dandi.tfvars @@ -13,13 +13,16 @@ user_buckets = { }, } + hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/earthscope.tfvars b/terraform/aws/projects/earthscope.tfvars index 688977269b..0fecda7e47 100644 --- a/terraform/aws/projects/earthscope.tfvars +++ b/terraform/aws/projects/earthscope.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/gridsst.tfvars b/terraform/aws/projects/gridsst.tfvars index 74680c5fcd..7def9eecb5 100644 --- a/terraform/aws/projects/gridsst.tfvars +++ b/terraform/aws/projects/gridsst.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/jupyter-health.tfvars b/terraform/aws/projects/jupyter-health.tfvars index b0a8c30d2f..5af56b293f 100644 --- a/terraform/aws/projects/jupyter-health.tfvars +++ b/terraform/aws/projects/jupyter-health.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/jupyter-meets-the-earth.tfvars b/terraform/aws/projects/jupyter-meets-the-earth.tfvars index 73a5a38797..09b553e953 100644 --- a/terraform/aws/projects/jupyter-meets-the-earth.tfvars +++ b/terraform/aws/projects/jupyter-meets-the-earth.tfvars @@ -16,37 +16,41 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - # FIXME: Previously, users were granted full S3 permissions. - # Keep it the same for now - extra_iam_policy : <<-EOT -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": ["s3:*"], - "Resource": ["arn:aws:s3:::*"] - } - ] -} -EOT + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + # FIXME: Previously, users were granted full S3 permissions. + # Keep it the same for now + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:*"], + "Resource": ["arn:aws:s3:::*"] + } + ] + } + EOT + }, }, "prod" : { - bucket_admin_access : ["scratch"], - # FIXME: Previously, users were granted full S3 permissions. - # Keep it the same for now - extra_iam_policy : <<-EOT -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": ["s3:*"], - "Resource": ["arn:aws:s3:::*"] - } - ] -} -EOT + "user-sa" : { + bucket_admin_access : ["scratch"], + # FIXME: Previously, users were granted full S3 permissions. + # Keep it the same for now + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:*"], + "Resource": ["arn:aws:s3:::*"] + } + ] + } + EOT + }, }, } diff --git a/terraform/aws/projects/kitware.tfvars b/terraform/aws/projects/kitware.tfvars index 128ba71b22..4636b90ae6 100644 --- a/terraform/aws/projects/kitware.tfvars +++ b/terraform/aws/projects/kitware.tfvars @@ -1,18 +1,9 @@ -/* - Some of the assumptions this template makes about the cluster: - - location of the nodes of the kubernetes cluster will be a - - no default scratch buckets support -*/ - region = "us-west-2" cluster_name = "kitware" cluster_nodes_location = "us-west-2a" -# Tip: uncomment and fill the missing info in the lines below if you want -# to setup scratch buckets for the hubs on this cluster. -# user_buckets = { "scratch-staging" : { "delete_after" : 7 @@ -24,11 +15,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/linc.tfvars b/terraform/aws/projects/linc.tfvars index d3d934c5fb..8b40a75889 100644 --- a/terraform/aws/projects/linc.tfvars +++ b/terraform/aws/projects/linc.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, } diff --git a/terraform/aws/projects/nasa-cryo.tfvars b/terraform/aws/projects/nasa-cryo.tfvars index 72197c009d..c58e9cbde6 100644 --- a/terraform/aws/projects/nasa-cryo.tfvars +++ b/terraform/aws/projects/nasa-cryo.tfvars @@ -22,71 +22,75 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging", "persistent-staging"], - # Provides readonly requestor-pays access to usgs-landsat bucket - # FIXME: We should find a way to allow access to *all* requester pays - # buckets, without having to explicitly list them. However, we don't want - # to give access to all *internal* s3 buckets willy-nilly - this can be - # a massive security hole, especially if terraform state is also here. - # As a temporary measure, we allow-list buckets here. - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:*" - ], - "Resource": [ - "arn:aws:s3:::usgs-landsat" - ] - }, - { - "Effect": "Allow", - "Action": [ - "s3:*" - ], - "Resource": [ - "arn:aws:s3:::usgs-landsat/*" - ] - } - ] - } - EOT + "user-sa" : { + bucket_admin_access : ["scratch-staging", "persistent-staging"], + # Provides readonly requestor-pays access to usgs-landsat bucket + # FIXME: We should find a way to allow access to *all* requester pays + # buckets, without having to explicitly list them. However, we don't want + # to give access to all *internal* s3 buckets willy-nilly - this can be + # a massive security hole, especially if terraform state is also here. + # As a temporary measure, we allow-list buckets here. + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::usgs-landsat" + ] + }, + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::usgs-landsat/*" + ] + } + ] + } + EOT + }, }, "prod" : { - bucket_admin_access : ["scratch", "persistent"], - # Provides readonly requestor-pays access to usgs-landsat bucket - # FIXME: We should find a way to allow access to *all* requester pays - # buckets, without having to explicitly list them. However, we don't want - # to give access to all *internal* s3 buckets willy-nilly - this can be - # a massive security hole, especially if terraform state is also here. - # As a temporary measure, we allow-list buckets here. - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:*" - ], - "Resource": [ - "arn:aws:s3:::usgs-landsat" - ] - }, - { - "Effect": "Allow", - "Action": [ - "s3:*" - ], - "Resource": [ - "arn:aws:s3:::usgs-landsat/*" - ] - } - ] - } - EOT + "user-sa" : { + bucket_admin_access : ["scratch", "persistent"], + # Provides readonly requestor-pays access to usgs-landsat bucket + # FIXME: We should find a way to allow access to *all* requester pays + # buckets, without having to explicitly list them. However, we don't want + # to give access to all *internal* s3 buckets willy-nilly - this can be + # a massive security hole, especially if terraform state is also here. + # As a temporary measure, we allow-list buckets here. + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::usgs-landsat" + ] + }, + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::usgs-landsat/*" + ] + } + ] + } + EOT + }, }, } diff --git a/terraform/aws/projects/nasa-esdis.tfvars b/terraform/aws/projects/nasa-esdis.tfvars index 9beb0b55cb..b371a6bdc6 100644 --- a/terraform/aws/projects/nasa-esdis.tfvars +++ b/terraform/aws/projects/nasa-esdis.tfvars @@ -16,67 +16,70 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + "user-sa" : { + bucket_admin_access : ["scratch"], + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:ListBucketVersions", - "s3:CreateBucket", - "s3:ListBucket", - "s3:DeleteObject", - "s3:GetBucketLocation", - "s3:ListMultipartUploadParts" - ], - "Resource": [ - "arn:aws:s3:::veda-data-store-staging", - "arn:aws:s3:::veda-data-store-staging/*", - "arn:aws:s3:::veda-nex-gddp-cmip6-public", - "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", - "arn:aws:s3:::cmip6-staging", - "arn:aws:s3:::cmip6-staging/*", - "arn:aws:s3:::lp-prod-protected", - "arn:aws:s3:::lp-prod-protected/*", - "arn:aws:s3:::gesdisc-cumulus-prod-protected", - "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", - "arn:aws:s3:::nsidc-cumulus-prod-protected", - "arn:aws:s3:::nsidc-cumulus-prod-protected/*", - "arn:aws:s3:::ornl-cumulus-prod-protected", - "arn:aws:s3:::ornl-cumulus-prod-protected/*", - "arn:aws:s3:::pangeo-forge-veda-output", - "arn:aws:s3:::pangeo-forge-veda-output/*", - "arn:aws:s3:::podaac-ops-cumulus-public", - "arn:aws:s3:::podaac-ops-cumulus-public/*", - "arn:aws:s3:::podaac-ops-cumulus-protected", - "arn:aws:s3:::podaac-ops-cumulus-protected/*", - "arn:aws:s3:::maap-ops-workspace", - "arn:aws:s3:::maap-ops-workspace/*", - "arn:aws:s3:::nasa-maap-data-store", - "arn:aws:s3:::nasa-maap-data-store/*", - "arn:aws:s3:::grss-veda-data-store", - "arn:aws:s3:::grss-veda-data-store/*", - "arn:aws:s3:::sentinel-cogs", - "arn:aws:s3:::sentinel-cogs/*" - ] + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucketMultipartUploads", + "s3:AbortMultipartUpload", + "s3:ListBucketVersions", + "s3:CreateBucket", + "s3:ListBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:ListMultipartUploadParts" + ], + "Resource": [ + "arn:aws:s3:::veda-data-store-staging", + "arn:aws:s3:::veda-data-store-staging/*", + "arn:aws:s3:::veda-nex-gddp-cmip6-public", + "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", + "arn:aws:s3:::cmip6-staging", + "arn:aws:s3:::cmip6-staging/*", + "arn:aws:s3:::lp-prod-protected", + "arn:aws:s3:::lp-prod-protected/*", + "arn:aws:s3:::gesdisc-cumulus-prod-protected", + "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", + "arn:aws:s3:::nsidc-cumulus-prod-protected", + "arn:aws:s3:::nsidc-cumulus-prod-protected/*", + "arn:aws:s3:::ornl-cumulus-prod-protected", + "arn:aws:s3:::ornl-cumulus-prod-protected/*", + "arn:aws:s3:::pangeo-forge-veda-output", + "arn:aws:s3:::pangeo-forge-veda-output/*", + "arn:aws:s3:::podaac-ops-cumulus-public", + "arn:aws:s3:::podaac-ops-cumulus-public/*", + "arn:aws:s3:::podaac-ops-cumulus-protected", + "arn:aws:s3:::podaac-ops-cumulus-protected/*", + "arn:aws:s3:::maap-ops-workspace", + "arn:aws:s3:::maap-ops-workspace/*", + "arn:aws:s3:::nasa-maap-data-store", + "arn:aws:s3:::nasa-maap-data-store/*", + "arn:aws:s3:::grss-veda-data-store", + "arn:aws:s3:::grss-veda-data-store/*", + "arn:aws:s3:::sentinel-cogs", + "arn:aws:s3:::sentinel-cogs/*" + ] }, { - "Effect": "Allow", - "Action": "s3:ListAllMyBuckets", - "Resource": "*" + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" } - ] - } - EOT + ] + } + EOT + }, }, } diff --git a/terraform/aws/projects/nasa-ghg.tfvars b/terraform/aws/projects/nasa-ghg.tfvars index 831205b98e..91482a309b 100644 --- a/terraform/aws/projects/nasa-ghg.tfvars +++ b/terraform/aws/projects/nasa-ghg.tfvars @@ -16,105 +16,109 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:ListBucketVersions", - "s3:ListBucket", - "s3:DeleteObject", - "s3:GetBucketLocation", - "s3:ListMultipartUploadParts" - ], - "Resource": [ - "arn:aws:s3:::ghgc-data-staging", - "arn:aws:s3:::ghgc-data-staging/*", - "arn:aws:s3:::ghgc-data-store-dev", - "arn:aws:s3:::ghgc-data-store-dev/*", - "arn:aws:s3:::ghgc-data-store", - "arn:aws:s3:::ghgc-data-store/*", - "arn:aws:s3:::ghgc-data-store-staging", - "arn:aws:s3:::ghgc-data-store-staging/*", - "arn:aws:s3:::veda-data-store-staging", - "arn:aws:s3:::veda-data-store-staging/*", - "arn:aws:s3:::lp-prod-protected", - "arn:aws:s3:::lp-prod-protected/*", - "arn:aws:s3:::gesdisc-cumulus-prod-protected", - "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", - "arn:aws:s3:::nsidc-cumulus-prod-protected", - "arn:aws:s3:::nsidc-cumulus-prod-protected/*", - "arn:aws:s3:::ornl-cumulus-prod-protected", - "arn:aws:s3:::ornl-cumulus-prod-protected/*", - "arn:aws:s3:::podaac-ops-cumulus-public", - "arn:aws:s3:::podaac-ops-cumulus-public/*", - "arn:aws:s3:::podaac-ops-cumulus-protected", - "arn:aws:s3:::podaac-ops-cumulus-protected/*" - ] + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucketMultipartUploads", + "s3:AbortMultipartUpload", + "s3:ListBucketVersions", + "s3:ListBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:ListMultipartUploadParts" + ], + "Resource": [ + "arn:aws:s3:::ghgc-data-staging", + "arn:aws:s3:::ghgc-data-staging/*", + "arn:aws:s3:::ghgc-data-store-dev", + "arn:aws:s3:::ghgc-data-store-dev/*", + "arn:aws:s3:::ghgc-data-store", + "arn:aws:s3:::ghgc-data-store/*", + "arn:aws:s3:::ghgc-data-store-staging", + "arn:aws:s3:::ghgc-data-store-staging/*", + "arn:aws:s3:::veda-data-store-staging", + "arn:aws:s3:::veda-data-store-staging/*", + "arn:aws:s3:::lp-prod-protected", + "arn:aws:s3:::lp-prod-protected/*", + "arn:aws:s3:::gesdisc-cumulus-prod-protected", + "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", + "arn:aws:s3:::nsidc-cumulus-prod-protected", + "arn:aws:s3:::nsidc-cumulus-prod-protected/*", + "arn:aws:s3:::ornl-cumulus-prod-protected", + "arn:aws:s3:::ornl-cumulus-prod-protected/*", + "arn:aws:s3:::podaac-ops-cumulus-public", + "arn:aws:s3:::podaac-ops-cumulus-public/*", + "arn:aws:s3:::podaac-ops-cumulus-protected", + "arn:aws:s3:::podaac-ops-cumulus-protected/*" + ] }, { - "Effect": "Allow", - "Action": "s3:ListAllMyBuckets", - "Resource": "*" + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" } - ] - } - EOT + ] + } + EOT + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + "user-sa" : { + bucket_admin_access : ["scratch"], + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:ListBucketVersions", - "s3:ListBucket", - "s3:DeleteObject", - "s3:GetBucketLocation", - "s3:ListMultipartUploadParts" - ], - "Resource": [ - "arn:aws:s3:::ghgc-data-staging", - "arn:aws:s3:::ghgc-data-staging/*", - "arn:aws:s3:::ghgc-data-store-dev", - "arn:aws:s3:::ghgc-data-store-dev/*", - "arn:aws:s3:::ghgc-data-store", - "arn:aws:s3:::ghgc-data-store/*", - "arn:aws:s3:::ghgc-data-store-staging", - "arn:aws:s3:::ghgc-data-store-staging/*", - "arn:aws:s3:::veda-data-store-staging", - "arn:aws:s3:::veda-data-store-staging/*", - "arn:aws:s3:::lp-prod-protected", - "arn:aws:s3:::lp-prod-protected/*", - "arn:aws:s3:::gesdisc-cumulus-prod-protected", - "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", - "arn:aws:s3:::nsidc-cumulus-prod-protected", - "arn:aws:s3:::nsidc-cumulus-prod-protected/*", - "arn:aws:s3:::ornl-cumulus-prod-protected", - "arn:aws:s3:::ornl-cumulus-prod-protected/*" - ] + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucketMultipartUploads", + "s3:AbortMultipartUpload", + "s3:ListBucketVersions", + "s3:ListBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:ListMultipartUploadParts" + ], + "Resource": [ + "arn:aws:s3:::ghgc-data-staging", + "arn:aws:s3:::ghgc-data-staging/*", + "arn:aws:s3:::ghgc-data-store-dev", + "arn:aws:s3:::ghgc-data-store-dev/*", + "arn:aws:s3:::ghgc-data-store", + "arn:aws:s3:::ghgc-data-store/*", + "arn:aws:s3:::ghgc-data-store-staging", + "arn:aws:s3:::ghgc-data-store-staging/*", + "arn:aws:s3:::veda-data-store-staging", + "arn:aws:s3:::veda-data-store-staging/*", + "arn:aws:s3:::lp-prod-protected", + "arn:aws:s3:::lp-prod-protected/*", + "arn:aws:s3:::gesdisc-cumulus-prod-protected", + "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", + "arn:aws:s3:::nsidc-cumulus-prod-protected", + "arn:aws:s3:::nsidc-cumulus-prod-protected/*", + "arn:aws:s3:::ornl-cumulus-prod-protected", + "arn:aws:s3:::ornl-cumulus-prod-protected/*" + ] }, { - "Effect": "Allow", - "Action": "s3:ListAllMyBuckets", - "Resource": "*" + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" } - ] - } - EOT + ] + } + EOT + }, }, } diff --git a/terraform/aws/projects/nasa-veda.tfvars b/terraform/aws/projects/nasa-veda.tfvars index fae2cfff2f..6192ede19a 100644 --- a/terraform/aws/projects/nasa-veda.tfvars +++ b/terraform/aws/projects/nasa-veda.tfvars @@ -16,125 +16,129 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:ListBucketVersions", - "s3:CreateBucket", - "s3:ListBucket", - "s3:DeleteObject", - "s3:GetBucketLocation", - "s3:ListMultipartUploadParts" - ], - "Resource": [ - "arn:aws:s3:::veda-data-store-staging", - "arn:aws:s3:::veda-data-store-staging/*", - "arn:aws:s3:::veda-nex-gddp-cmip6-public", - "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", - "arn:aws:s3:::cmip6-staging", - "arn:aws:s3:::cmip6-staging/*", - "arn:aws:s3:::lp-prod-protected", - "arn:aws:s3:::lp-prod-protected/*", - "arn:aws:s3:::gesdisc-cumulus-prod-protected", - "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", - "arn:aws:s3:::nsidc-cumulus-prod-protected", - "arn:aws:s3:::nsidc-cumulus-prod-protected/*", - "arn:aws:s3:::ornl-cumulus-prod-protected", - "arn:aws:s3:::ornl-cumulus-prod-protected/*", - "arn:aws:s3:::pangeo-forge-veda-output", - "arn:aws:s3:::pangeo-forge-veda-output/*", - "arn:aws:s3:::podaac-ops-cumulus-public", - "arn:aws:s3:::podaac-ops-cumulus-public/*", - "arn:aws:s3:::podaac-ops-cumulus-protected", - "arn:aws:s3:::podaac-ops-cumulus-protected/*", - "arn:aws:s3:::maap-ops-workspace", - "arn:aws:s3:::maap-ops-workspace/*", - "arn:aws:s3:::nasa-maap-data-store", - "arn:aws:s3:::nasa-maap-data-store/*", - "arn:aws:s3:::sdap-dev-zarr", - "arn:aws:s3:::sdap-dev-zarr/*", - "arn:aws:s3:::usgs-landsat", - "arn:aws:s3:::usgs-landsat/*", - "arn:aws:s3:::sentinel-cogs", - "arn:aws:s3:::sentinel-cogs/*" - ] + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucketMultipartUploads", + "s3:AbortMultipartUpload", + "s3:ListBucketVersions", + "s3:CreateBucket", + "s3:ListBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:ListMultipartUploadParts" + ], + "Resource": [ + "arn:aws:s3:::veda-data-store-staging", + "arn:aws:s3:::veda-data-store-staging/*", + "arn:aws:s3:::veda-nex-gddp-cmip6-public", + "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", + "arn:aws:s3:::cmip6-staging", + "arn:aws:s3:::cmip6-staging/*", + "arn:aws:s3:::lp-prod-protected", + "arn:aws:s3:::lp-prod-protected/*", + "arn:aws:s3:::gesdisc-cumulus-prod-protected", + "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", + "arn:aws:s3:::nsidc-cumulus-prod-protected", + "arn:aws:s3:::nsidc-cumulus-prod-protected/*", + "arn:aws:s3:::ornl-cumulus-prod-protected", + "arn:aws:s3:::ornl-cumulus-prod-protected/*", + "arn:aws:s3:::pangeo-forge-veda-output", + "arn:aws:s3:::pangeo-forge-veda-output/*", + "arn:aws:s3:::podaac-ops-cumulus-public", + "arn:aws:s3:::podaac-ops-cumulus-public/*", + "arn:aws:s3:::podaac-ops-cumulus-protected", + "arn:aws:s3:::podaac-ops-cumulus-protected/*", + "arn:aws:s3:::maap-ops-workspace", + "arn:aws:s3:::maap-ops-workspace/*", + "arn:aws:s3:::nasa-maap-data-store", + "arn:aws:s3:::nasa-maap-data-store/*", + "arn:aws:s3:::sdap-dev-zarr", + "arn:aws:s3:::sdap-dev-zarr/*", + "arn:aws:s3:::usgs-landsat", + "arn:aws:s3:::usgs-landsat/*", + "arn:aws:s3:::sentinel-cogs", + "arn:aws:s3:::sentinel-cogs/*" + ] }, { - "Effect": "Allow", - "Action": "s3:ListAllMyBuckets", - "Resource": "*" + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" } - ] - } - EOT + ] + } + EOT + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + "user-sa" : { + bucket_admin_access : ["scratch"], + extra_iam_policy : <<-EOT + { + "Version": "2012-10-17", + "Statement": [ { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucketMultipartUploads", - "s3:AbortMultipartUpload", - "s3:ListBucketVersions", - "s3:CreateBucket", - "s3:ListBucket", - "s3:DeleteObject", - "s3:GetBucketLocation", - "s3:ListMultipartUploadParts" - ], - "Resource": [ - "arn:aws:s3:::veda-data-store-staging", - "arn:aws:s3:::veda-data-store-staging/*", - "arn:aws:s3:::veda-nex-gddp-cmip6-public", - "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", - "arn:aws:s3:::cmip6-staging", - "arn:aws:s3:::cmip6-staging/*", - "arn:aws:s3:::lp-prod-protected", - "arn:aws:s3:::lp-prod-protected/*", - "arn:aws:s3:::gesdisc-cumulus-prod-protected", - "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", - "arn:aws:s3:::nsidc-cumulus-prod-protected", - "arn:aws:s3:::nsidc-cumulus-prod-protected/*", - "arn:aws:s3:::ornl-cumulus-prod-protected", - "arn:aws:s3:::ornl-cumulus-prod-protected/*", - "arn:aws:s3:::pangeo-forge-veda-output", - "arn:aws:s3:::pangeo-forge-veda-output/*", - "arn:aws:s3:::podaac-ops-cumulus-public", - "arn:aws:s3:::podaac-ops-cumulus-public/*", - "arn:aws:s3:::podaac-ops-cumulus-protected", - "arn:aws:s3:::podaac-ops-cumulus-protected/*", - "arn:aws:s3:::maap-ops-workspace", - "arn:aws:s3:::maap-ops-workspace/*", - "arn:aws:s3:::nasa-maap-data-store", - "arn:aws:s3:::nasa-maap-data-store/*", - "arn:aws:s3:::sdap-dev-zarr", - "arn:aws:s3:::sdap-dev-zarr/*", - "arn:aws:s3:::usgs-landsat", - "arn:aws:s3:::usgs-landsat/*" - ] + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucketMultipartUploads", + "s3:AbortMultipartUpload", + "s3:ListBucketVersions", + "s3:CreateBucket", + "s3:ListBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:ListMultipartUploadParts" + ], + "Resource": [ + "arn:aws:s3:::veda-data-store-staging", + "arn:aws:s3:::veda-data-store-staging/*", + "arn:aws:s3:::veda-nex-gddp-cmip6-public", + "arn:aws:s3:::veda-nex-gddp-cmip6-public/*", + "arn:aws:s3:::cmip6-staging", + "arn:aws:s3:::cmip6-staging/*", + "arn:aws:s3:::lp-prod-protected", + "arn:aws:s3:::lp-prod-protected/*", + "arn:aws:s3:::gesdisc-cumulus-prod-protected", + "arn:aws:s3:::gesdisc-cumulus-prod-protected/*", + "arn:aws:s3:::nsidc-cumulus-prod-protected", + "arn:aws:s3:::nsidc-cumulus-prod-protected/*", + "arn:aws:s3:::ornl-cumulus-prod-protected", + "arn:aws:s3:::ornl-cumulus-prod-protected/*", + "arn:aws:s3:::pangeo-forge-veda-output", + "arn:aws:s3:::pangeo-forge-veda-output/*", + "arn:aws:s3:::podaac-ops-cumulus-public", + "arn:aws:s3:::podaac-ops-cumulus-public/*", + "arn:aws:s3:::podaac-ops-cumulus-protected", + "arn:aws:s3:::podaac-ops-cumulus-protected/*", + "arn:aws:s3:::maap-ops-workspace", + "arn:aws:s3:::maap-ops-workspace/*", + "arn:aws:s3:::nasa-maap-data-store", + "arn:aws:s3:::nasa-maap-data-store/*", + "arn:aws:s3:::sdap-dev-zarr", + "arn:aws:s3:::sdap-dev-zarr/*", + "arn:aws:s3:::usgs-landsat", + "arn:aws:s3:::usgs-landsat/*" + ] }, { - "Effect": "Allow", - "Action": "s3:ListAllMyBuckets", - "Resource": "*" + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*" } - ] - } - EOT + ] + } + EOT + }, }, } diff --git a/terraform/aws/projects/openscapes.tfvars b/terraform/aws/projects/openscapes.tfvars index e1f9b5dc44..1bd7851e47 100644 --- a/terraform/aws/projects/openscapes.tfvars +++ b/terraform/aws/projects/openscapes.tfvars @@ -25,17 +25,19 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : [ - "scratch-staging", - "persistent-staging" - ], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : [ + "scratch-staging", + "persistent-staging", + ], + }, }, "prod" : { - bucket_admin_access : [ - "scratch", - "persistent" - ], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : [ + "scratch", + "persistent", + ], + } }, } diff --git a/terraform/aws/projects/smithsonian.tfvars b/terraform/aws/projects/smithsonian.tfvars index 1ec655e8e7..28edc972f6 100644 --- a/terraform/aws/projects/smithsonian.tfvars +++ b/terraform/aws/projects/smithsonian.tfvars @@ -13,11 +13,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, } diff --git a/terraform/aws/projects/template.tfvars b/terraform/aws/projects/template.tfvars index cc953250a0..afd0412f0c 100644 --- a/terraform/aws/projects/template.tfvars +++ b/terraform/aws/projects/template.tfvars @@ -25,8 +25,9 @@ cluster_nodes_location = "{{ cluster_region }}a" # #hub_cloud_permissions = { # "{{ hub_name }}" : { -# bucket_admin_access : ["scratch-{{ hub_name }}"], -# extra_iam_policy : "" +# "user-sa" : { +# bucket_admin_access : ["scratch-{{ hub_name }}"], +# }, # }, # # Tip: add more namespaces below, if this cluster will be multi-tenant #} diff --git a/terraform/aws/projects/ubc-eoas.tfvars b/terraform/aws/projects/ubc-eoas.tfvars index f38abdf057..98686f1f7f 100644 --- a/terraform/aws/projects/ubc-eoas.tfvars +++ b/terraform/aws/projects/ubc-eoas.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/projects/victor.tfvars b/terraform/aws/projects/victor.tfvars index f6237fe892..7e61ad64a4 100644 --- a/terraform/aws/projects/victor.tfvars +++ b/terraform/aws/projects/victor.tfvars @@ -16,11 +16,13 @@ user_buckets = { hub_cloud_permissions = { "staging" : { - bucket_admin_access : ["scratch-staging"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch-staging"], + }, }, "prod" : { - bucket_admin_access : ["scratch"], - extra_iam_policy : "" + "user-sa" : { + bucket_admin_access : ["scratch"], + }, }, -} \ No newline at end of file +} diff --git a/terraform/aws/variables.tf b/terraform/aws/variables.tf index 332a78ab5a..f7272c32f9 100644 --- a/terraform/aws/variables.tf +++ b/terraform/aws/variables.tf @@ -44,21 +44,39 @@ variable "user_buckets" { } variable "hub_cloud_permissions" { - type = map(object({ - bucket_admin_access : set(string), - extra_iam_policy : string - })) + type = map( + map( + object({ + bucket_admin_access : optional(set(string), []) + bucket_readonly_access : optional(set(string), []) + extra_iam_policy : optional(string, "") + }) + ) + ) default = {} description = <<-EOT - Map of cloud permissions given to a particular hub - - Key is name of the hub namespace in the cluster, and values are particular - permissions users running on those hubs should have. Currently supported are: - - 1. bucket_admin_access: List of S3 storage buckets that users on this hub should have read - and write permissions for. - 2. extra_iam_policy: An AWS IAM Policy document that grants additional rights to the users - on this hub when talking to AWS services. + Cloud permissions attached to Kubernetes Service Accounts in a particular + k8s namespace (hub) in this cluster. + + The key is a Kubernetes namespace, which by convention in 2i2c clusters + is also the name of the hub. + + The value is itself a map, as each hub can have multiple Kubernetes Service + Accounts attached to it, for different kinds of users. The key is the name + of the Kubernetes Service Account. By convention, basehub currently only + supports creation of Kubernetes Service Accounts `user-sa` (for non-admin + users on the hub) and `admin-sa` (for admin users on the hub). The value + can be one of: + + 1. bucket_admin_access: List of S3 storage buckets to grant full read & write + permissions to. + 2. bucket_readonly_access: List of S3 storage buckets to grant full read + permissions to. + 3. extra_iam_policy: An AWS IAM Policy document that grants additional rights + to this Kubernetes Service Account. + + Note that these are independent of each other - so if you want both admins + and non-admins to have a set of permissions, you may need to repeat them. EOT }