Skip to content

Commit 87a210b

Browse files
Enforce team name constraints and fix TG name overflow (#88)
## Summary - Add team name validation in team provisioner: `^[a-z]{1,12}$` (lowercase letters only, max 12 chars) - Rename excluded team references: `platform-owners` → `platform` everywhere - Update registered teams: `platform-test-team` → `testteam` - Fix ALB target group name overflow: truncate + 6-char hash suffix when >32 chars - Update app-yaml-reference.md with team constraints and `{team}-{name}` naming table ## Why The `{team}-{service}` naming pattern hits AWS limits (ALB TG: 32 chars) with long team names. This enforces short team names at the provisioner level and adds a safety truncation in the routing module. ## Files changed - `terraform/lambda-src/team_provisioner/handler.py` — `_validate_team_name()` function - `terraform/lambda-src/ci_broker/handler.py` — excluded team → `platform` - `terraform/modules/service-routing/main.tf` — TG name truncation - `scripts/*.sh`, `scripts/*.py` — excluded team → `platform` - `.github/CODEOWNERS` — `@javaBin/platform` - `docs/app-yaml-reference.md` — naming constraints and table - `terraform/platform/registered-teams.auto.tfvars` — `testteam` ## IAM impact - Terraform will destroy `javabin-ci-team-platform-test-team` and create `javabin-ci-team-testteam` - Same for deploy roles ## Test plan - [ ] Merge registry PR first (team YAMLs) - [ ] Merge this PR - [ ] Verify platform CI passes (plan + apply) - [ ] Merge test app PR and verify CI uses new team name
1 parent 689f327 commit 87a210b

9 files changed

Lines changed: 61 additions & 20 deletions

File tree

.github/CODEOWNERS

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
* @javaBin/platform-owners
2-
terraform/org/ @javaBin/platform-owners
3-
terraform/platform/iam/ @javaBin/platform-owners
4-
terraform/platform/monitoring/ @javaBin/platform-owners
1+
* @javaBin/platform
2+
terraform/org/ @javaBin/platform
3+
terraform/platform/iam/ @javaBin/platform
4+
terraform/platform/monitoring/ @javaBin/platform

docs/app-yaml-reference.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ Used for: ECS service name, ECR repo name, IAM role names, CloudWatch log groups
6565
6666
Team that owns this service. Must match a file in `javaBin/registry/teams/`.
6767

68+
Team names must be **lowercase letters only** (a-z), no hyphens, digits, or symbols. Max 12 characters. This constraint ensures resource names fit within AWS limits (e.g. ALB target groups: 32 chars).
69+
6870
```yaml
6971
team: core
7072
```
7173

72-
Used for: resource tagging, budget allocation, access control.
74+
Used for: resource name prefix (`{team}-{service}`), ABAC tagging, budget allocation, access control.
7375

7476
### compute
7577

@@ -361,17 +363,20 @@ Generated files have a `# GENERATED FROM app.yaml` marker. The script only overw
361363

362364
## Naming Conventions
363365

366+
All app resources are prefixed with the team name for ABAC enforcement.
367+
364368
| Resource | Name Pattern |
365369
|----------|-------------|
366-
| ECS service | `{name}` |
367-
| ECR repo | `{name}` |
368-
| S3 bucket | `javabin-{bucket_name}-{account_id}` |
369-
| DynamoDB table | `javabin-{table_name}` |
370-
| SQS queue | `javabin-{queue_name}` |
371-
| RDS instance | `{db_name}` (identifier) |
372-
| SSM (secrets) | `/javabin/apps/{service}/{secret_name}` |
373-
| IAM task role | `javabin-{name}` |
374-
| CloudWatch logs | `/ecs/javabin/{name}` |
370+
| ECS service | `{team}-{name}` |
371+
| ECR repo | `{team}-{name}` |
372+
| ALB target group | `{team}-{name}` (max 32 chars, truncated+hashed if over) |
373+
| S3 bucket | `{team}-{name}-{account_id}` |
374+
| DynamoDB table | `{team}-{name}` |
375+
| SQS queue | `{team}-{name}` |
376+
| RDS instance | `{team}-{name}` |
377+
| SSM (secrets) | `/javabin/apps/{team}/{service}/{secret_name}` |
378+
| IAM task role | `{team}-{name}` |
379+
| CloudWatch logs | `/ecs/{team}/{name}` |
375380
| DNS record | `{routing.host}` |
376381
| SSM (Cognito) | `/javabin/platform-apps/{name}/cognito-*` |
377382

scripts/ensure-tf-boilerplate.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ PROJECT="javabin"
2626
TEAM=""
2727
if command -v gh >/dev/null 2>&1; then
2828
TEAM=$(gh api "/repos/${GITHUB_REPOSITORY}/teams" \
29-
--jq '[.[] | select(.slug != "platform-owners")] | .[0].slug // ""' 2>/dev/null || true)
29+
--jq '[.[] | select(.slug != "platform")] | .[0].slug // ""' 2>/dev/null || true)
3030
fi
3131
[ -z "$TEAM" ] && TEAM="unknown"
3232

scripts/resolve-team.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ set -e
1414
REPO="${GITHUB_REPOSITORY:?GITHUB_REPOSITORY required}"
1515

1616
TEAM=$(gh api "/repos/${REPO}/teams" \
17-
--jq '[.[] | select(.slug != "platform-owners")] | .[0].slug // empty' 2>/dev/null || true)
17+
--jq '[.[] | select(.slug != "platform")] | .[0].slug // empty' 2>/dev/null || true)
1818

1919
if [ -z "$TEAM" ]; then
2020
echo "ERROR: repo ${REPO} does not belong to any GitHub team."

scripts/sync-registered-teams.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
GITHUB_API = "https://api.github.com"
2525

2626
# Platform-internal teams that don't get app CI roles
27-
EXCLUDED_TEAMS = {"platform-owners"}
27+
EXCLUDED_TEAMS = {"platform"}
2828

2929

3030
def github_get(path, token):

terraform/lambda-src/ci_broker/handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"deploy": f"{PROJECT}-ci-deploy-",
4343
}
4444

45-
EXCLUDED_TEAMS = {"platform-owners"}
45+
EXCLUDED_TEAMS = {"platform"}
4646

4747

4848
def _get_ssm(param_name):

terraform/lambda-src/team_provisioner/handler.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@
6565
)
6666
BUDGET_ENFORCEMENT_TOPIC_ARN = os.environ.get("BUDGET_ENFORCEMENT_TOPIC_ARN", "")
6767

68+
# Team name constraints: lowercase letters only (a-z), max 12 characters.
69+
# This keeps resource names within AWS limits (ALB TG: 32 chars for {team}-{service}).
70+
import re
71+
_TEAM_NAME_RE = re.compile(r"^[a-z]{1,12}$")
72+
73+
74+
def _validate_team_name(name):
75+
"""Return True if the team name meets naming constraints."""
76+
if not _TEAM_NAME_RE.match(name):
77+
logger.warning(
78+
"Invalid team name '%s' — must be 1-12 lowercase letters (a-z), no hyphens/digits/symbols",
79+
name,
80+
)
81+
return False
82+
return True
83+
84+
6885
# javaBin horizontal white logo PNG — loaded from the Lambda zip at cold start.
6986
# CID-embedded in welcome emails to avoid "trust this email" prompts in Outlook.
7087
# Source file: terraform/lambda-src/team_provisioner/javabin-logo-white.png
@@ -1892,6 +1909,13 @@ def handler(event, context):
18921909
)
18931910
continue
18941911

1912+
if not _validate_team_name(team_name):
1913+
results[team_name] = {
1914+
"error": "invalid team name — must be 1-12 lowercase letters only (a-z), "
1915+
"no hyphens, digits, or special characters"
1916+
}
1917+
continue
1918+
18951919
if not team.get("description"):
18961920
logger.warning(
18971921
"Team %s missing required 'description' — skipping",

terraform/modules/service-routing/main.tf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@
22
# ALB Target Group
33
################################################################################
44

5+
locals {
6+
# ALB target group names are limited to 32 characters.
7+
# Use full name if it fits, otherwise truncate and append a 6-char hash suffix
8+
# to avoid collisions. Other resources don't have this limit.
9+
full_name = "${var.team}-${var.name}"
10+
tg_name = (
11+
length(local.full_name) <= 32
12+
? local.full_name
13+
: "${substr(local.full_name, 0, 25)}-${substr(sha256(local.full_name), 0, 6)}"
14+
)
15+
}
16+
517
resource "aws_lb_target_group" "this" {
6-
name = "${var.team}-${var.name}"
18+
name = local.tg_name
719
port = var.port
820
protocol = "HTTP"
921
vpc_id = var.vpc_id

terraform/platform/registered-teams.auto.tfvars

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
# Source of truth: GitHub teams in javaBin org
33

44
registered_teams = [
5-
"platform-test-team",
5+
"testteam",
66
]

0 commit comments

Comments
 (0)