Skip to content

Commit f041103

Browse files
Team-prefixed resource naming + boundary enforcement (#84)
## Summary Replace `javabin-` prefix with `{team}-` prefix on all app resource names. Team is now part of the resource name, enabling ARN-based IAM scoping for services that don't support tag-based conditions. ### Why Tags alone don't scope all resources — CloudWatch logs, metrics, SG rules, and some create operations don't support `aws:ResourceTag` in IAM conditions. Team in the resource name gives us a second scoping mechanism via ARN patterns. ### Naming convention | Before | After | |--------|-------| | `javabin-moresleep` (ECS/ECR/IAM) | `web-team-moresleep` | | `/ecs/moresleep` (log group) | `/ecs/web-team/moresleep` | | `javabin-uploads-{acct}` (S3) | `web-team-uploads-{acct}` | | `/javabin/apps/moresleep/key` (SSM) | `/javabin/apps/web-team/moresleep/key` | Platform resources keep `javabin-*` prefix (unchanged). ### Boundary enforcement (terraform/org/, human-applied) `DenyNonTeamPrefixedCreation` blocks resource creation unless name matches `${aws:PrincipalTag/team}-*`. Uses `NotResource` with IAM policy variables. ### Developer permission set - Tag-scoped reads with `StringEquals` (strict — no access to untagged resources) - ARN-scoped reads for logs (`/ecs/{team}/*`) and SSM (`/javabin/apps/{team}/*`) - Metrics: global read (not scoped — CloudWatch metrics aren't resources) ### Migration Option A: new resources get team prefix going forward. Existing resources keep current names until redeployed. ## Manual steps after merge The boundary and identity-center changes are in `terraform/org/` — apply manually: ```bash cd terraform/org AWS_PROFILE=javabin terraform apply ``` ## Test plan - [ ] CI plan shows no platform infra changes (modules only affect app repos) - [ ] Generate expanded TF for a test app → verify team-prefixed names - [ ] Manual: apply org boundary + identity center - [ ] Verify developer console access scoped to team logs/SSM
1 parent 1a2d96f commit f041103

23 files changed

Lines changed: 159 additions & 72 deletions

File tree

‎scripts/registry.py‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"cardinality": "singleton",
7575
"vars": {
7676
"name": "yaml:name",
77+
"team": "yaml:team",
7778
},
7879
"rename": "ecr",
7980
"output_map": {
@@ -93,7 +94,7 @@
9394
"cardinality": "singleton",
9495
"vars": {
9596
"name": "yaml:name",
96-
"project": f"const:{PROJECT}",
97+
"team": "yaml:team",
9798
"vpc_id": "ref:platform.vpc_id",
9899
"port": "yaml:compute.port|default:8000",
99100
"health_check_path": "yaml:compute.health_check|default:/health",
@@ -124,7 +125,7 @@
124125
"cardinality": "singleton",
125126
"vars": {
126127
"name": "yaml:name",
127-
"project": f"const:{PROJECT}",
128+
"team": "yaml:team",
128129
"region": "env:AWS_REGION",
129130
"aws_account_id": "env:AWS_ACCOUNT_ID",
130131
"permissions_boundary_arn": "ref:platform.developer_boundary_arn",
@@ -156,6 +157,7 @@
156157
"cardinality": "singleton",
157158
"vars": {
158159
"name": "yaml:name",
160+
"team": "yaml:team",
159161
"cluster_id": "ref:platform.ecs_cluster_id",
160162
"image": "expr:${ref:ecr.repository_url}:latest",
161163
"cpu": "yaml:compute.cpu|default:512",
@@ -191,7 +193,7 @@
191193
"condition": "yaml:alarms.enabled|default:true",
192194
"vars": {
193195
"name": "yaml:name",
194-
"project": f"const:{PROJECT}",
196+
"team": "yaml:team",
195197
"service": "yaml:name",
196198
"cluster_name": "ref:platform.ecs_cluster_name",
197199
"sns_topic_arns": "list:data.aws_sns_topic.alerts.arn",
@@ -232,7 +234,7 @@
232234
"instance_key": "name",
233235
"vars": {
234236
"name": "item:name",
235-
"project": "yaml:name",
237+
"team": "yaml:team",
236238
"aws_account_id": "env:AWS_ACCOUNT_ID",
237239
"service": "yaml:name",
238240
"versioning": "item:versioning|default:true",
@@ -266,7 +268,7 @@
266268
"engine_filter": "dynamodb",
267269
"vars": {
268270
"name": "item:name",
269-
"project": "yaml:name",
271+
"team": "yaml:team",
270272
"service": "yaml:name",
271273
"hash_key": "item:hash_key|default:id",
272274
"hash_key_type": "item:hash_key_type|default:S",
@@ -302,7 +304,8 @@
302304
"engine_filter": "postgres",
303305
"vars": {
304306
"name": "item:name",
305-
"project": "yaml:name",
307+
"team": "yaml:team",
308+
"project": f"const:{PROJECT}",
306309
"engine_version": "item:engine_version|default:16",
307310
"instance_class": "item:instance_class|default:db.t3.micro",
308311
"allocated_storage": "item:allocated_storage|default:20",
@@ -335,7 +338,8 @@
335338
"instance_key": "name",
336339
"vars": {
337340
"name": "item:name",
338-
"project": "yaml:name",
341+
"team": "yaml:team",
342+
"project": f"const:{PROJECT}",
339343
"service": "yaml:name",
340344
"description": "item:description|default:",
341345
},
@@ -358,7 +362,7 @@
358362
"instance_key": "name",
359363
"vars": {
360364
"name": "item:name",
361-
"project": "yaml:name",
365+
"team": "yaml:team",
362366
"service": "yaml:name",
363367
"visibility_timeout_seconds": "item:visibility_timeout|default:30",
364368
"retention_seconds": "item:retention_seconds|default:345600",

‎terraform/modules/ecr-repo/main.tf‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
################################################################################
44

55
resource "aws_ecr_repository" "this" {
6-
name = var.name
6+
name = "${var.team}-${var.name}"
77
image_tag_mutability = "MUTABLE"
88

99
image_scanning_configuration {
@@ -15,7 +15,7 @@ resource "aws_ecr_repository" "this" {
1515
}
1616

1717
tags = {
18-
Name = var.name
18+
Name = "${var.team}-${var.name}"
1919
}
2020
}
2121

‎terraform/modules/ecr-repo/variables.tf‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ variable "name" {
33
type = string
44
}
55

6+
variable "team" {
7+
description = "Team name, used as resource name prefix for team-scoped isolation"
8+
type = string
9+
}
10+
611
variable "scan_on_push" {
712
description = "Enable image scanning on push"
813
type = bool

‎terraform/modules/ecs-service/main.tf‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
################################################################################
44

55
resource "aws_cloudwatch_log_group" "this" {
6-
name = "/ecs/${var.name}"
6+
name = "/ecs/${var.team}/${var.name}"
77
retention_in_days = 30
88
}
99

@@ -12,7 +12,7 @@ resource "aws_cloudwatch_log_group" "this" {
1212
################################################################################
1313

1414
resource "aws_ecs_task_definition" "this" {
15-
family = var.name
15+
family = "${var.team}-${var.name}"
1616
requires_compatibilities = ["FARGATE"]
1717
network_mode = "awsvpc"
1818
cpu = var.cpu
@@ -79,7 +79,7 @@ resource "aws_ecs_task_definition" "this" {
7979
################################################################################
8080

8181
resource "aws_ecs_service" "this" {
82-
name = var.name
82+
name = "${var.team}-${var.name}"
8383
cluster = var.cluster_id
8484
task_definition = aws_ecs_task_definition.this.arn
8585
desired_count = var.desired_count

‎terraform/modules/ecs-service/variables.tf‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ variable "name" {
33
type = string
44
}
55

6+
variable "team" {
7+
description = "Team name, used as resource name prefix for team-scoped isolation"
8+
type = string
9+
}
10+
611
variable "cluster_id" {
712
description = "ECS cluster ID"
813
type = string

‎terraform/modules/service-alarm/main.tf‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
################################################################################
44

55
resource "aws_cloudwatch_metric_alarm" "cpu_high" {
6-
alarm_name = "${var.project}-${var.name}-cpu-high"
6+
alarm_name = "${var.team}-${var.name}-cpu-high"
77
comparison_operator = "GreaterThanThreshold"
88
evaluation_periods = 3
99
metric_name = "CPUUtilization"
@@ -21,13 +21,13 @@ resource "aws_cloudwatch_metric_alarm" "cpu_high" {
2121
}
2222

2323
tags = {
24-
Name = "${var.project}-${var.name}-cpu-high"
24+
Name = "${var.team}-${var.name}-cpu-high"
2525
service = var.service
2626
}
2727
}
2828

2929
resource "aws_cloudwatch_metric_alarm" "memory_high" {
30-
alarm_name = "${var.project}-${var.name}-memory-high"
30+
alarm_name = "${var.team}-${var.name}-memory-high"
3131
comparison_operator = "GreaterThanThreshold"
3232
evaluation_periods = 3
3333
metric_name = "MemoryUtilization"
@@ -45,14 +45,14 @@ resource "aws_cloudwatch_metric_alarm" "memory_high" {
4545
}
4646

4747
tags = {
48-
Name = "${var.project}-${var.name}-memory-high"
48+
Name = "${var.team}-${var.name}-memory-high"
4949
service = var.service
5050
}
5151
}
5252

5353
resource "aws_cloudwatch_metric_alarm" "unhealthy_targets" {
5454
count = var.enable_alb_alarms ? 1 : 0
55-
alarm_name = "${var.project}-${var.name}-unhealthy-targets"
55+
alarm_name = "${var.team}-${var.name}-unhealthy-targets"
5656
comparison_operator = "GreaterThanThreshold"
5757
evaluation_periods = 2
5858
metric_name = "UnHealthyHostCount"
@@ -70,14 +70,14 @@ resource "aws_cloudwatch_metric_alarm" "unhealthy_targets" {
7070
}
7171

7272
tags = {
73-
Name = "${var.project}-${var.name}-unhealthy-targets"
73+
Name = "${var.team}-${var.name}-unhealthy-targets"
7474
service = var.service
7575
}
7676
}
7777

7878
resource "aws_cloudwatch_metric_alarm" "target_5xx" {
7979
count = var.enable_alb_alarms ? 1 : 0
80-
alarm_name = "${var.project}-${var.name}-5xx"
80+
alarm_name = "${var.team}-${var.name}-5xx"
8181
comparison_operator = "GreaterThanThreshold"
8282
evaluation_periods = 2
8383
metric_name = "HTTPCode_Target_5XX_Count"
@@ -96,7 +96,7 @@ resource "aws_cloudwatch_metric_alarm" "target_5xx" {
9696
}
9797

9898
tags = {
99-
Name = "${var.project}-${var.name}-5xx"
99+
Name = "${var.team}-${var.name}-5xx"
100100
service = var.service
101101
}
102102
}

‎terraform/modules/service-alarm/variables.tf‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ variable "name" {
33
type = string
44
}
55

6-
variable "project" {
7-
description = "Project name prefix"
6+
variable "team" {
7+
description = "Team name, used as resource name prefix for team-scoped isolation"
88
type = string
99
}
1010

‎terraform/modules/service-bucket/main.tf‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
################################################################################
44

55
resource "aws_s3_bucket" "this" {
6-
bucket = "${var.project}-${var.name}-${var.aws_account_id}"
6+
bucket = "${var.team}-${var.name}-${var.aws_account_id}"
77

88
tags = {
9-
Name = "${var.project}-${var.name}"
9+
Name = "${var.team}-${var.name}"
1010
service = var.service
1111
}
1212
}

‎terraform/modules/service-bucket/variables.tf‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
variable "name" {
2-
description = "Bucket purpose (e.g. 'data', 'uploads'). Bucket name: {project}-{name}-{account_id}"
2+
description = "Bucket purpose (e.g. 'data', 'uploads'). Bucket name: {team}-{name}-{account_id}"
33
type = string
44
}
55

6-
variable "project" {
7-
description = "Project name prefix"
6+
variable "team" {
7+
description = "Team name, used as resource name prefix for team-scoped isolation"
88
type = string
99
}
1010

‎terraform/modules/service-database/main.tf‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
################################################################################
44

55
resource "aws_dynamodb_table" "this" {
6-
name = "${var.project}-${var.name}"
6+
name = "${var.team}-${var.name}"
77
billing_mode = var.billing_mode
88
hash_key = var.hash_key
99

@@ -36,7 +36,7 @@ resource "aws_dynamodb_table" "this" {
3636
}
3737

3838
tags = {
39-
Name = "${var.project}-${var.name}"
39+
Name = "${var.team}-${var.name}"
4040
service = var.service
4141
}
4242
}

0 commit comments

Comments
 (0)