Skip to content

feat: add additional bucket policy#8194

Open
jjfrench wants to merge 2 commits into
2i2c-org:mainfrom
jjfrench:feat/additional-bucket-policy
Open

feat: add additional bucket policy#8194
jjfrench wants to merge 2 commits into
2i2c-org:mainfrom
jjfrench:feat/additional-bucket-policy

Conversation

@jjfrench

Copy link
Copy Markdown
Contributor

Description

  • Attempting to add an additional bucket policy to one of the scratch buckets generated with the hubs

@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will trigger the following deployment actions.

Support deployments

No support upgrades will be triggered

Staging deployments

Cloud Provider Cluster Name Hub Name Reason for Redeploy
aws bnext-bio staging Core common infrastructure has been updated
aws projectpythia staging Core common infrastructure has been updated
aws opensci staging Core common infrastructure has been updated
aws victor staging Core common infrastructure has been updated
aws aimatx-2i2c-hub staging Core common infrastructure has been updated
aws 2i2c-aws-us staging Core common infrastructure has been updated
aws disasters staging Core common infrastructure has been updated
aws nasa-veda staging terraform file was modified
gcp cloudbank staging terraform file was modified
gcp hhmi staging terraform file was modified
aws nasa-cryo staging Core common infrastructure has been updated
aws maap staging Core common infrastructure has been updated
aws nmfs-openscapes staging Core common infrastructure has been updated
aws earthscope staging terraform file was modified
aws nasa-ghg-hub staging Core common infrastructure has been updated
aws jupyter-health staging Core common infrastructure has been updated
aws temple staging Core common infrastructure has been updated
gcp 2i2c staging Core common infrastructure has been updated
gcp 2i2c-uk staging terraform file was modified
aws berkeley-geojupyter staging Core common infrastructure has been updated
aws reflective staging Core common infrastructure has been updated
aws smithsonian staging Core common infrastructure has been updated
gcp leap staging terraform file was modified
gcp awi-ciroh staging terraform file was modified
aws ucmerced staging Core common infrastructure has been updated
aws openscapeshub staging Core common infrastructure has been updated

Production deployments

Cloud Provider Cluster Name Hub Name Reason for Redeploy
aws bnext-bio prod Core common infrastructure has been updated
aws projectpythia prod Core common infrastructure has been updated
aws projectpythia pythia-binder Core common infrastructure has been updated
aws opensci sciencecore Core common infrastructure has been updated
aws opensci climaterisk Core common infrastructure has been updated
aws opensci small-binder Core common infrastructure has been updated
aws opensci big-binder Core common infrastructure has been updated
aws victor prod Core common infrastructure has been updated
aws aimatx-2i2c-hub prod Core common infrastructure has been updated
aws 2i2c-aws-us showcase Core common infrastructure has been updated
aws disasters prod Core common infrastructure has been updated
aws nasa-veda prod terraform file was modified
aws nasa-veda binder terraform file was modified
gcp cloudbank ahs terraform file was modified
gcp cloudbank authoring terraform file was modified
gcp cloudbank bcc terraform file was modified
gcp cloudbank bmcc terraform file was modified
gcp cloudbank chaffey terraform file was modified
gcp cloudbank ccsf terraform file was modified
gcp cloudbank chabot terraform file was modified
gcp cloudbank chicagostate terraform file was modified
gcp cloudbank cmu terraform file was modified
gcp cloudbank cra terraform file was modified
gcp cloudbank csm terraform file was modified
gcp cloudbank csum terraform file was modified
gcp cloudbank deanza terraform file was modified
gcp cloudbank demo terraform file was modified
gcp cloudbank dvc terraform file was modified
gcp cloudbank elac terraform file was modified
gcp cloudbank elcamino terraform file was modified
gcp cloudbank evc terraform file was modified
gcp cloudbank etsu terraform file was modified
gcp cloudbank fresno terraform file was modified
gcp cloudbank foothill terraform file was modified
gcp cloudbank glendale terraform file was modified
gcp cloudbank golden terraform file was modified
gcp cloudbank gwu terraform file was modified
gcp cloudbank gpu-demo terraform file was modified
gcp cloudbank high terraform file was modified
gcp cloudbank hmc terraform file was modified
gcp cloudbank humboldt terraform file was modified
gcp cloudbank kean terraform file was modified
gcp cloudbank lacc terraform file was modified
gcp cloudbank lahc terraform file was modified
gcp cloudbank laney terraform file was modified
gcp cloudbank lavc terraform file was modified
gcp cloudbank lbcc terraform file was modified
gcp cloudbank mendocino terraform file was modified
gcp cloudbank merced terraform file was modified
gcp cloudbank merritt terraform file was modified
gcp cloudbank mmc terraform file was modified
gcp cloudbank miracosta terraform file was modified
gcp cloudbank mission terraform file was modified
gcp cloudbank moreno terraform file was modified
gcp cloudbank norco terraform file was modified
gcp cloudbank ocu terraform file was modified
gcp cloudbank palomar terraform file was modified
gcp cloudbank pasadena terraform file was modified
gcp cloudbank redwoods terraform file was modified
gcp cloudbank reedley terraform file was modified
gcp cloudbank riohondo terraform file was modified
gcp cloudbank saddleback terraform file was modified
gcp cloudbank santiago terraform file was modified
gcp cloudbank sbcc terraform file was modified
gcp cloudbank sbcc-dev terraform file was modified
gcp cloudbank sierra terraform file was modified
gcp cloudbank sjcc terraform file was modified
gcp cloudbank sjsu terraform file was modified
gcp cloudbank skyline terraform file was modified
gcp cloudbank sou terraform file was modified
gcp cloudbank stanford terraform file was modified
gcp cloudbank spelman terraform file was modified
gcp cloudbank srjc terraform file was modified
gcp cloudbank tuskegee terraform file was modified
gcp cloudbank ucsc terraform file was modified
gcp cloudbank umd terraform file was modified
gcp cloudbank und terraform file was modified
gcp cloudbank virginia terraform file was modified
gcp cloudbank wlac terraform file was modified
gcp hhmi spyglass terraform file was modified
gcp hhmi binder terraform file was modified
aws nasa-cryo prod Core common infrastructure has been updated
aws maap prod Core common infrastructure has been updated
aws nmfs-openscapes prod Core common infrastructure has been updated
aws nmfs-openscapes workshop Core common infrastructure has been updated
aws nmfs-openscapes noaa-only Core common infrastructure has been updated
aws earthscope prod terraform file was modified
aws earthscope binder terraform file was modified
aws nasa-ghg-hub prod Core common infrastructure has been updated
aws nasa-ghg-hub binder Core common infrastructure has been updated
aws jupyter-health prod Core common infrastructure has been updated
aws temple prod Core common infrastructure has been updated
aws temple advanced Core common infrastructure has been updated
aws temple research Core common infrastructure has been updated
gcp dubois ephemeral terraform file was modified
gcp 2i2c mtu Core common infrastructure has been updated
gcp 2i2c-uk lis terraform file was modified
aws berkeley-geojupyter prod Core common infrastructure has been updated
aws reflective prod Core common infrastructure has been updated
aws reflective workshop Core common infrastructure has been updated
aws smithsonian prod Core common infrastructure has been updated
gcp leap prod terraform file was modified
gcp leap public terraform file was modified
gcp awi-ciroh prod terraform file was modified
gcp awi-ciroh workshop terraform file was modified
aws ucmerced prod Core common infrastructure has been updated
aws openscapeshub prod Core common infrastructure has been updated
aws openscapeshub workshop Core common infrastructure has been updated

@jjfrench

Copy link
Copy Markdown
Contributor Author

I didn't notice a place to add additional bucket policies like hub_cloud_permissions.extra_iam_policy does for the hub, and the existing bucket policy seemed to only be generated through the current "bucket_access" for_each. Maybe I just missed the configuration somewhere?
cc: @wildintellect

"s3:GetBucketLocation"
],
"Resource": [
"__BUCKET_ARN__",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This needs the actual ARN right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it should, yeah. I try to do this with a replace using the value from below

aws_s3_bucket.user_buckets[each.value.bucket_name].arn

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah! Can we just hardcode it instead? This terraform is used for a lot of hubs (outside of the veda related projects too https://github.com/2i2c-org/infrastructure/tree/main/terraform/aws/projects), and I want to keep changes minimal if we can. (sorry, forgot to post this earlier)

@jjfrench jjfrench May 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hardcode the ARN? Yeah, I can make that change, it would just be removing the try/replace. It would still modify the "user_buckets" object in variables.tf which is probably why it's showing so many changes?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, I had misread where this was being applied. I think this is fine. I just documented BUCKET_ARN here.

Thanks for the PR, and sorry about the delay!

@jjfrench

jjfrench commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

Were there other comments about this? Not sure about the urgency of it, just wanted to make sure we got this back into code

@yuvipanda

Copy link
Copy Markdown
Member

@jjfrench trying to apply this (after rebasing on main) gives me a much larger diff than I expect:

data.sops_file.pagerduty_volume_integration: Reading...
data.sops_file.pagerduty_volume_integration: Read complete after 0s [id=-]
data.aws_caller_identity.current: Reading...
aws_iam_user.continuous_deployer: Refreshing state... [id=hub-continuous-deployer]
aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["scratch"]: Refreshing state... [id=nasa-veda-scratch]
aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["scratch-binder"]: Refreshing state... [id=nasa-veda-scratch-binder]
aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["scratch-staging"]: Refreshing state... [id=nasa-veda-scratch-staging]
aws_sns_topic.volume_metric_exceeded: Refreshing state... [id=arn:aws:sns:us-west-2:444055461661:volume-metric-exceeded-topic]
aws_s3_bucket.user_buckets["scratch-binder"]: Refreshing state... [id=nasa-veda-scratch-binder]
aws_s3_bucket.user_buckets["scratch"]: Refreshing state... [id=nasa-veda-scratch]
aws_s3_bucket.user_buckets["scratch-staging"]: Refreshing state... [id=nasa-veda-scratch-staging]
aws_iam_policy.extra_user_policy["binder"]: Refreshing state... [id=arn:aws:iam::444055461661:policy/nasa-veda-binder-extra-user-policy]
data.aws_caller_identity.current: Read complete after 0s [id=444055461661]
aws_iam_policy.extra_user_policy["prod"]: Refreshing state... [id=arn:aws:iam::444055461661:policy/nasa-veda-prod-extra-user-policy]
aws_iam_policy.extra_user_policy["staging"]: Refreshing state... [id=arn:aws:iam::444055461661:policy/nasa-veda-staging-extra-user-policy]
aws_iam_role.dlm_lifecycle_role[0]: Refreshing state... [id=dlm-lifecycle-role]
data.aws_partition.current: Reading...
data.aws_eks_cluster.cluster: Reading...
data.aws_partition.current: Read complete after 0s [id=aws]
aws_ebs_volume.nfs_home_dirs["prod"]: Refreshing state... [id=vol-0063ecd342e052ef5]
aws_ebs_volume.nfs_home_dirs["staging"]: Refreshing state... [id=vol-0a1246ee2e07372d0]
data.aws_eks_cluster.cluster: Read complete after 1s [id=nasa-veda]
aws_sns_topic_subscription.volume_metric_exceeded_https_target: Refreshing state... [id=arn:aws:sns:us-west-2:444055461661:volume-metric-exceeded-topic:ed24041a-14f4-40f7-b66c-2ae0af30c4cf]
aws_iam_access_key.continuous_deployer: Refreshing state... [id=AKIAWOY6ET4OWCZUFNED]
aws_iam_user_policy.continuous_deployer: Refreshing state... [id=hub-continuous-deployer:eks-readonly]
data.aws_security_group.cluster_nodes_shared_security_group: Reading...
data.aws_subnets.cluster_node_subnets: Reading...
aws_iam_role.jupyterhub_grafana_cloudwatch: Refreshing state... [id=jupyterhub_grafana_cloudwatch]
aws_iam_role.jupyterhub_cost_monitoring_iam_role[0]: Refreshing state... [id=jupyterhub_cost_monitoring_iam_role]
aws_iam_role.irsa_role["binder"]: Refreshing state... [id=nasa-veda-binder]
aws_iam_role.irsa_role["staging"]: Refreshing state... [id=nasa-veda-staging]
aws_iam_role.irsa_role["prod"]: Refreshing state... [id=nasa-veda-prod]
aws_cloudwatch_metric_alarm.volume_throughput_alarm["staging"]: Refreshing state... [id=warn-volume-throughput-exceeded]
aws_cloudwatch_metric_alarm.volume_throughput_alarm["prod"]: Refreshing state... [id=warn-volume-throughput-exceeded]
aws_cloudwatch_metric_alarm.volume_iops_alarm["prod"]: Refreshing state... [id=warn-volume-iops-exceeded]
data.aws_security_group.cluster_nodes_shared_security_group: Read complete after 0s [id=sg-0864cea487cfb5c5a]
aws_cloudwatch_metric_alarm.volume_iops_alarm["staging"]: Refreshing state... [id=warn-volume-iops-exceeded]
data.aws_subnets.cluster_node_subnets: Read complete after 0s [id=us-west-2]
aws_iam_role_policy.dlm_lifecycle[0]: Refreshing state... [id=dlm-lifecycle-role:dlm-lifecycle-policy]
aws_dlm_lifecycle_policy.nfs_backup[0]: Refreshing state... [id=policy-0fe9d5e6f01e75ff9]
aws_iam_role_policy.jupyterhub_grafana_cloudwatch: Refreshing state... [id=jupyterhub_grafana_cloudwatch:jupyterhub_grafana_cloudwatch]
aws_iam_role_policy.jupyterhub_cost_monitoring_iam_policy[0]: Refreshing state... [id=jupyterhub_cost_monitoring_iam_role:jupyterhub_cost_monitoring_iam_policy]
aws_iam_role_policy_attachment.extra_user_policy["binder"]: Refreshing state... [id=nasa-veda-binder-20240808145901693300000001]
aws_iam_role_policy_attachment.extra_user_policy["prod"]: Refreshing state... [id=nasa-veda-prod-20230228170043753800000002]
aws_iam_role_policy_attachment.extra_user_policy["staging"]: Refreshing state... [id=nasa-veda-staging-20230228170043748900000001]
aws_s3_bucket_policy.user_bucket_access["prod.scratch"]: Refreshing state... [id=nasa-veda-scratch]
aws_s3_bucket_policy.user_bucket_access["binder.scratch-binder"]: Refreshing state... [id=nasa-veda-scratch-binder]
aws_iam_role_policies_exclusive.jupyterhub_grafana_cloudwatch: Refreshing state...
aws_s3_bucket_policy.user_bucket_access["staging.scratch-staging"]: Refreshing state... [id=nasa-veda-scratch-staging]
aws_iam_role_policies_exclusive.jupyterhub_cost_monitoring_iam_role_policies_exclusive[0]: Refreshing state...

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
  ~ update in-place
  - destroy

Terraform will perform the following actions:

  # aws_cloudwatch_metric_alarm.volume_iops_alarm["staging"] will be updated in-place
  ~ resource "aws_cloudwatch_metric_alarm" "volume_iops_alarm" {
      ~ dimensions                = {
          ~ "VolumeId" = "vol-0063ecd342e052ef5" -> "vol-0a1246ee2e07372d0"
        }
        id                        = "warn-volume-iops-exceeded"
        tags                      = {}
        # (17 unchanged attributes hidden)
    }

  # aws_cloudwatch_metric_alarm.volume_throughput_alarm["prod"] will be updated in-place
  ~ resource "aws_cloudwatch_metric_alarm" "volume_throughput_alarm" {
      ~ dimensions                = {
          ~ "VolumeId" = "vol-0a1246ee2e07372d0" -> "vol-0063ecd342e052ef5"
        }
        id                        = "warn-volume-throughput-exceeded"
        tags                      = {}
        # (17 unchanged attributes hidden)
    }

  # aws_iam_policy.extra_user_policy["binder"] will be destroyed
  # (because key ["binder"] is not in for_each map)
  - resource "aws_iam_policy" "extra_user_policy" {
      - arn              = "arn:aws:iam::444055461661:policy/nasa-veda-binder-extra-user-policy" -> null
      - attachment_count = 1 -> null
      - description      = "Extra permissions granted to users on hub binder on nasa-veda" -> null
      - id               = "arn:aws:iam::444055461661:policy/nasa-veda-binder-extra-user-policy" -> null
      - name             = "nasa-veda-binder-extra-user-policy" -> null
      - path             = "/" -> null
      - policy           = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "s3:GetObject",
                          - "s3:ListBucketVersions",
                          - "s3:ListBucket",
                          - "s3:GetBucketLocation",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:s3:::veda-data-store",
                          - "arn:aws:s3:::veda-data-store/*",
                          - "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:::nasa-waterinsight",
                          - "arn:aws:s3:::nasa-waterinsight/*",
                          - "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/*",
                          - "arn:aws:s3:::sport-lis",
                          - "arn:aws:s3:::sport-lis/*",
                          - "arn:aws:s3:::nasa-disasters",
                          - "arn:aws:s3:::nasa-disasters/*",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected/*",
                        ]
                    },
                  - {
                      - Action   = "s3:ListAllMyBuckets"
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - policy_id        = "ANPAWOY6ET4ORQWBA2VSL" -> null
      - tags             = {} -> null
      - tags_all         = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
    }

  # aws_iam_policy.extra_user_policy["prod"] will be destroyed
  # (because key ["prod"] is not in for_each map)
  - resource "aws_iam_policy" "extra_user_policy" {
      - arn              = "arn:aws:iam::444055461661:policy/nasa-veda-prod-extra-user-policy" -> null
      - attachment_count = 1 -> null
      - description      = "Extra permissions granted to users on hub prod on nasa-veda" -> null
      - id               = "arn:aws:iam::444055461661:policy/nasa-veda-prod-extra-user-policy" -> null
      - name             = "nasa-veda-prod-extra-user-policy" -> null
      - path             = "/" -> null
      - policy           = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "s3:PutObject",
                          - "s3:GetObject",
                          - "s3:ListBucketMultipartUploads",
                          - "s3:AbortMultipartUpload",
                          - "s3:ListBucketVersions",
                          - "s3:CreateBucket",
                          - "s3:ListBucket",
                          - "s3:DeleteObject",
                          - "s3:GetBucketLocation",
                          - "s3:ListMultipartUploadParts",
                          - "s3:PutObjectTagging",
                          - "s3:GetObjectTagging",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:s3:::veda-data-store",
                          - "arn:aws:s3:::veda-data-store/*",
                          - "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:::nasa-waterinsight",
                          - "arn:aws:s3:::nasa-waterinsight/*",
                          - "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:::sport-lis",
                          - "arn:aws:s3:::sport-lis/*",
                          - "arn:aws:s3:::nasa-disasters",
                          - "arn:aws:s3:::nasa-disasters/*",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected/*",
                        ]
                    },
                  - {
                      - Action   = "s3:ListAllMyBuckets"
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - policy_id        = "ANPAWOY6ET4O7CNAUSBZS" -> null
      - tags             = {} -> null
      - tags_all         = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
    }

  # aws_iam_policy.extra_user_policy["staging"] will be destroyed
  # (because key ["staging"] is not in for_each map)
  - resource "aws_iam_policy" "extra_user_policy" {
      - arn              = "arn:aws:iam::444055461661:policy/nasa-veda-staging-extra-user-policy" -> null
      - attachment_count = 1 -> null
      - description      = "Extra permissions granted to users on hub staging on nasa-veda" -> null
      - id               = "arn:aws:iam::444055461661:policy/nasa-veda-staging-extra-user-policy" -> null
      - name             = "nasa-veda-staging-extra-user-policy" -> null
      - path             = "/" -> null
      - policy           = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "s3:PutObject",
                          - "s3:GetObject",
                          - "s3:ListBucketMultipartUploads",
                          - "s3:AbortMultipartUpload",
                          - "s3:ListBucketVersions",
                          - "s3:CreateBucket",
                          - "s3:ListBucket",
                          - "s3:DeleteObject",
                          - "s3:GetBucketLocation",
                          - "s3:ListMultipartUploadParts",
                          - "s3:PutObjectTagging",
                          - "s3:GetObjectTagging",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:s3:::veda-data-store",
                          - "arn:aws:s3:::veda-data-store/*",
                          - "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:::nasa-waterinsight",
                          - "arn:aws:s3:::nasa-waterinsight/*",
                          - "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/*",
                          - "arn:aws:s3:::sport-lis",
                          - "arn:aws:s3:::sport-lis/*",
                          - "arn:aws:s3:::nasa-disasters",
                          - "arn:aws:s3:::nasa-disasters/*",
                          - "arn:aws:s3:::nasa-eodc-scratch",
                          - "arn:aws:s3:::nasa-eodc-scratch/*",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected",
                          - "arn:aws:s3:::gesdisc-cumulus-uat-protected/*",
                        ]
                    },
                  - {
                      - Action   = "s3:ListAllMyBuckets"
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - policy_id        = "ANPAWOY6ET4O3G5PDWM7C" -> null
      - tags             = {} -> null
      - tags_all         = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
    }

  # aws_iam_role.irsa_role["binder"] will be destroyed
  # (because key ["binder"] is not in for_each map)
  - resource "aws_iam_role" "irsa_role" {
      - arn                   = "arn:aws:iam::444055461661:role/nasa-veda-binder" -> null
      - assume_role_policy    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "sts:AssumeRoleWithWebIdentity"
                      - Condition = {
                          - StringEquals = {
                              - "oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC:sub" = "system:serviceaccount:binder:user-sa"
                            }
                        }
                      - Effect    = "Allow"
                      - Principal = {
                          - Federated = "arn:aws:iam::444055461661:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC"
                        }
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - create_date           = "2024-08-08T14:59:00Z" -> null
      - force_detach_policies = false -> null
      - id                    = "nasa-veda-binder" -> null
      - managed_policy_arns   = [
          - "arn:aws:iam::444055461661:policy/nasa-veda-binder-extra-user-policy",
        ] -> null
      - max_session_duration  = 3600 -> null
      - name                  = "nasa-veda-binder" -> null
      - path                  = "/" -> null
      - tags                  = {} -> null
      - tags_all              = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
      - unique_id             = "AROAWOY6ET4O5FJSQXMX4" -> null
    }

  # aws_iam_role.irsa_role["prod"] will be destroyed
  # (because key ["prod"] is not in for_each map)
  - resource "aws_iam_role" "irsa_role" {
      - arn                   = "arn:aws:iam::444055461661:role/nasa-veda-prod" -> null
      - assume_role_policy    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "sts:AssumeRoleWithWebIdentity"
                      - Condition = {
                          - StringEquals = {
                              - "oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC:sub" = "system:serviceaccount:prod:user-sa"
                            }
                        }
                      - Effect    = "Allow"
                      - Principal = {
                          - Federated = "arn:aws:iam::444055461661:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC"
                        }
                      - Sid       = ""
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - create_date           = "2023-01-23T21:18:35Z" -> null
      - force_detach_policies = false -> null
      - id                    = "nasa-veda-prod" -> null
      - managed_policy_arns   = [
          - "arn:aws:iam::444055461661:policy/nasa-veda-prod-extra-user-policy",
          - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
        ] -> null
      - max_session_duration  = 3600 -> null
      - name                  = "nasa-veda-prod" -> null
      - path                  = "/" -> null
      - tags                  = {} -> null
      - tags_all              = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
      - unique_id             = "AROAWOY6ET4OYMXU5EABJ" -> null

      - inline_policy {
          - name   = "assume-veda-upload-role" -> null
          - policy = jsonencode(
                {
                  - Statement = [
                      - {
                          - Action   = [
                              - "sts:AssumeRole",
                            ]
                          - Effect   = "Allow"
                          - Resource = [
                              - "arn:aws:iam::444055461661:role/veda-upload-to-staging-role",
                              - "arn:aws:iam::444055461661:role/brian-data-access-test",
                            ]
                          - Sid      = "Statement1"
                        },
                    ]
                  - Version   = "2012-10-17"
                }
            ) -> null
        }
    }

  # aws_iam_role.irsa_role["staging"] will be destroyed
  # (because key ["staging"] is not in for_each map)
  - resource "aws_iam_role" "irsa_role" {
      - arn                   = "arn:aws:iam::444055461661:role/nasa-veda-staging" -> null
      - assume_role_policy    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "sts:AssumeRoleWithWebIdentity"
                      - Condition = {
                          - StringEquals = {
                              - "oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC:sub" = "system:serviceaccount:staging:user-sa"
                            }
                        }
                      - Effect    = "Allow"
                      - Principal = {
                          - Federated = "arn:aws:iam::444055461661:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/22EC5DE3AFFE1B1FAC3A83FC063FA0BC"
                        }
                      - Sid       = ""
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - create_date           = "2023-01-23T21:18:35Z" -> null
      - force_detach_policies = false -> null
      - id                    = "nasa-veda-staging" -> null
      - managed_policy_arns   = [
          - "arn:aws:iam::444055461661:policy/nasa-veda-staging-extra-user-policy",
        ] -> null
      - max_session_duration  = 3600 -> null
      - name                  = "nasa-veda-staging" -> null
      - path                  = "/" -> null
      - tags                  = {} -> null
      - tags_all              = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "ManagedBy"             = "2i2c"
        } -> null
      - unique_id             = "AROAWOY6ET4OWO74RYJL7" -> null
    }

  # aws_iam_role_policy_attachment.extra_user_policy["binder"] will be destroyed
  # (because key ["binder"] is not in for_each map)
  - resource "aws_iam_role_policy_attachment" "extra_user_policy" {
      - id         = "nasa-veda-binder-20240808145901693300000001" -> null
      - policy_arn = "arn:aws:iam::444055461661:policy/nasa-veda-binder-extra-user-policy" -> null
      - role       = "nasa-veda-binder" -> null
    }

  # aws_iam_role_policy_attachment.extra_user_policy["prod"] will be destroyed
  # (because key ["prod"] is not in for_each map)
  - resource "aws_iam_role_policy_attachment" "extra_user_policy" {
      - id         = "nasa-veda-prod-20230228170043753800000002" -> null
      - policy_arn = "arn:aws:iam::444055461661:policy/nasa-veda-prod-extra-user-policy" -> null
      - role       = "nasa-veda-prod" -> null
    }

  # aws_iam_role_policy_attachment.extra_user_policy["staging"] will be destroyed
  # (because key ["staging"] is not in for_each map)
  - resource "aws_iam_role_policy_attachment" "extra_user_policy" {
      - id         = "nasa-veda-staging-20230228170043748900000001" -> null
      - policy_arn = "arn:aws:iam::444055461661:policy/nasa-veda-staging-extra-user-policy" -> null
      - role       = "nasa-veda-staging" -> null
    }

  # aws_s3_bucket.user_buckets["binder"] will be created
  + resource "aws_s3_bucket" "user_buckets" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "nasa-veda-binder"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = {
          + "2i2c.org/cluster-name" = "nasa-veda"
          + "ManagedBy"             = "2i2c"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
    }

  # aws_s3_bucket.user_buckets["prod"] will be created
  + resource "aws_s3_bucket" "user_buckets" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "nasa-veda-prod"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = {
          + "2i2c.org/cluster-name" = "nasa-veda"
          + "ManagedBy"             = "2i2c"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
    }

  # aws_s3_bucket.user_buckets["scratch"] will be updated in-place
  ~ resource "aws_s3_bucket" "user_buckets" {
        id                          = "nasa-veda-scratch"
      ~ tags                        = {
          - "2i2c:hub-name" = "prod" -> null
        }
      ~ tags_all                    = {
          - "2i2c:hub-name"         = "prod" -> null
            # (2 unchanged elements hidden)
        }
        # (10 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

  # aws_s3_bucket.user_buckets["scratch-binder"] will be destroyed
  # (because key ["scratch-binder"] is not in for_each map)
  - resource "aws_s3_bucket" "user_buckets" {
      - arn                         = "arn:aws:s3:::nasa-veda-scratch-binder" -> null
      - bucket                      = "nasa-veda-scratch-binder" -> null
      - bucket_domain_name          = "nasa-veda-scratch-binder.s3.amazonaws.com" -> null
      - bucket_regional_domain_name = "nasa-veda-scratch-binder.s3.us-west-2.amazonaws.com" -> null
      - force_destroy               = false -> null
      - hosted_zone_id              = "Z3BJ6K6RIION7M" -> null
      - id                          = "nasa-veda-scratch-binder" -> null
      - object_lock_enabled         = false -> null
      - policy                      = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Effect    = "Allow"
                      - Principal = {
                          - AWS = "arn:aws:iam::444055461661:role/nasa-veda-binder"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::nasa-veda-scratch-binder/*",
                          - "arn:aws:s3:::nasa-veda-scratch-binder",
                        ]
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - region                      = "us-west-2" -> null
      - request_payer               = "BucketOwner" -> null
      - tags                        = {
          - "2i2c:hub-name" = "binder"
        } -> null
      - tags_all                    = {
          - "2i2c.org/cluster-name" = "nasa-veda"
          - "2i2c:hub-name"         = "binder"
          - "ManagedBy"             = "2i2c"
        } -> null

      - grant {
          - id          = "999895c6156a106070c145a832b286f2da2aa4340a296c2b698879bd9dbe515f" -> null
          - permissions = [
              - "FULL_CONTROL",
            ] -> null
          - type        = "CanonicalUser" -> null
        }

      - lifecycle_rule {
          - abort_incomplete_multipart_upload_days = 0 -> null
          - enabled                                = true -> null
          - id                                     = "delete-after-expiry" -> null
          - tags                                   = {} -> null

          - expiration {
              - days                         = 1 -> null
              - expired_object_delete_marker = false -> null
            }
        }

      - server_side_encryption_configuration {
          - rule {
              - bucket_key_enabled = false -> null

              - apply_server_side_encryption_by_default {
                  - sse_algorithm = "AES256" -> null
                }
            }
        }

      - versioning {
          - enabled    = false -> null
          - mfa_delete = false -> null
        }
    }

  # aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["binder"] will be created
  + resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" {
      + bucket                                 = "nasa-veda-binder"
      + expected_bucket_owner                  = (known after apply)
      + id                                     = (known after apply)
      + transition_default_minimum_object_size = "all_storage_classes_128K"

      + rule {
          + id     = "delete-after-expiry"
          + status = "Disabled"

          + expiration {
              + days                         = 0
              + expired_object_delete_marker = false
            }

          + filter {
            }
        }
    }

  # aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["prod"] will be created
  + resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" {
      + bucket                                 = "nasa-veda-prod"
      + expected_bucket_owner                  = (known after apply)
      + id                                     = (known after apply)
      + transition_default_minimum_object_size = "all_storage_classes_128K"

      + rule {
          + id     = "delete-after-expiry"
          + status = "Disabled"

          + expiration {
              + days                         = 0
              + expired_object_delete_marker = false
            }

          + filter {
            }
        }
    }

  # aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["scratch-binder"] will be destroyed
  # (because key ["scratch-binder"] is not in for_each map)
  - resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry" {
      - bucket                                 = "nasa-veda-scratch-binder" -> null
      - id                                     = "nasa-veda-scratch-binder" -> null
      - transition_default_minimum_object_size = "all_storage_classes_128K" -> null

      - rule {
          - id     = "delete-after-expiry" -> null
          - status = "Enabled" -> null

          - expiration {
              - days                         = 1 -> null
              - expired_object_delete_marker = false -> null
            }

          - filter {
            }
        }
    }

  # aws_s3_bucket_policy.user_bucket_access["binder.scratch-binder"] will be destroyed
  # (because key ["binder.scratch-binder"] is not in for_each map)
  - resource "aws_s3_bucket_policy" "user_bucket_access" {
      - bucket = "nasa-veda-scratch-binder" -> null
      - id     = "nasa-veda-scratch-binder" -> null
      - policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Effect    = "Allow"
                      - Principal = {
                          - AWS = "arn:aws:iam::444055461661:role/nasa-veda-binder"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::nasa-veda-scratch-binder/*",
                          - "arn:aws:s3:::nasa-veda-scratch-binder",
                        ]
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
    }

  # aws_s3_bucket_policy.user_bucket_access["prod.scratch"] will be destroyed
  # (because key ["prod.scratch"] is not in for_each map)
  - resource "aws_s3_bucket_policy" "user_bucket_access" {
      - bucket = "nasa-veda-scratch" -> null
      - id     = "nasa-veda-scratch" -> null
      - policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Effect    = "Allow"
                      - Principal = {
                          - AWS = "arn:aws:iam::444055461661:role/nasa-veda-prod"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::nasa-veda-scratch/*",
                          - "arn:aws:s3:::nasa-veda-scratch",
                        ]
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
    }

  # aws_s3_bucket_policy.user_bucket_access["staging.scratch-staging"] will be destroyed
  # (because key ["staging.scratch-staging"] is not in for_each map)
  - resource "aws_s3_bucket_policy" "user_bucket_access" {
      - bucket = "nasa-veda-scratch-staging" -> null
      - id     = "nasa-veda-scratch-staging" -> null
      - policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Effect    = "Allow"
                      - Principal = {
                          - AWS = "arn:aws:iam::444055461661:role/nasa-veda-staging"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::nasa-veda-scratch-staging/*",
                          - "arn:aws:s3:::nasa-veda-scratch-staging",
                        ]
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
    }

Plan: 4 to add, 3 to change, 14 to destroy.

Changes to Outputs:
  ~ buckets                                         = {
      + binder          = (known after apply)
      + prod            = (known after apply)
      - scratch-binder  = "nasa-veda-scratch-binder"
        # (2 unchanged attributes hidden)
    }
  ~ kubernetes_sa_annotations                       = {
      - binder  = "eks.amazonaws.com/role-arn: arn:aws:iam::444055461661:role/nasa-veda-binder"
      - prod    = "eks.amazonaws.com/role-arn: arn:aws:iam::444055461661:role/nasa-veda-prod"
      - staging = "eks.amazonaws.com/role-arn: arn:aws:iam::444055461661:role/nasa-veda-staging"
    }

Warning: Invalid Attribute Combination

  with aws_s3_bucket_lifecycle_configuration.user_bucket_expiry["binder"],
  on buckets.tf line 17, in resource "aws_s3_bucket_lifecycle_configuration" "user_bucket_expiry":
  17:     expiration {

No attribute specified when one (and only one) of
[rule[0].expiration[0].date,rule[0].expiration[0].days,rule[0].expiration[0].expired_object_delete_marker] is required

This will be an error in a future version of the provider

(and one more similar warning elsewhere)

Do you want to perform these actions in workspace "nasa-veda"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: 
Apply cancelled.

Any idea what's going on?

@jjfrench

jjfrench commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

My terraform knowledge isn't the greatest 😅 but it looks like it's picking up a different var file? I didn't touch the for_each so it should still be using the user_buckets struct

I thought it might be another project's but I couldn't find any structs like
{
"binder": { ... },
"prod": { ... },
"scratch": { ... }
}

also expected some change to scratch-staging somewhere given the changes to the bucket definition but maybe it's compiling the same even after the change since it doesn't change what's deployed

@agoose77
agoose77 force-pushed the main branch 2 times, most recently from 6498e7e to 41988cb Compare June 23, 2026 15:40
@agoose77
agoose77 force-pushed the main branch 2 times, most recently from 525365c to ab6687e Compare July 6, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants