diff --git a/terraform/hcp_iam.tf b/terraform/hcp_iam.tf index bb77db2..e739ccc 100644 --- a/terraform/hcp_iam.tf +++ b/terraform/hcp_iam.tf @@ -1086,10 +1086,14 @@ resource "aws_iam_role_policy" "hcptf_apply_services" { policy = data.aws_iam_policy_document.hcptf_apply_services.json } -resource "aws_iam_role_policy" "hcptf_apply_ecs" { - name = "afterhours-shift-manager-ecs" - role = aws_iam_role.hcptf_apply.id - policy = data.aws_iam_policy_document.hcptf_apply_ecs.json +# Customer-managed: the apply role already has two inlines (scoped-iam + +# services). A third PutRolePolicy exceeds the 10KB combined inline limit +# in seahaven-prod. CreatePolicy still needs the hcptf-bootstrap window. +resource "aws_iam_policy" "hcptf_apply_ecs" { + name = "afterhours-shift-manager-ecs" + path = "/tf-managed/" + description = "ECS, ALB, ECR, SQS, and VPC permissions for hcptf-afterhours-shift-manager" + policy = data.aws_iam_policy_document.hcptf_apply_ecs.json } resource "aws_iam_role_policy" "hcptf_plan_refresh" { @@ -1104,8 +1108,10 @@ resource "aws_iam_role_policy_attachment" "hcptf_plan_view_only" { } resource "aws_iam_role_policy_attachments_exclusive" "hcptf_apply" { - role_name = aws_iam_role.hcptf_apply.name - policy_arns = [] + role_name = aws_iam_role.hcptf_apply.name + policy_arns = [ + aws_iam_policy.hcptf_apply_ecs.arn, + ] } resource "aws_iam_role_policy_attachments_exclusive" "hcptf_plan" { diff --git a/terraform/vpc.tf b/terraform/vpc.tf index f2a35a4..782ba29 100644 --- a/terraform/vpc.tf +++ b/terraform/vpc.tf @@ -14,7 +14,7 @@ resource "aws_vpc" "this" { # First apply updates the live hcptf apply role before CreateVpc. depends_on = [ aws_iam_role_policy.hcptf_apply_services, - aws_iam_role_policy.hcptf_apply_ecs, + aws_iam_role_policy_attachments_exclusive.hcptf_apply, ] } diff --git a/tests/infra/test_hcp_contract.py b/tests/infra/test_hcp_contract.py index e00f5f6..632f18d 100644 --- a/tests/infra/test_hcp_contract.py +++ b/tests/infra/test_hcp_contract.py @@ -83,6 +83,9 @@ def test_stack_owns_a_vpc_instead_of_looking_up_default(): assert "sid = \"RefreshVpc\"" in HCP_IAM assert "afterhours-shift-manager-ecs" in HCP_IAM assert "hcptf_apply_ecs" in HCP_IAM + assert 'resource "aws_iam_policy" "hcptf_apply_ecs"' in HCP_IAM + assert 'resource "aws_iam_role_policy" "hcptf_apply_ecs"' not in HCP_IAM + assert "aws_iam_policy.hcptf_apply_ecs.arn" in HCP_IAM def test_ecs_task_boundary_uses_static_arns():