mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 13:33:13 +00:00
* fix(iam): attach per-workload lambda permissions boundary (PLAT-52) * fix(iam): skip boundary delete on weekly-menu role (PLAT-52)
128 lines
4.3 KiB
HCL
128 lines
4.3 KiB
HCL
# GitHub Actions OIDC role for .github/workflows/weekly-menu.yml.
|
|
#
|
|
# Trust is pinned three ways (aud, sub to main, job_workflow_ref to the
|
|
# weekly-menu workflow at main) so no other workflow in the repo can assume it.
|
|
# Permissions mirror the mgmt github-oidc-deploy-roles weekly-menu role, retargeted
|
|
# to prod resources and without form-api-key (SigV4 publish path).
|
|
#
|
|
# OIDC provider ARN is literal (not a data source): hcptf-meal-order-manager-plan
|
|
# lacks iam:GetOpenIDConnectProvider, and the provider is account-stable.
|
|
|
|
locals {
|
|
github_oidc_provider_arn = "arn:aws:iam::${local.account_id}:oidc-provider/token.actions.githubusercontent.com"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "weekly_menu_assume" {
|
|
statement {
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRoleWithWebIdentity"]
|
|
|
|
principals {
|
|
type = "Federated"
|
|
identifiers = [local.github_oidc_provider_arn]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "token.actions.githubusercontent.com:aud"
|
|
values = ["sts.amazonaws.com"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "token.actions.githubusercontent.com:sub"
|
|
values = ["repo:Sea-Haven-Industries/meal-order-manager:ref:refs/heads/main"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "token.actions.githubusercontent.com:job_workflow_ref"
|
|
values = ["Sea-Haven-Industries/meal-order-manager/.github/workflows/weekly-menu.yml@refs/heads/main"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "weekly_menu" {
|
|
name = "githubdeploy-meal-order-manager-weekly-menu"
|
|
path = "/tf-managed/"
|
|
description = "GitHub Actions weekly-menu scrape/publish for meal-order-manager"
|
|
assume_role_policy = data.aws_iam_policy_document.weekly_menu_assume.json
|
|
max_session_duration = 3600
|
|
|
|
# Not a Lambda execution role. Config omits permissions_boundary so a later
|
|
# apply will not PutRolePermissionsBoundary the Lambda ceiling back. Live still
|
|
# has seahaven-lambda-execution-boundary; omitting without ignore_changes would
|
|
# plan DeleteRolePermissionsBoundary, which hcptf-meal-order-manager is denied
|
|
# (DenyBoundaryTampering). Ignore the attribute so this apply does not touch
|
|
# the ceiling. An administrator deletes the live attachment, then a follow-up
|
|
# drops this lifecycle after refresh-only updates state to null.
|
|
lifecycle {
|
|
ignore_changes = [permissions_boundary]
|
|
}
|
|
}
|
|
|
|
data "aws_iam_policy_document" "weekly_menu" {
|
|
statement {
|
|
sid = "SlackBotSecret"
|
|
effect = "Allow"
|
|
actions = [
|
|
"secretsmanager:GetSecretValue",
|
|
]
|
|
resources = [var.slack_bot_secret_arn]
|
|
}
|
|
|
|
statement {
|
|
sid = "DeployAndAppParams"
|
|
effect = "Allow"
|
|
actions = [
|
|
"ssm:GetParameter",
|
|
]
|
|
resources = [
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.ssm_prefix}/deploy/api-url",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.ssm_prefix}/deploy/form-bucket",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.ssm_prefix}/deploy/distribution-id",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.ssm_prefix}/deploy/form-url",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.google_client_id_param}",
|
|
"arn:aws:ssm:${var.aws_region}:${local.account_id}:parameter${local.slack_channel_param}",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "PublishApi"
|
|
effect = "Allow"
|
|
actions = [
|
|
"execute-api:Invoke",
|
|
]
|
|
resources = [
|
|
"arn:aws:execute-api:${var.aws_region}:${local.account_id}:${aws_apigatewayv2_api.order_api.id}/*/GET/api/publish/settings",
|
|
"arn:aws:execute-api:${var.aws_region}:${local.account_id}:${aws_apigatewayv2_api.order_api.id}/*/POST/api/publish/menu",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "FormObjects"
|
|
effect = "Allow"
|
|
actions = [
|
|
"s3:PutObject",
|
|
]
|
|
resources = [
|
|
"${aws_s3_bucket.form.arn}/index.html",
|
|
"${aws_s3_bucket.form.arn}/archive/*.html",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "InvalidateForm"
|
|
effect = "Allow"
|
|
actions = [
|
|
"cloudfront:CreateInvalidation",
|
|
]
|
|
resources = [aws_cloudfront_distribution.form.arn]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "weekly_menu" {
|
|
name = "weekly-menu-publish"
|
|
role = aws_iam_role.weekly_menu.id
|
|
policy = data.aws_iam_policy_document.weekly_menu.json
|
|
}
|