diff --git a/README.md b/README.md index 5313bc8..6e68f77 100644 --- a/README.md +++ b/README.md @@ -527,7 +527,10 @@ projects `seahaven-mgmt`, `seahaven-prod`, `seahaven-dev`). `CreateRole` / `PutRolePolicy` / `AttachRolePolicy` / `PutRolePermissionsBoundary` on `tf-managed` roles require `iam:PermissionsBoundary` `StringLike` `policy/tf-managed/*` or - `policy/seahaven-lambda-execution-boundary*`. `Null` false is not enough: + `policy/seahaven-lambda-execution-boundary*`. `PassRole` on `tf-managed` + roles is allowed to `lambda.amazonaws.com`, `ecs-tasks.amazonaws.com`, + and `scheduler.amazonaws.com` so a first apply can create Fargate tasks + and EventBridge Scheduler targets. `Null` false is not enough: it would accept `AdministratorAccess` as the ceiling. Must not mutate `githubdeploy-*`, `github-cfn-execution-role`, `cdk-hnb659fds-*`, `OrganizationAccountAccessRole`, `seahaven-*`. SCP diff --git a/examples/hcptf-workspace-iam/hcp_iam.tf.example b/examples/hcptf-workspace-iam/hcp_iam.tf.example index ff4cb80..f904328 100644 --- a/examples/hcptf-workspace-iam/hcp_iam.tf.example +++ b/examples/hcptf-workspace-iam/hcp_iam.tf.example @@ -140,14 +140,14 @@ data "aws_iam_policy_document" "hcptf_scoped_iam" { resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/${local.stack_prefix}*"] } statement { - sid = "PassExecRolesToLambda" + sid = "PassExecRolesToCompute" effect = "Allow" actions = ["iam:PassRole"] resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/${local.stack_prefix}*"] condition { test = "StringEquals" variable = "iam:PassedToService" - values = ["lambda.amazonaws.com"] + values = ["lambda.amazonaws.com", "ecs-tasks.amazonaws.com", "scheduler.amazonaws.com"] } } statement { diff --git a/lib/hcptf-bootstrap/apply-policy.json.tmpl b/lib/hcptf-bootstrap/apply-policy.json.tmpl index ce64504..658e78e 100644 --- a/lib/hcptf-bootstrap/apply-policy.json.tmpl +++ b/lib/hcptf-bootstrap/apply-policy.json.tmpl @@ -86,13 +86,17 @@ "Resource": "arn:aws:iam::__ACCOUNT_ID__:role/hcptf-*" }, { - "Sid": "PassTfManagedRolesToLambda", + "Sid": "PassTfManagedRolesToCompute", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::__ACCOUNT_ID__:role/tf-managed/*", "Condition": { "StringEquals": { - "iam:PassedToService": "lambda.amazonaws.com" + "iam:PassedToService": [ + "lambda.amazonaws.com", + "ecs-tasks.amazonaws.com", + "scheduler.amazonaws.com" + ] } } }, diff --git a/lib/hcptf-bootstrap/scoped-apply-iam.json.tmpl b/lib/hcptf-bootstrap/scoped-apply-iam.json.tmpl index 284903f..9b8c8c6 100644 --- a/lib/hcptf-bootstrap/scoped-apply-iam.json.tmpl +++ b/lib/hcptf-bootstrap/scoped-apply-iam.json.tmpl @@ -66,7 +66,11 @@ "Resource": "arn:aws:iam::__ACCOUNT_ID__:role/tf-managed/__STACK_PREFIX__*", "Condition": { "StringEquals": { - "iam:PassedToService": "lambda.amazonaws.com" + "iam:PassedToService": [ + "lambda.amazonaws.com", + "ecs-tasks.amazonaws.com", + "scheduler.amazonaws.com" + ] } } }, diff --git a/lib/terraform-substrate/terraform-substrate.template.yaml b/lib/terraform-substrate/terraform-substrate.template.yaml index d3c4244..508273a 100644 --- a/lib/terraform-substrate/terraform-substrate.template.yaml +++ b/lib/terraform-substrate/terraform-substrate.template.yaml @@ -1837,8 +1837,12 @@ Resources: Resource: "*" # --------------------------------------------------------------------------- - # meal-order-manager-prod (PLAT-70) — HttpApi + 7 Lambdas + layer + DynamoDB - # + S3 form/reports/artifacts + CloudFront/ACM/WAF + EventBridge + alarms. + # meal-order-manager-prod (PLAT-70, imported to the app workspace in PLAT-146). + # Live plan/apply IAM is terraform/hcp_iam.tf in meal-order-manager (ECS/ALB + # as of PLAT-215). Do not mutate these CFN role policies; they are Retain + # leftovers. githubdeploy-meal-order-manager OIDC lives in that app module. + # --------------------------------------------------------------------------- + # Original shape: HttpApi + Lambdas + DynamoDB + S3 + CloudFront. # Plan role: ViewOnly + plan-refresh sidecar. Apply role: HcptfIamManagement # + prefix-scoped service wildcards (no enumerated Get* lists). # ---------------------------------------------------------------------------