Skip to content

feat(auth): group claims, public and validate-only clients for app.yaml - #138

Merged
Alexanderamiri merged 10 commits into
mainfrom
feat/app-auth-features
Oct 23, 2026
Merged

Alexanderamiri merged 10 commits into
mainfrom
feat/app-auth-features

Conversation

@Alexanderamiri

Copy link
Copy Markdown
Member

Stacked on #134 (per-team execution roles). Merge #134 first and GitHub retargets this to main.

What cupcake/frosting need for login to work.

Why

  • Groups never reach tokens. cupcake's backend requires helter in cognito:groups. Federated (GoogleSAML) users arrive with only an email, and team-provisioner only adds users who already signed in. The internal pool has 0 users and empty groups, so every login would get a 401, and auth.groups did nothing.
  • The frontend needs a public client. frosting does OIDC from the browser (oidc-client-ts with PKCE). The platform only made confidential clients with a secret, which a browser can't use.
  • The backend needs no client. cupcake's backend only verifies tokens. auth: internal would create a client it never uses.
  • The apps read their own env var names: NUXT_PUBLIC_OIDC_CLIENT_ID, OIDC_WELL_KNOWN_URL.

What changed

  • Group claims:
    • team-provisioner records registry membership (groups.yaml groups with cognito: true, plus team-<name>) in a new javabin-auth-memberships table.
    • A new pre-token-generation V2 trigger, javabin-auth-claims (internal pool, ESSENTIALS tier), puts the user's groups into cognito:groups of the ID and access token at every sign-in and refresh. Native Cognito groups are kept.
    • It refuses the token when the client has allowed groups and the user is in none.
  • app-auth-sync:
    • client_type confidential/public; a type change replaces the client, since the secret setting is immutable.
    • allowed_groups written to the table and removed with the client.
    • http://localhost callbacks allowed for local dev.
  • cognito-app-client module: client_type (none requests no client), allowed_groups, and a well_known_url output.
  • app.yaml:
    • auth.client: confidential|public|none
    • auth.groups now restricts sign-in
    • auth.env aliases injected values to the app's own names
    • COGNITO_WELL_KNOWN_URL is injected
  • Docs: app-yaml-reference (client types, groups, aliases), lambda-functions, reusable-modules, CLAUDE.md.

Cupcake's app.yaml after this:

# frosting
auth:
  pool: internal
  client: public
  groups: [helter]
  callback_urls: [https://cupcake.javazone.no/, https://cupcake.javazone.no/auth/callback, http://localhost:3000/]
  env: {COGNITO_CLIENT_ID: NUXT_PUBLIC_OIDC_CLIENT_ID, COGNITO_ISSUER_URL: NUXT_PUBLIC_OIDC_AUTHORITY}
# cupcake backend
auth:
  pool: internal
  client: none
  env: {COGNITO_WELL_KNOWN_URL: OIDC_WELL_KNOWN_URL}

Checks

  • Generator tests (19) and Lambda tests (35) pass. New ones cover the auth-claims group union, deny, and caching; public clients, type switching, allowed groups, and localhost-vs-localhost.evil.com; and generator client types and aliases.
  • Generated configs for both cupcake apps pass terraform validate against the changed modules, as does terraform/platform.

Rollout notes

  • Memberships fill on the next registry provisioning run. Re-run provision-groups and provision-teams in javaBin/registry after apply. Until then tokens carry no registry groups, as today.
  • Adding the trigger modifies aws_cognito_user_pool.internal in place (lambda_config). The GoogleSAML IdP, which was created outside Terraform, is a separate resource and is not touched.

🤖 Generated with Claude Code

Alexanderamiri and others added 7 commits October 23, 2026 16:09
- The shared javabin-ecs-execution role could read every /javabin/apps/*
  parameter and every team could pass it, so any team could mount another
  team's secrets in its own task definition. Each registered team now gets
  javabin-ecs-exec-{team}, reading only its own path; the developer
  boundary only lets a team pass its own. The shared role keeps image pull
  and logs only.
- DenyShared did not cover ec2:AuthorizeSecurityGroup*/RevokeSecurityGroup*,
  so any team CI role could open every app to every other or remove the
  ALB rule on the shared ECS tasks SG (confirmed with the IAM simulator).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Both Lambdas took the repo from the request payload, and the gate's sign
action (approve a HIGH-risk plan) was open to any caller. Code running in
an app's platform job (a Terraform external data source, say) could claim
another repo's team credentials or sign its own override.

Callers now send a GitHub OIDC token; the Lambdas verify it against
GitHub's JWKS (RS256 via openssl, no new dependencies) and read the repo
from its signed claims. check also requires the plan to be the repo's own,
and sign requires a token from approve-override.yml in javaBin/platform in
the override-approval environment, recording the token's actor. The
override workflow passes inputs via env instead of interpolating them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
sync-registered-teams listed every GitHub org team, so non-app teams like
owners and developer got AWS CI and deploy roles. Use teams/*.yaml in
javaBin/registry, the documented source of truth.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Moved to its own PR: switching to registry teams destroys the roles of 21
non-app org teams (148 resources), which plans HIGH and needs a board
override. The security fixes here should not wait on that.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The previous revert also undid the CLAUDE.md entries for the execution
roles, the OIDC token script and the broker fix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Internal-pool tokens had no cognito:groups: federated users only bring an
email, and team-provisioner only adds users who already signed in. So
cupcake, which requires helter, would have refused everyone, and
app.yaml auth.groups changed nothing.

team-provisioner now records registry membership in a
javabin-auth-memberships table, and a pre-token-generation V2 trigger
(javabin-auth-claims) puts the user's groups into the ID and access token
at every sign-in and refresh. When an app client lists allowed groups and
the user is in none, the trigger refuses the token.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- auth.client: public creates a client without a secret, for browser
  apps doing OIDC with PKCE (frosting); none requests no client and only
  injects issuer values, for APIs that verify another client's tokens
  (cupcake backend).
- auth.groups is sent as the client's allowed groups.
- auth.env exposes injected values under names the app already reads
  (NUXT_PUBLIC_OIDC_CLIENT_ID, OIDC_WELL_KNOWN_URL).
- COGNITO_WELL_KNOWN_URL is injected; http://localhost callbacks are
  allowed for local development.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Alexanderamiri
Alexanderamiri requested a review from a team as a code owner October 23, 2026 14:41
@github-actions

Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 78 to add, 32 to change, 1 to destroy.

Plan output
Acquiring state lock. This may take a few moments...
aws_ssm_parameter.atlassian_api_key: Refreshing state... [id=/javabin/platform/atlassian-api-key]
aws_ssm_parameter.atlassian_org_id: Refreshing state... [id=/javabin/platform/atlassian-org-id]

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:

  # module.iam.aws_iam_policy.developer_boundary will be updated in-place
  ~ resource "aws_iam_policy" "developer_boundary" {
        id               = "arn:aws:iam::553637109631:policy/javabin-developer-boundary"
        name             = "javabin-developer-boundary"
      ~ policy           = jsonencode(
          ~ {
              ~ Statement = [
                    # (9 unchanged elements hidden)
                    {
                        Action      = "*"
                        Condition   = {
                            Null            = {
                                "aws:ResourceTag/team" = "false"
                            }
                            StringNotEquals = {
                                "aws:ResourceTag/team" = [
                                    "${aws:PrincipalTag/team}",
                                    "shared",
                                ]
                            }
                        }
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:s3:::javabin-terraform-state-553637109631",
                            "arn:aws:s3:::javabin-terraform-state-553637109631/*",
                            "arn:aws:dynamodb:eu-central-1:553637109631:table/javabin-terraform-app-locks",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631/*",
                        ]
                        Sid         = "DenyXTeam"
                    },
                  ~ {
                      ~ Action    = [
                            # (15 unchanged elements hidden)
                            "sns:SetTopicAttributes",
                          + "ec2:AuthorizeSecurityGroup*",
                          + "ec2:RevokeSecurityGroup*",
                        ]
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = [
                            "ec2:DeleteTags",
                            "ec2:CreateTags",
                            "ecs:TagResource",
                            "ecs:UntagResource",
                            "elasticloadbalancing:AddTags",
                            "elasticloadbalancing:RemoveTags",
                            "iam:TagRole",
                            "iam:UntagRole",
                            "sns:TagResource",
                            "sns:UntagResource",
                        ]
                        Condition = {
                            StringEquals = {
                                "aws:ResourceTag/team" = [
                                    "shared",
                                    "platform",
                                ]
                            }
                        }
                        Effect    = "Deny"
                        Resource  = "*"
                        Sid       = "DenyTagStrip"
                    },
                    {
                        Action   = [
                            "ssm:GetParameter*",
                            "ssm:GetParametersByPath",
                        ]
                        Effect   = "Deny"
                        Resource = [
                            "arn:aws:ssm:*:*:parameter/javabin/platform/*",
                            "arn:aws:ssm:*:*:parameter/javabin/slack/*",
                            "arn:aws:ssm:*:*:parameter/javabin/platform-overrides/*",
                        ]
                        Sid      = "DenyPlatSSM"
                    },
                  ~ {
                      ~ NotResource = [
                            "arn:aws:iam::*:role/${aws:PrincipalTag/team}-*",
                          - "arn:aws:iam::*:role/javabin-ecs-execution",
                          + "arn:aws:iam::*:role/javabin-ecs-exec-${aws:PrincipalTag/team}",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action      = [
                            "logs:GetLogEvents",
                            "logs:FilterLogEvents",
                            "logs:StartQuery",
                            "logs:GetQueryResults",
                        ]
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*",
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*:*",
                        ]
                        Sid         = "DenyXLogs"
                    },
                    # (3 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        tags             = {
            "Name" = "javabin-developer-boundary"
        }
        # (6 unchanged attributes hidden)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cake"
          + "for-team" = "cake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cake"
          + "environment" = "production"
          + "for-team"    = "cake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["commandchimps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-commandchimps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-commandchimps"
          + "for-team" = "commandchimps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-commandchimps"
          + "environment" = "production"
          + "for-team"    = "commandchimps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cupcake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cupcake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cupcake"
          + "for-team" = "cupcake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cupcake"
          + "environment" = "production"
          + "for-team"    = "cupcake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["developer"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-developer"
          + "for-team" = "developer"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-developer"
          + "environment" = "production"
          + "for-team"    = "developer"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["java-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-java-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-java-no"
          + "for-team" = "java-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-java-no"
          + "environment" = "production"
          + "for-team"    = "java-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-no"
          + "for-team" = "javazone-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-no"
          + "environment" = "production"
          + "for-team"    = "javazone-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-work"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-work"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-work"
          + "for-team" = "javazone-work"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-work"
          + "environment" = "production"
          + "for-team"    = "javazone-work"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["jzwatch"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-jzwatch"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-jzwatch"
          + "for-team" = "jzwatch"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-jzwatch"
          + "environment" = "production"
          + "for-team"    = "jzwatch"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["owners"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-owners"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-owners"
          + "for-team" = "owners"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-owners"
          + "environment" = "production"
          + "for-team"    = "owners"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["partnermanagement"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-partnermanagement"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-partnermanagement"
          + "for-team" = "partnermanagement"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-partnermanagement"
          + "environment" = "production"
          + "for-team"    = "partnermanagement"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-apps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-apps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-apps"
          + "for-team" = "team-apps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-apps"
          + "environment" = "production"
          + "for-team"    = "team-apps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus"
          + "for-team" = "team-cibus"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus"
          + "environment" = "production"
          + "for-team"    = "team-cibus"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus2"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus2"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus2"
          + "for-team" = "team-cibus2"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus2"
          + "environment" = "production"
          + "for-team"    = "team-cibus2"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-ems"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-ems"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-ems"
          + "for-team" = "team-ems"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-ems"
          + "environment" = "production"
          + "for-team"    = "team-ems"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-incogito"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-incogito"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-incogito"
          + "for-team" = "team-incogito"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-incogito"
          + "environment" = "production"
          + "for-team"    = "team-incogito"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-badge"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-badge"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-badge"
          + "for-team" = "team-javazone-badge"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-badge"
          + "environment" = "production"
          + "for-team"    = "team-javazone-badge"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-video"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-video"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-video"
          + "for-team" = "team-javazone-video"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-video"
          + "environment" = "production"
          + "for-team"    = "team-javazone-video"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-jz-text-adventure"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-jz-text-adventure"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-jz-text-adventure"
          + "for-team" = "team-jz-text-adventure"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-jz-text-adventure"
          + "environment" = "production"
          + "for-team"    = "team-jz-text-adventure"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-portal"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-portal"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-portal"
          + "for-team" = "team-portal"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-portal"
          + "environment" = "production"
          + "for-team"    = "team-portal"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-scala-training-code"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-scala-training-code"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-scala-training-code"
          + "for-team" = "team-scala-training-code"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-scala-training-code"
          + "environment" = "production"
          + "for-team"    = "team-scala-training-code"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-submitit"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-submitit"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-submitit"
          + "for-team" = "team-submitit"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-submitit"
          + "environment" = "production"
          + "for-team"    = "team-submitit"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teammoosehead"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teammoosehead"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teammoosehead"
          + "for-team" = "teammoosehead"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teammoosehead"
          + "environment" = "production"
          + "for-team"    = "teammoosehead"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teamteknologihuset"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teamteknologihuset"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teamteknologihuset"
          + "for-team" = "teamteknologihuset"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teamteknologihuset"
          + "environment" = "production"
          + "for-team"    = "teamteknologihuset"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["testteam"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-testteam"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-testteam"
          + "for-team" = "testteam"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-testteam"
          + "environment" = "production"
          + "for-team"    = "testteam"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["commandchimps"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-commandchimps:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "commandchimps"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/commandchimps-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cupcake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cupcake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cupcake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cupcake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["developer"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-developer:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "developer"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/developer-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["java-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-java-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "java-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/java-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-work"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-work:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-work"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-work-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["jzwatch"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-jzwatch:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "jzwatch"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDe

LLM Review

Risk: 🟡 MEDIUM

Plan updates the developer permissions boundary (adds EC2 security group authorize/revoke actions and changes the ECS execution role exception) and creates many per-team ECS execution roles, with no destructive actions visible in the truncated output.

  • 🔒 [security] Developer boundary policy gains ec2:AuthorizeSecurityGroup* and ec2:RevokeSecurityGroup* allowances. Developers could modify security group rules within their team scope; the DenyXTeam statement is the main guard, so verify that shared/platform security groups are protected by tag conditions and that these actions cannot open ingress to 0.0.0.0/0 on platform SGs (e.g., alb, ecs_tasks).
  • 🔒 [security] The boundary's NotResource exception changes from javabin-ecs-execution to javabin-ecs-exec-${aws:PrincipalTag/team}. This is a narrowing of role-passing exemptions and appears intentional, but confirm the existing javabin-ecs-execution role is no longer needed by any team and that the templated name cannot be spoofed via principal tags.
  • 🔒 [security] Thirty-plus new IAM roles (javabin-ecs-exec-) are created, each with permissions_boundary set to javabin-org-boundary and tagged team=shared. Permissions boundary is correctly applied. Review the attached policies (not visible in truncated output) to ensure they grant only ECS task execution needs and not secrets/SSM access beyond the intended scope.
  • ✅ [routine] New roles are pure creates with no destruction visible in the reviewed portion. Output is truncated, so remaining changes (possible deletions or further boundary edits) could not be fully verified.
  • 💰 [cost] IAM roles themselves are free; no billable resources (NAT, RDS, ALB) appear in the visible portion of the plan.

…roups

Review feedback on #138:
- Removed or no-longer-cognito groups kept their member rows, so users
  kept those groups in tokens forever. A full group sync now prunes them
  (team-<name> and client rows are left alone).
- A provisioner payload without member lists no longer overwrites the
  recorded membership with an empty list.
- app-auth-sync refuses to record a client without its allowed groups
  when the table is not configured, instead of silently dropping the
  restriction.
- Docs: validate-only APIs accept any pool client's token; changing
  auth.client replaces the client, so redeploy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 78 to add, 32 to change, 1 to destroy.

Plan output
Acquiring state lock. This may take a few moments...
aws_ssm_parameter.atlassian_api_key: Refreshing state... [id=/javabin/platform/atlassian-api-key]
aws_ssm_parameter.atlassian_org_id: Refreshing state... [id=/javabin/platform/atlassian-org-id]

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:

  # module.iam.aws_iam_policy.developer_boundary will be updated in-place
  ~ resource "aws_iam_policy" "developer_boundary" {
        id               = "arn:aws:iam::553637109631:policy/javabin-developer-boundary"
        name             = "javabin-developer-boundary"
      ~ policy           = jsonencode(
          ~ {
              ~ Statement = [
                    # (9 unchanged elements hidden)
                    {
                        Action      = "*"
                        Condition   = {
                            Null            = {
                                "aws:ResourceTag/team" = "false"
                            }
                            StringNotEquals = {
                                "aws:ResourceTag/team" = [
                                    "${aws:PrincipalTag/team}",
                                    "shared",
                                ]
                            }
                        }
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:s3:::javabin-terraform-state-553637109631",
                            "arn:aws:s3:::javabin-terraform-state-553637109631/*",
                            "arn:aws:dynamodb:eu-central-1:553637109631:table/javabin-terraform-app-locks",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631/*",
                        ]
                        Sid         = "DenyXTeam"
                    },
                  ~ {
                      ~ Action    = [
                            # (15 unchanged elements hidden)
                            "sns:SetTopicAttributes",
                          + "ec2:AuthorizeSecurityGroup*",
                          + "ec2:RevokeSecurityGroup*",
                        ]
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = [
                            "ec2:DeleteTags",
                            "ec2:CreateTags",
                            "ecs:TagResource",
                            "ecs:UntagResource",
                            "elasticloadbalancing:AddTags",
                            "elasticloadbalancing:RemoveTags",
                            "iam:TagRole",
                            "iam:UntagRole",
                            "sns:TagResource",
                            "sns:UntagResource",
                        ]
                        Condition = {
                            StringEquals = {
                                "aws:ResourceTag/team" = [
                                    "shared",
                                    "platform",
                                ]
                            }
                        }
                        Effect    = "Deny"
                        Resource  = "*"
                        Sid       = "DenyTagStrip"
                    },
                    {
                        Action   = [
                            "ssm:GetParameter*",
                            "ssm:GetParametersByPath",
                        ]
                        Effect   = "Deny"
                        Resource = [
                            "arn:aws:ssm:*:*:parameter/javabin/platform/*",
                            "arn:aws:ssm:*:*:parameter/javabin/slack/*",
                            "arn:aws:ssm:*:*:parameter/javabin/platform-overrides/*",
                        ]
                        Sid      = "DenyPlatSSM"
                    },
                  ~ {
                      ~ NotResource = [
                            "arn:aws:iam::*:role/${aws:PrincipalTag/team}-*",
                          - "arn:aws:iam::*:role/javabin-ecs-execution",
                          + "arn:aws:iam::*:role/javabin-ecs-exec-${aws:PrincipalTag/team}",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action      = [
                            "logs:GetLogEvents",
                            "logs:FilterLogEvents",
                            "logs:StartQuery",
                            "logs:GetQueryResults",
                        ]
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*",
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*:*",
                        ]
                        Sid         = "DenyXLogs"
                    },
                    # (3 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        tags             = {
            "Name" = "javabin-developer-boundary"
        }
        # (6 unchanged attributes hidden)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cake"
          + "for-team" = "cake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cake"
          + "environment" = "production"
          + "for-team"    = "cake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["commandchimps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-commandchimps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-commandchimps"
          + "for-team" = "commandchimps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-commandchimps"
          + "environment" = "production"
          + "for-team"    = "commandchimps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cupcake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cupcake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cupcake"
          + "for-team" = "cupcake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cupcake"
          + "environment" = "production"
          + "for-team"    = "cupcake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["developer"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-developer"
          + "for-team" = "developer"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-developer"
          + "environment" = "production"
          + "for-team"    = "developer"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["java-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-java-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-java-no"
          + "for-team" = "java-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-java-no"
          + "environment" = "production"
          + "for-team"    = "java-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-no"
          + "for-team" = "javazone-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-no"
          + "environment" = "production"
          + "for-team"    = "javazone-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-work"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-work"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-work"
          + "for-team" = "javazone-work"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-work"
          + "environment" = "production"
          + "for-team"    = "javazone-work"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["jzwatch"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-jzwatch"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-jzwatch"
          + "for-team" = "jzwatch"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-jzwatch"
          + "environment" = "production"
          + "for-team"    = "jzwatch"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["owners"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-owners"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-owners"
          + "for-team" = "owners"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-owners"
          + "environment" = "production"
          + "for-team"    = "owners"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["partnermanagement"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-partnermanagement"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-partnermanagement"
          + "for-team" = "partnermanagement"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-partnermanagement"
          + "environment" = "production"
          + "for-team"    = "partnermanagement"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-apps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-apps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-apps"
          + "for-team" = "team-apps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-apps"
          + "environment" = "production"
          + "for-team"    = "team-apps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus"
          + "for-team" = "team-cibus"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus"
          + "environment" = "production"
          + "for-team"    = "team-cibus"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus2"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus2"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus2"
          + "for-team" = "team-cibus2"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus2"
          + "environment" = "production"
          + "for-team"    = "team-cibus2"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-ems"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-ems"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-ems"
          + "for-team" = "team-ems"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-ems"
          + "environment" = "production"
          + "for-team"    = "team-ems"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-incogito"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-incogito"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-incogito"
          + "for-team" = "team-incogito"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-incogito"
          + "environment" = "production"
          + "for-team"    = "team-incogito"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-badge"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-badge"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-badge"
          + "for-team" = "team-javazone-badge"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-badge"
          + "environment" = "production"
          + "for-team"    = "team-javazone-badge"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-video"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-video"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-video"
          + "for-team" = "team-javazone-video"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-video"
          + "environment" = "production"
          + "for-team"    = "team-javazone-video"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-jz-text-adventure"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-jz-text-adventure"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-jz-text-adventure"
          + "for-team" = "team-jz-text-adventure"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-jz-text-adventure"
          + "environment" = "production"
          + "for-team"    = "team-jz-text-adventure"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-portal"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-portal"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-portal"
          + "for-team" = "team-portal"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-portal"
          + "environment" = "production"
          + "for-team"    = "team-portal"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-scala-training-code"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-scala-training-code"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-scala-training-code"
          + "for-team" = "team-scala-training-code"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-scala-training-code"
          + "environment" = "production"
          + "for-team"    = "team-scala-training-code"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-submitit"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-submitit"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-submitit"
          + "for-team" = "team-submitit"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-submitit"
          + "environment" = "production"
          + "for-team"    = "team-submitit"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teammoosehead"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teammoosehead"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teammoosehead"
          + "for-team" = "teammoosehead"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teammoosehead"
          + "environment" = "production"
          + "for-team"    = "teammoosehead"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teamteknologihuset"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teamteknologihuset"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teamteknologihuset"
          + "for-team" = "teamteknologihuset"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teamteknologihuset"
          + "environment" = "production"
          + "for-team"    = "teamteknologihuset"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["testteam"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-testteam"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-testteam"
          + "for-team" = "testteam"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-testteam"
          + "environment" = "production"
          + "for-team"    = "testteam"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["commandchimps"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-commandchimps:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "commandchimps"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/commandchimps-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cupcake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cupcake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cupcake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cupcake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["developer"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-developer:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "developer"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/developer-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["java-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-java-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "java-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/java-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-work"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-work:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-work"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-work-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["jzwatch"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-jzwatch:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "jzwatch"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDe

LLM Review

Risk: 🟡 MEDIUM

Plan updates the developer permissions boundary (adds EC2 security group authorize/revoke actions and changes an ECS execution role exclusion) and creates many per-team ECS execution roles, all with the org permissions boundary attached; no destruction of databases or public exposure is visible in the truncated output.

  • 🔒 [security] Developer boundary is modified to allow ec2:AuthorizeSecurityGroup* and ec2:RevokeSecurityGroup*. These are in an Allow-style statement of the boundary, so developers' own IAM policies could now change security group rules. This widens what delegated developers can do to network access and should be checked against the intent, given the DenyTagStrip and DenyXTeam statements only partly limit it.
  • 🔒 [security] The NotResource exclusion changes from arn:aws:iam:::role/javabin-ecs-execution to arn:aws:iam:::role/javabin-ecs-exec-${aws:PrincipalTag/team}. This changes which roles the boundary's role-scoped deny covers. The new name is per-team, so confirm that the old shared execution role is still protected and that the new pattern cannot be abused by a team tag value that matches another team's role.
  • 🔒 [security] Creates many new ECS execution roles (ecs_exec_team, one per team) with the javabin-org-boundary permissions boundary and an ecs-tasks trust policy. Tags show team=shared while for-team varies. The team tag mismatch could affect tag-based access conditions, so verify the tagging is intentional.
  • 💥 [destruction] No destroy actions are visible in the truncated output. The remaining plan (after the first ~10 role creations) was cut off, so the full set of changes, including any deletions or replacements, cannot be confirmed. Review the complete plan before applying.
  • 💰 [cost] IAM roles and policies are free. No new NAT gateways, RDS, or load balancers are visible in the shown portion of the plan.
  • ✅ [routine] Most of the plan is refresh output with no drift. The visible changes are IAM-only, so overall risk is rated MEDIUM because of the boundary change to security group permissions, not because of any destructive operation.

Base automatically changed from fix/team-isolation to main October 23, 2026 15:14
# Conflicts:
#	CLAUDE.md
#	docs/apply-gate.md
#	scripts/github-oidc-token.sh
#	scripts/invoke-override-sign.sh
#	terraform/lambda-src/shared/github_oidc.py
#	terraform/lambda-src/tests/test_github_oidc.py
@github-actions

Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 78 to add, 32 to change, 1 to destroy.

Plan output
Acquiring state lock. This may take a few moments...
aws_ssm_parameter.atlassian_api_key: Refreshing state... [id=/javabin/platform/atlassian-api-key]
aws_ssm_parameter.atlassian_org_id: Refreshing state... [id=/javabin/platform/atlassian-org-id]

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:

  # module.iam.aws_iam_policy.developer_boundary will be updated in-place
  ~ resource "aws_iam_policy" "developer_boundary" {
        id               = "arn:aws:iam::553637109631:policy/javabin-developer-boundary"
        name             = "javabin-developer-boundary"
      ~ policy           = jsonencode(
          ~ {
              ~ Statement = [
                    # (9 unchanged elements hidden)
                    {
                        Action      = "*"
                        Condition   = {
                            Null            = {
                                "aws:ResourceTag/team" = "false"
                            }
                            StringNotEquals = {
                                "aws:ResourceTag/team" = [
                                    "${aws:PrincipalTag/team}",
                                    "shared",
                                ]
                            }
                        }
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:s3:::javabin-terraform-state-553637109631",
                            "arn:aws:s3:::javabin-terraform-state-553637109631/*",
                            "arn:aws:dynamodb:eu-central-1:553637109631:table/javabin-terraform-app-locks",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631/*",
                        ]
                        Sid         = "DenyXTeam"
                    },
                  ~ {
                      ~ Action    = [
                            # (9 unchanged elements hidden)
                            "iam:DeleteRolePolicy",
                          + "iam:UpdateAssumeRolePolicy",
                            "iam:PutRolePolicy",
                            # (4 unchanged elements hidden)
                            "sns:SetTopicAttributes",
                          + "ec2:AuthorizeSecurityGroup*",
                          + "ec2:RevokeSecurityGroup*",
                        ]
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = [
                            "ec2:DeleteTags",
                            "ec2:CreateTags",
                            "ecs:TagResource",
                            "ecs:UntagResource",
                            "elasticloadbalancing:AddTags",
                            "elasticloadbalancing:RemoveTags",
                            "iam:TagRole",
                            "iam:UntagRole",
                            "sns:TagResource",
                            "sns:UntagResource",
                        ]
                        Condition = {
                            StringEquals = {
                                "aws:ResourceTag/team" = [
                                    "shared",
                                    "platform",
                                ]
                            }
                        }
                        Effect    = "Deny"
                        Resource  = "*"
                        Sid       = "DenyTagStrip"
                    },
                    {
                        Action   = [
                            "ssm:GetParameter*",
                            "ssm:GetParametersByPath",
                        ]
                        Effect   = "Deny"
                        Resource = [
                            "arn:aws:ssm:*:*:parameter/javabin/platform/*",
                            "arn:aws:ssm:*:*:parameter/javabin/slack/*",
                            "arn:aws:ssm:*:*:parameter/javabin/platform-overrides/*",
                        ]
                        Sid      = "DenyPlatSSM"
                    },
                  ~ {
                      ~ NotResource = [
                            "arn:aws:iam::*:role/${aws:PrincipalTag/team}-*",
                          - "arn:aws:iam::*:role/javabin-ecs-execution",
                          + "arn:aws:iam::*:role/javabin-ecs-exec-${aws:PrincipalTag/team}",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action      = [
                            "logs:GetLogEvents",
                            "logs:FilterLogEvents",
                            "logs:StartQuery",
                            "logs:GetQueryResults",
                        ]
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*",
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*:*",
                        ]
                        Sid         = "DenyXLogs"
                    },
                    # (3 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        tags             = {
            "Name" = "javabin-developer-boundary"
        }
        # (6 unchanged attributes hidden)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cake"
          + "for-team" = "cake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cake"
          + "environment" = "production"
          + "for-team"    = "cake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["commandchimps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-commandchimps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-commandchimps"
          + "for-team" = "commandchimps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-commandchimps"
          + "environment" = "production"
          + "for-team"    = "commandchimps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cupcake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cupcake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cupcake"
          + "for-team" = "cupcake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cupcake"
          + "environment" = "production"
          + "for-team"    = "cupcake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["developer"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-developer"
          + "for-team" = "developer"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-developer"
          + "environment" = "production"
          + "for-team"    = "developer"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["java-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-java-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-java-no"
          + "for-team" = "java-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-java-no"
          + "environment" = "production"
          + "for-team"    = "java-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-no"
          + "for-team" = "javazone-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-no"
          + "environment" = "production"
          + "for-team"    = "javazone-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-work"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-work"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-work"
          + "for-team" = "javazone-work"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-work"
          + "environment" = "production"
          + "for-team"    = "javazone-work"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["jzwatch"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-jzwatch"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-jzwatch"
          + "for-team" = "jzwatch"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-jzwatch"
          + "environment" = "production"
          + "for-team"    = "jzwatch"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["owners"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-owners"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-owners"
          + "for-team" = "owners"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-owners"
          + "environment" = "production"
          + "for-team"    = "owners"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["partnermanagement"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-partnermanagement"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-partnermanagement"
          + "for-team" = "partnermanagement"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-partnermanagement"
          + "environment" = "production"
          + "for-team"    = "partnermanagement"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-apps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-apps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-apps"
          + "for-team" = "team-apps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-apps"
          + "environment" = "production"
          + "for-team"    = "team-apps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus"
          + "for-team" = "team-cibus"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus"
          + "environment" = "production"
          + "for-team"    = "team-cibus"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus2"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus2"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus2"
          + "for-team" = "team-cibus2"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus2"
          + "environment" = "production"
          + "for-team"    = "team-cibus2"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-ems"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-ems"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-ems"
          + "for-team" = "team-ems"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-ems"
          + "environment" = "production"
          + "for-team"    = "team-ems"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-incogito"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-incogito"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-incogito"
          + "for-team" = "team-incogito"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-incogito"
          + "environment" = "production"
          + "for-team"    = "team-incogito"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-badge"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-badge"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-badge"
          + "for-team" = "team-javazone-badge"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-badge"
          + "environment" = "production"
          + "for-team"    = "team-javazone-badge"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-video"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-video"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-video"
          + "for-team" = "team-javazone-video"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-video"
          + "environment" = "production"
          + "for-team"    = "team-javazone-video"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-jz-text-adventure"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-jz-text-adventure"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-jz-text-adventure"
          + "for-team" = "team-jz-text-adventure"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-jz-text-adventure"
          + "environment" = "production"
          + "for-team"    = "team-jz-text-adventure"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-portal"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-portal"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-portal"
          + "for-team" = "team-portal"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-portal"
          + "environment" = "production"
          + "for-team"    = "team-portal"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-scala-training-code"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-scala-training-code"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-scala-training-code"
          + "for-team" = "team-scala-training-code"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-scala-training-code"
          + "environment" = "production"
          + "for-team"    = "team-scala-training-code"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-submitit"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-submitit"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-submitit"
          + "for-team" = "team-submitit"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-submitit"
          + "environment" = "production"
          + "for-team"    = "team-submitit"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teammoosehead"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teammoosehead"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teammoosehead"
          + "for-team" = "teammoosehead"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teammoosehead"
          + "environment" = "production"
          + "for-team"    = "teammoosehead"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teamteknologihuset"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teamteknologihuset"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teamteknologihuset"
          + "for-team" = "teamteknologihuset"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teamteknologihuset"
          + "environment" = "production"
          + "for-team"    = "teamteknologihuset"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["testteam"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-testteam"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-testteam"
          + "for-team" = "testteam"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-testteam"
          + "environment" = "production"
          + "for-team"    = "testteam"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["commandchimps"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-commandchimps:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "commandchimps"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/commandchimps-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cupcake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cupcake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cupcake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cupcake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["developer"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-developer:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "developer"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/developer-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["java-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-java-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "java-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/java-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-work"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-work:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-work"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-work-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["jzwatch"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-jzwatch:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "jzwatch"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
      

LLM Review

Risk: 🔴 HIGH

Plan updates the developer permissions boundary (adds ec2 security group authorize/revoke and iam:UpdateAssumeRolePolicy to the allowed actions, and changes the ECS execution role exemption) and creates many new per-team ECS execution roles; the visible output is truncated, so the full plan should be checked before apply.

  • 🔒 [security] The developer permissions boundary is loosened: the 'DenyXTeam'/allow statement now permits ec2:AuthorizeSecurityGroup* and ec2:RevokeSecurityGroup* and iam:UpdateAssumeRolePolicy. Developers could open security groups (potentially to 0.0.0.0/0) and rewrite trust policies on roles within their scope. This is a privilege-escalation path and should be explicitly reviewed and approved before apply.
  • 🔒 [security] The NotResource exemption for the ECS execution role changes from the shared 'javabin-ecs-execution' role to a per-team pattern 'javabin-ecs-exec-${aws:PrincipalTag/team}'. This changes which IAM roles developers can access and needs verification that the new pattern cannot match platform roles.
  • 🔒 [security] Twenty-plus new IAM roles (javabin-ecs-exec-) are created with the org permissions boundary attached. The boundary is correct, but tags show team=shared while for-team differs; confirm the team tag does not affect the boundary's team-scoped conditions.
  • 💥 [destruction] No resources are destroyed in the visible portion of the plan. The truncation hides the remainder, so any destroy or replace actions in the hidden part cannot be assessed; request the full plan output.
  • 💰 [cost] IAM roles, policies and boundary updates carry no direct cost. No NAT gateways, load balancers, RDS instances or other billable resources are visible in the shown portion.

# Conflicts:
#	CLAUDE.md
#	docs/lambda-functions.md
@github-actions

Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 82 to add, 57 to change, 1 to destroy.

Plan output
aws_ssm_parameter.atlassian_org_id: Refreshing state... [id=/javabin/platform/atlassian-org-id]
aws_ssm_parameter.atlassian_api_key: Refreshing state... [id=/javabin/platform/atlassian-api-key]

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:

  # module.iam.aws_iam_policy.developer_boundary will be updated in-place
  ~ resource "aws_iam_policy" "developer_boundary" {
        id               = "arn:aws:iam::553637109631:policy/javabin-developer-boundary"
        name             = "javabin-developer-boundary"
      ~ policy           = jsonencode(
          ~ {
              ~ Statement = [
                    # (9 unchanged elements hidden)
                    {
                        Action      = "*"
                        Condition   = {
                            Null            = {
                                "aws:ResourceTag/team" = "false"
                            }
                            StringNotEquals = {
                                "aws:ResourceTag/team" = [
                                    "${aws:PrincipalTag/team}",
                                    "shared",
                                ]
                            }
                        }
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:s3:::javabin-terraform-state-553637109631",
                            "arn:aws:s3:::javabin-terraform-state-553637109631/*",
                            "arn:aws:dynamodb:eu-central-1:553637109631:table/javabin-terraform-app-locks",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631",
                            "arn:aws:s3:::javabin-ci-plan-artifacts-553637109631/*",
                        ]
                        Sid         = "DenyXTeam"
                    },
                  ~ {
                      ~ Action    = [
                            # (9 unchanged elements hidden)
                            "iam:DeleteRolePolicy",
                          + "iam:UpdateAssumeRolePolicy",
                            "iam:PutRolePolicy",
                            # (4 unchanged elements hidden)
                            "sns:SetTopicAttributes",
                          + "ec2:AuthorizeSecurityGroup*",
                          + "ec2:RevokeSecurityGroup*",
                        ]
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = [
                            "ec2:DeleteTags",
                            "ec2:CreateTags",
                            "ecs:TagResource",
                            "ecs:UntagResource",
                            "elasticloadbalancing:AddTags",
                            "elasticloadbalancing:RemoveTags",
                            "iam:TagRole",
                            "iam:UntagRole",
                            "sns:TagResource",
                            "sns:UntagResource",
                        ]
                        Condition = {
                            StringEquals = {
                                "aws:ResourceTag/team" = [
                                    "shared",
                                    "platform",
                                ]
                            }
                        }
                        Effect    = "Deny"
                        Resource  = "*"
                        Sid       = "DenyTagStrip"
                    },
                    {
                        Action   = [
                            "ssm:GetParameter*",
                            "ssm:GetParametersByPath",
                        ]
                        Effect   = "Deny"
                        Resource = [
                            "arn:aws:ssm:*:*:parameter/javabin/platform/*",
                            "arn:aws:ssm:*:*:parameter/javabin/slack/*",
                            "arn:aws:ssm:*:*:parameter/javabin/platform-overrides/*",
                        ]
                        Sid      = "DenyPlatSSM"
                    },
                  ~ {
                      ~ NotResource = [
                            "arn:aws:iam::*:role/${aws:PrincipalTag/team}-*",
                          - "arn:aws:iam::*:role/javabin-ecs-execution",
                          + "arn:aws:iam::*:role/javabin-ecs-exec-${aws:PrincipalTag/team}",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action      = [
                            "logs:GetLogEvents",
                            "logs:FilterLogEvents",
                            "logs:StartQuery",
                            "logs:GetQueryResults",
                        ]
                        Effect      = "Deny"
                        NotResource = [
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*",
                            "arn:aws:logs:*:*:log-group:/ecs/${aws:PrincipalTag/team}/*:*",
                        ]
                        Sid         = "DenyXLogs"
                    },
                    # (3 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        tags             = {
            "Name" = "javabin-developer-boundary"
        }
        # (6 unchanged attributes hidden)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cake"
          + "for-team" = "cake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cake"
          + "environment" = "production"
          + "for-team"    = "cake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["commandchimps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-commandchimps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-commandchimps"
          + "for-team" = "commandchimps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-commandchimps"
          + "environment" = "production"
          + "for-team"    = "commandchimps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["cupcake"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-cupcake"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-cupcake"
          + "for-team" = "cupcake"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-cupcake"
          + "environment" = "production"
          + "for-team"    = "cupcake"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["developer"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-developer"
          + "for-team" = "developer"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-developer"
          + "environment" = "production"
          + "for-team"    = "developer"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["java-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-java-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-java-no"
          + "for-team" = "java-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-java-no"
          + "environment" = "production"
          + "for-team"    = "java-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-no"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-no"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-no"
          + "for-team" = "javazone-no"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-no"
          + "environment" = "production"
          + "for-team"    = "javazone-no"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["javazone-work"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-javazone-work"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-javazone-work"
          + "for-team" = "javazone-work"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-javazone-work"
          + "environment" = "production"
          + "for-team"    = "javazone-work"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["jzwatch"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-jzwatch"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-jzwatch"
          + "for-team" = "jzwatch"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-jzwatch"
          + "environment" = "production"
          + "for-team"    = "jzwatch"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["owners"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-owners"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-owners"
          + "for-team" = "owners"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-owners"
          + "environment" = "production"
          + "for-team"    = "owners"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["partnermanagement"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-partnermanagement"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-partnermanagement"
          + "for-team" = "partnermanagement"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-partnermanagement"
          + "environment" = "production"
          + "for-team"    = "partnermanagement"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-apps"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-apps"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-apps"
          + "for-team" = "team-apps"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-apps"
          + "environment" = "production"
          + "for-team"    = "team-apps"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus"
          + "for-team" = "team-cibus"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus"
          + "environment" = "production"
          + "for-team"    = "team-cibus"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-cibus2"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-cibus2"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-cibus2"
          + "for-team" = "team-cibus2"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-cibus2"
          + "environment" = "production"
          + "for-team"    = "team-cibus2"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-ems"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-ems"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-ems"
          + "for-team" = "team-ems"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-ems"
          + "environment" = "production"
          + "for-team"    = "team-ems"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-incogito"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-incogito"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-incogito"
          + "for-team" = "team-incogito"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-incogito"
          + "environment" = "production"
          + "for-team"    = "team-incogito"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-badge"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-badge"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-badge"
          + "for-team" = "team-javazone-badge"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-badge"
          + "environment" = "production"
          + "for-team"    = "team-javazone-badge"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-javazone-video"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-javazone-video"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-javazone-video"
          + "for-team" = "team-javazone-video"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-javazone-video"
          + "environment" = "production"
          + "for-team"    = "team-javazone-video"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-jz-text-adventure"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-jz-text-adventure"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-jz-text-adventure"
          + "for-team" = "team-jz-text-adventure"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-jz-text-adventure"
          + "environment" = "production"
          + "for-team"    = "team-jz-text-adventure"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-portal"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-portal"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-portal"
          + "for-team" = "team-portal"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-portal"
          + "environment" = "production"
          + "for-team"    = "team-portal"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-scala-training-code"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-scala-training-code"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-scala-training-code"
          + "for-team" = "team-scala-training-code"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-scala-training-code"
          + "environment" = "production"
          + "for-team"    = "team-scala-training-code"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["team-submitit"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-team-submitit"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-team-submitit"
          + "for-team" = "team-submitit"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-team-submitit"
          + "environment" = "production"
          + "for-team"    = "team-submitit"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teammoosehead"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teammoosehead"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teammoosehead"
          + "for-team" = "teammoosehead"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teammoosehead"
          + "environment" = "production"
          + "for-team"    = "teammoosehead"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["teamteknologihuset"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-teamteknologihuset"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-teamteknologihuset"
          + "for-team" = "teamteknologihuset"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-teamteknologihuset"
          + "environment" = "production"
          + "for-team"    = "teamteknologihuset"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role.ecs_exec_team["testteam"] will be created
  + resource "aws_iam_role" "ecs_exec_team" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "javabin-ecs-exec-testteam"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + permissions_boundary  = "arn:aws:iam::553637109631:policy/javabin-org-boundary"
      + tags                  = {
          + "Name"     = "javabin-ecs-exec-testteam"
          + "for-team" = "testteam"
          + "team"     = "shared"
        }
      + tags_all              = {
          + "Name"        = "javabin-ecs-exec-testteam"
          + "environment" = "production"
          + "for-team"    = "testteam"
          + "managed-by"  = "terraform"
          + "repo"        = "javaBin/platform"
          + "service"     = "platform"
          + "team"        = "shared"
        }
      + unique_id             = (known after apply)
    }

  # module.iam.aws_iam_role_policy.ci_app_broker will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_app_broker" {
        id     = "javabin-ci-app-broker:invoke-ci-broker-only"
        name   = "invoke-ci-broker-only"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = "lambda:InvokeFunction"
                      - Effect   = "Allow"
                      - Resource = "arn:aws:lambda:eu-central-1:553637109631:function:javabin-ci-broker"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["commandchimps"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-commandchimps:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "commandchimps"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/commandchimps-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["cupcake"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-cupcake:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "cupcake"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/cupcake-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["developer"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-developer:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "developer"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/developer-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["java-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-java-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "java-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/java-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-no"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-no:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-no"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-no-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["javazone-work"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-javazone-work:ecs-deploy"
        name   = "ecs-deploy"
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = [
                          - "ecs:UpdateService",
                          - "ecs:DescribeServices",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "aws:ResourceTag/team" = "javazone-work"
                            }
                        }
                      - Effect    = "Allow"
                      - Resource  = "*"
                      - Sid       = "EcsServiceManagement"
                    },
                  - {
                      - Action   = [
                          - "ecs:DescribeTaskDefinition",
                          - "ecs:RegisterTaskDefinition",
                          - "ecs:DeregisterTaskDefinition",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                      - Sid      = "EcsTaskDefinitionManagement"
                    },
                  - {
                      - Action   = [
                          - "iam:PassRole",
                        ]
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:iam::553637109631:role/javabin-ecs-execution",
                          - "arn:aws:iam::553637109631:role/javazone-work-*",
                        ]
                      - Sid      = "PassRole"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.iam.aws_iam_role_policy.ci_deploy_ecs["jzwatch"] will be updated in-place
  ~ resource "aws_iam_role_policy" "ci_deploy_ecs" {
        id     = "javabin-ci-deploy-jzwatch:ecs-deploy"
        nam

LLM Review

Risk: 🔴 HIGH

Plan modifies the developer permission boundary (adds security group authorize/revoke and iam:UpdateAssumeRolePolicy permissions, and changes the ECS execution role exemption) and creates many new ECS execution IAM roles, with the visible portion of output truncated before all changes are reviewed.

  • 🔒 [security] Developer permissions boundary (javabin-developer-boundary) is updated to allow ec2:AuthorizeSecurityGroup* and ec2:RevokeSecurityGroup*, and iam:UpdateAssumeRolePolicy. Developers could open security groups (potentially to the internet) and change trust policies of roles, weakening the boundary that constrains team roles.
  • 🔒 [security] The boundary's NotResource exemption changes from the shared javabin-ecs-execution role to a per-team pattern javabin-ecs-exec-${aws:PrincipalTag/team}. This changes which IAM roles developers can reach and needs verification that the pattern cannot match platform roles.
  • 🔒 [security] About 20+ new aws_iam_role.ecs_exec_team roles are created for teams, each with permissions_boundary javabin-org-boundary and tags team=shared. Their permission policies are not visible in the truncated output, so their privileges cannot be assessed.
  • 💥 [destruction] No resource destruction is visible in the reviewed portion. The output is truncated, so the remainder of the plan (possibly including destroy or replace actions) must be checked before approval.
  • 💰 [cost] New IAM roles and policies are free. No billable resources such as NAT gateways, RDS, or load balancers are visible in the reviewed portion.

@Alexanderamiri
Alexanderamiri merged commit 23a4219 into main Oct 23, 2026
4 checks passed
@Alexanderamiri
Alexanderamiri deleted the feat/app-auth-features branch October 23, 2026 15:21
Alexanderamiri added a commit that referenced this pull request Oct 23, 2026
## Why
Applying #137 and #138 failed (run 39978752602):
`reading ZIP file (identity/builds/auth_claims.zip): no such file or
directory`.
The plan job uploads only `terraform/platform/lambdas/builds/` as the
`lambda-zips` artifact. #138 added a Lambda in the `identity` module,
whose zip is built at `identity/builds/`. A saved plan doesn't rebuild
`archive_file` outputs, so the apply job needs every zip.

## What changed
- Upload `${TF_ROOT}/*/builds/*.zip` (paths relative to `TF_ROOT`), and
fail if nothing matches.
- Download into `${TF_ROOT}/`, so each zip lands in its own module's
`builds/`.

## Checks
actionlint. The real check is this PR's own merge run, which must apply
the pending #137/#138 changes (10 to add, 30 to change, MEDIUM).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Alexanderamiri added a commit that referenced this pull request Oct 24, 2026
…ole plan (#147)

## Why

Reviews kept saying "Plan is truncated; the remaining changes ... could
not be reviewed". Where the input was actually cut:

| Reviews | Cut by | Real? |
|---|---|---|
| #134, #135 (14:14, 14:31), #137, #138, #139 on 2026-10-23, before #141
merged at 15:43 | the old 80k cut in `review-plan.py` | yes. These
include the quoted "other roles, Lambdas, or networking" review (#135,
14:31) |
| #135 on 2026-10-24 09:53 (run 40083680062) | #141's 400k cap: the plan
was 830k chars, 231 destroys (destroy diffs print every attribute) |
yes. The model saw 28 of 231 changes and correctly said so |
| #145 (2026-10-24 09:25, 09:40), #146, app reviews (cupcake#258,
frosting#249/#250) | none | no truncation claims |

Ruled out:
- (a) The PR comment's 60k cut: the review reads `plan-output.txt`
itself. The cut was silent to humans, though, so the comment now says
when it is cut.
- (b) `run-plan.sh` writes the full `-no-color` output with no
head/tail.
- (c) platform-ci reviews `terraform/platform/plan-output.txt`, the full
file.
- (e) No reviews hit `max_tokens`. Converse is still called without
inferenceConfig (no maxTokens set, on purpose), but a `stopReason:
max_tokens` answer is now discarded instead of trusted.
- (f) The Lambda reads the whole S3 object.

## What changed

- `scripts/review-plan.py`: no default input cap. The whole plan goes to
Haiku 5.5, which has a 1M-token context. `REVIEW_MAX_PLAN_CHARS` still
turns on the existing notice + change-list mode if it is set.
- The prompt now opens with `COMPLETE PLAN` (change count + the `Plan:`
line) and says not to call the plan truncated. It also explains that
Terraform hides parts of every plan by design: `# (N unchanged
attributes/blocks/elements hidden)`, `(sensitive value)`, `(known after
apply)` and partial `jsonencode` diffs are not truncation.
- `stopReason == "max_tokens"` → returns None. Platform CI records
FAILED; the Lambda retries.
- `scripts/post-plan-comment.sh`: adds a notice when the plan is cut at
60k (GitHub's comment limit) and keeps the cut-off point configurable.
- Docs: `docs/ci-workflow.md`.

Trade-off: a plan larger than the model's context now fails the review
(FAILED, override available) instead of being cut.

## Checks

- `python3 -m unittest discover -s scripts/tests`: 38 OK. New tests: the
complete-plan declaration, the elision markers, no default cap (2M-char
plan), an 830k destroy plan sent whole, max_tokens discarded, and the
comment cut notice.
- `python3 -m unittest discover -s terraform/lambda-src/tests`: 63 OK.
New tests: COMPLETE PLAN reaches Bedrock, and a max_tokens answer is
retried.
- `terraform fmt -check -recursive terraform`: OK. `shellcheck
scripts/post-plan-comment.sh`: OK. No workflow changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.

1 participant