mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 03:03:12 +00:00
* feat(menu): publish the weekly menu from the job worker Monday publish parses the catalog embedded in the Redefine menu page and runs on the Fargate worker, so the GitHub Actions scrape cron can go away. * fix(menu): address review feedback Use the form deadline in the Monday Slack post, and compare that message exactly so CodeQL does not treat the test as URL sanitization.
1089 lines
31 KiB
HCL
1089 lines
31 KiB
HCL
# HCP plan/apply roles imported from seahaven-terraform-substrate (PLAT-146).
|
|
# Import, do not recreate. Role names stay hcptf-meal-order-manager / hcptf-meal-order-manager-plan.
|
|
#
|
|
# Live seahaven-hcptf-iam-management DenySelfMutation blocks DetachRolePolicy
|
|
# and PutRolePolicy on hcptf-* (including this role). Import apply sequence:
|
|
# 1. seahaven-org-baseline scripts/create-hcptf-bootstrap-roles.sh
|
|
# --account prod|dev --allow-workspace meal-order-manager-<env>
|
|
# 2. Point this workspace's TFC_AWS_* at hcptf-bootstrap /
|
|
# hcptf-bootstrap-plan (workspace vars, never a project set).
|
|
# 3. One Manual apply (import + detach seahaven-hcptf-iam-management +
|
|
# put scoped inline).
|
|
# 4. Point TFC_AWS_* back at hcptf-meal-order-manager / hcptf-meal-order-manager-plan.
|
|
# 5. Re-run the script without --allow-workspace to pin trust back to
|
|
# iam-bootstrap-<env> only.
|
|
# seahaven-lambda-execution-boundary remains seahaven-lambda-execution-boundary-meal-order-manager.
|
|
|
|
import {
|
|
to = aws_iam_role.hcptf_apply
|
|
id = "hcptf-meal-order-manager"
|
|
}
|
|
|
|
import {
|
|
to = aws_iam_role.hcptf_plan
|
|
id = "hcptf-meal-order-manager-plan"
|
|
}
|
|
|
|
import {
|
|
to = aws_iam_role_policy.hcptf_plan_refresh
|
|
id = "hcptf-meal-order-manager-plan:meal-order-manager-plan-refresh"
|
|
}
|
|
|
|
import {
|
|
to = aws_iam_role_policy_attachments_exclusive.hcptf_apply
|
|
id = "hcptf-meal-order-manager"
|
|
}
|
|
|
|
import {
|
|
to = aws_iam_role_policy_attachment.hcptf_plan_viewonly
|
|
id = "hcptf-meal-order-manager-plan/arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
|
|
}
|
|
|
|
import {
|
|
to = aws_iam_role_policy_attachments_exclusive.hcptf_plan
|
|
id = "hcptf-meal-order-manager-plan"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "hcptf_apply_trust" {
|
|
statement {
|
|
sid = "HcpApply"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRoleWithWebIdentity"]
|
|
|
|
principals {
|
|
type = "Federated"
|
|
identifiers = ["arn:aws:iam::${local.account_id}:oidc-provider/app.terraform.io"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "app.terraform.io:aud"
|
|
values = ["aws.workload.identity"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "app.terraform.io:sub"
|
|
values = [
|
|
"organization:seahaven:project:${local.hcp_project}:workspace:${local.hcp_workspace}:run_phase:apply",
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
data "aws_iam_policy_document" "hcptf_plan_trust" {
|
|
statement {
|
|
sid = "HcpPlan"
|
|
effect = "Allow"
|
|
actions = ["sts:AssumeRoleWithWebIdentity"]
|
|
|
|
principals {
|
|
type = "Federated"
|
|
identifiers = ["arn:aws:iam::${local.account_id}:oidc-provider/app.terraform.io"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "app.terraform.io:aud"
|
|
values = ["aws.workload.identity"]
|
|
}
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "app.terraform.io:sub"
|
|
values = [
|
|
"organization:seahaven:project:${local.hcp_project}:workspace:${local.hcp_workspace}:run_phase:plan",
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
data "aws_iam_policy_document" "hcptf_scoped_iam" {
|
|
statement {
|
|
sid = "DenyCreatePolicy"
|
|
effect = "Deny"
|
|
actions = ["iam:CreatePolicy", "iam:CreatePolicyVersion"]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "CreateExecRoleWithBoundary"
|
|
effect = "Allow"
|
|
actions = ["iam:CreateRole"]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*"]
|
|
|
|
condition {
|
|
test = "StringLike"
|
|
variable = "iam:PermissionsBoundary"
|
|
values = [
|
|
"arn:aws:iam::${local.account_id}:policy/tf-managed/meal-order-manager-*",
|
|
"arn:aws:iam::${local.account_id}:policy/seahaven-lambda-execution-boundary-meal-order-manager"
|
|
]
|
|
}
|
|
}
|
|
|
|
statement {
|
|
sid = "MutateExecRoleWithBoundary"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:AttachRolePolicy",
|
|
"iam:PutRolePolicy",
|
|
"iam:PutRolePermissionsBoundary",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*"]
|
|
|
|
condition {
|
|
test = "StringLike"
|
|
variable = "iam:PermissionsBoundary"
|
|
values = [
|
|
"arn:aws:iam::${local.account_id}:policy/tf-managed/meal-order-manager-*",
|
|
"arn:aws:iam::${local.account_id}:policy/seahaven-lambda-execution-boundary-meal-order-manager"
|
|
]
|
|
}
|
|
}
|
|
|
|
statement {
|
|
sid = "WriteExecRoles"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:DeleteRole",
|
|
"iam:DeleteRolePolicy",
|
|
"iam:DetachRolePolicy",
|
|
"iam:TagRole",
|
|
"iam:UntagRole",
|
|
"iam:UpdateAssumeRolePolicy",
|
|
"iam:UpdateRole",
|
|
"iam:UpdateRoleDescription",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "PassExecRolesToCompute"
|
|
effect = "Allow"
|
|
actions = ["iam:PassRole"]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*"]
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "iam:PassedToService"
|
|
values = ["ecs-tasks.amazonaws.com", "scheduler.amazonaws.com"]
|
|
}
|
|
}
|
|
|
|
statement {
|
|
sid = "CreateDeployRole"
|
|
effect = "Allow"
|
|
actions = ["iam:CreateRole"]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager"]
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "iam:PermissionsBoundary"
|
|
values = [aws_iam_policy.github_deploy_boundary.arn]
|
|
}
|
|
}
|
|
|
|
statement {
|
|
sid = "WriteGithubDeployRole"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:DeleteRole",
|
|
"iam:DeleteRolePolicy",
|
|
"iam:TagRole",
|
|
"iam:UntagRole",
|
|
"iam:UpdateAssumeRolePolicy",
|
|
"iam:UpdateRole",
|
|
"iam:UpdateRoleDescription",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager"]
|
|
}
|
|
|
|
statement {
|
|
sid = "MutateGithubDeployRoleWithBoundary"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:PutRolePolicy",
|
|
"iam:PutRolePermissionsBoundary",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager"]
|
|
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "iam:PermissionsBoundary"
|
|
values = [aws_iam_policy.github_deploy_boundary.arn]
|
|
}
|
|
}
|
|
|
|
statement {
|
|
sid = "DenyGithubDeployAttach"
|
|
effect = "Deny"
|
|
actions = [
|
|
"iam:AttachRolePolicy",
|
|
"iam:DetachRolePolicy",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager"]
|
|
}
|
|
|
|
# Kept so this apply can delete githubdeploy-meal-order-manager-weekly-menu.
|
|
# Drop the statement after that role is gone.
|
|
statement {
|
|
sid = "WriteDeployRoles"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:AttachRolePolicy",
|
|
"iam:CreateRole",
|
|
"iam:DeleteRole",
|
|
"iam:DeleteRolePolicy",
|
|
"iam:DetachRolePolicy",
|
|
"iam:PutRolePolicy",
|
|
"iam:TagRole",
|
|
"iam:UntagRole",
|
|
"iam:UpdateAssumeRolePolicy",
|
|
"iam:UpdateRole",
|
|
"iam:UpdateRoleDescription",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager-weekly-menu"]
|
|
}
|
|
|
|
statement {
|
|
sid = "IamReadOnly"
|
|
effect = "Allow"
|
|
actions = [
|
|
"iam:GetPolicy",
|
|
"iam:GetPolicyVersion",
|
|
"iam:GetRole",
|
|
"iam:GetRolePolicy",
|
|
"iam:ListAttachedRolePolicies",
|
|
"iam:ListInstanceProfilesForRole",
|
|
"iam:ListPolicies",
|
|
"iam:ListPolicyVersions",
|
|
"iam:ListRolePolicies",
|
|
"iam:ListRoleTags",
|
|
"iam:ListRoles",
|
|
]
|
|
resources = ["*"]
|
|
}
|
|
|
|
statement {
|
|
sid = "DenySelfMutation"
|
|
effect = "Deny"
|
|
actions = [
|
|
"iam:AttachRolePolicy",
|
|
"iam:DeleteRole",
|
|
"iam:DeleteRolePolicy",
|
|
"iam:DeleteRolePermissionsBoundary",
|
|
"iam:DetachRolePolicy",
|
|
"iam:PutRolePolicy",
|
|
"iam:PutRolePermissionsBoundary",
|
|
"iam:UpdateAssumeRolePolicy",
|
|
"iam:UpdateRole",
|
|
"iam:UpdateRoleDescription",
|
|
]
|
|
resources = [
|
|
"arn:aws:iam::${local.account_id}:role/hcptf-*",
|
|
"arn:aws:iam::${local.account_id}:role/github-cfn-execution-role",
|
|
"arn:aws:iam::${local.account_id}:role/githubdeploy-*",
|
|
"arn:aws:iam::${local.account_id}:role/cdk-hnb659fds-*",
|
|
"arn:aws:iam::${local.account_id}:role/OrganizationAccountAccessRole",
|
|
"arn:aws:iam::${local.account_id}:role/seahaven-*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "DenyBoundaryTampering"
|
|
effect = "Deny"
|
|
actions = [
|
|
"iam:DeleteRolePermissionsBoundary",
|
|
"iam:DeleteUserPermissionsBoundary",
|
|
]
|
|
resources = [
|
|
"arn:aws:iam::${local.account_id}:role/*",
|
|
"arn:aws:iam::${local.account_id}:user/*",
|
|
]
|
|
}
|
|
|
|
statement {
|
|
sid = "DenyBoundaryPolicyEdit"
|
|
effect = "Deny"
|
|
actions = [
|
|
"iam:CreatePolicyVersion",
|
|
"iam:DeletePolicy",
|
|
"iam:DeletePolicyVersion",
|
|
"iam:SetDefaultPolicyVersion",
|
|
]
|
|
resources = ["arn:aws:iam::${local.account_id}:policy/seahaven-*"]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_policy" "hcptf_apply_compute" {
|
|
name = "meal-order-manager-apply-compute"
|
|
path = "/tf-managed/"
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = [
|
|
"ecs:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ecs:us-east-1:${local.account_id}:cluster/meal-order-manager",
|
|
"arn:aws:ecs:us-east-1:${local.account_id}:service/meal-order-manager/meal-order-manager",
|
|
"arn:aws:ecs:us-east-1:${local.account_id}:task-definition/meal-order-manager:*",
|
|
"arn:aws:ecs:us-east-1:${local.account_id}:task-definition/meal-order-manager",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "EcsWorkload"
|
|
},
|
|
{
|
|
Action = [
|
|
"ecs:CreateCluster",
|
|
"ecs:CreateService",
|
|
"ecs:DeleteService",
|
|
"ecs:DeregisterTaskDefinition",
|
|
"ecs:DescribeClusters",
|
|
"ecs:DescribeServices",
|
|
"ecs:DescribeTaskDefinition",
|
|
"ecs:ListClusters",
|
|
"ecs:ListServices",
|
|
"ecs:ListTaskDefinitions",
|
|
"ecs:RegisterTaskDefinition",
|
|
"ecs:TagResource",
|
|
"ecs:UntagResource",
|
|
"ecs:UpdateService",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "EcsAccount"
|
|
},
|
|
{
|
|
Action = [
|
|
"elasticloadbalancing:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:elasticloadbalancing:us-east-1:${local.account_id}:loadbalancer/app/meal-order-manager/*",
|
|
"arn:aws:elasticloadbalancing:us-east-1:${local.account_id}:targetgroup/meal-order-manager-api/*",
|
|
"arn:aws:elasticloadbalancing:us-east-1:${local.account_id}:listener/app/meal-order-manager/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "ElbWorkload"
|
|
},
|
|
{
|
|
Action = [
|
|
"elasticloadbalancing:Describe*",
|
|
"elasticloadbalancing:CreateLoadBalancer",
|
|
"elasticloadbalancing:CreateTargetGroup",
|
|
"elasticloadbalancing:CreateListener",
|
|
"elasticloadbalancing:CreateRule",
|
|
"elasticloadbalancing:AddTags",
|
|
"elasticloadbalancing:ModifyLoadBalancerAttributes",
|
|
"elasticloadbalancing:ModifyTargetGroup",
|
|
"elasticloadbalancing:ModifyTargetGroupAttributes",
|
|
"elasticloadbalancing:ModifyListener",
|
|
"elasticloadbalancing:SetSecurityGroups",
|
|
"elasticloadbalancing:SetSubnets",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "ElbDescribe"
|
|
},
|
|
{
|
|
Action = [
|
|
"ecr:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ecr:us-east-1:${local.account_id}:repository/meal-order-manager",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "EcrRepo"
|
|
},
|
|
{
|
|
Action = [
|
|
"ecr:DescribeRepositories",
|
|
"ecr:GetAuthorizationToken",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "EcrAccount"
|
|
},
|
|
{
|
|
Action = [
|
|
"sqs:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:sqs:us-east-1:${local.account_id}:meal-order-manager-jobs",
|
|
"arn:aws:sqs:us-east-1:${local.account_id}:meal-order-manager-jobs-dlq",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "JobsQueues"
|
|
},
|
|
{
|
|
Action = [
|
|
"scheduler:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:scheduler:us-east-1:${local.account_id}:schedule/meal-order-manager/*",
|
|
"arn:aws:scheduler:us-east-1:${local.account_id}:schedule-group/meal-order-manager",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "SchedulerJobs"
|
|
},
|
|
{
|
|
Action = [
|
|
"scheduler:CreateScheduleGroup",
|
|
"scheduler:ListScheduleGroups",
|
|
"scheduler:ListSchedules",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "SchedulerAccount"
|
|
},
|
|
]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_policy" "hcptf_apply_services" {
|
|
name = "meal-order-manager-apply-services"
|
|
path = "/tf-managed/"
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = [
|
|
"lambda:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:lambda:us-east-1:${local.account_id}:function:meal-order-manager-*",
|
|
"arn:aws:lambda:us-east-1:${local.account_id}:layer:meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "LambdaAll"
|
|
},
|
|
{
|
|
Action = [
|
|
"lambda:ListFunctions",
|
|
"lambda:ListLayers",
|
|
"lambda:GetAccountSettings",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "LambdaList"
|
|
},
|
|
{
|
|
Action = [
|
|
"events:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:events:us-east-1:${local.account_id}:rule/meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "EventBridgeRules"
|
|
},
|
|
{
|
|
Action = [
|
|
"logs:CreateLogGroup",
|
|
"logs:DeleteLogGroup",
|
|
"logs:PutRetentionPolicy",
|
|
"logs:DeleteRetentionPolicy",
|
|
"logs:TagResource",
|
|
"logs:UntagResource",
|
|
"logs:ListTagsForResource",
|
|
"logs:PutMetricFilter",
|
|
"logs:DeleteMetricFilter",
|
|
"logs:DescribeMetricFilters",
|
|
]
|
|
Resource = [
|
|
"arn:aws:logs:us-east-1:${local.account_id}:log-group:/aws/lambda/meal-order-manager-*",
|
|
"arn:aws:logs:us-east-1:${local.account_id}:log-group:/aws/apigateway/meal-order-manager*",
|
|
"arn:aws:logs:us-east-1:${local.account_id}:log-group:/ecs/meal-order-manager",
|
|
"arn:aws:logs:us-east-1:${local.account_id}:log-group:/ecs/meal-order-manager:*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "CloudWatchLogs"
|
|
},
|
|
{
|
|
Action = [
|
|
"logs:DescribeLogGroups",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "CloudWatchLogsDescribe"
|
|
},
|
|
{
|
|
Action = [
|
|
"logs:CreateLogDelivery",
|
|
"logs:GetLogDelivery",
|
|
"logs:UpdateLogDelivery",
|
|
"logs:DeleteLogDelivery",
|
|
"logs:ListLogDeliveries",
|
|
"logs:DescribeResourcePolicies",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "MealOrderApiGwAccessLogDelivery"
|
|
},
|
|
{
|
|
Action = [
|
|
"s3:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:s3:::meal-order-manager-artifacts-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-artifacts-${local.account_id}/*",
|
|
"arn:aws:s3:::meal-order-manager-form-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-form-${local.account_id}/*",
|
|
"arn:aws:s3:::meal-order-manager-reports-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-reports-${local.account_id}/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "StackBuckets"
|
|
},
|
|
{
|
|
Action = [
|
|
"dynamodb:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:dynamodb:us-east-1:${local.account_id}:table/meal-order-manager-orders",
|
|
"arn:aws:dynamodb:us-east-1:${local.account_id}:table/meal-order-manager-orders/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "DynamoDBTable"
|
|
},
|
|
{
|
|
Action = [
|
|
"dynamodb:ListTables",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "DynamoDBList"
|
|
},
|
|
{
|
|
Action = [
|
|
"apigateway:*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:apigateway:us-east-1::/apis",
|
|
"arn:aws:apigateway:us-east-1::/apis/*",
|
|
"arn:aws:apigateway:us-east-1::/tags/*",
|
|
"arn:aws:apigateway:us-east-1::/vpclinks",
|
|
"arn:aws:apigateway:us-east-1::/vpclinks/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "HttpApiManage"
|
|
},
|
|
{
|
|
Action = [
|
|
"cloudfront:*",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "CloudFrontManage"
|
|
},
|
|
{
|
|
Condition = {
|
|
StringEquals = {
|
|
"aws:RequestTag/Project" = "meal-order-manager"
|
|
}
|
|
}
|
|
Action = [
|
|
"acm:RequestCertificate",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "AcmCreate"
|
|
},
|
|
{
|
|
Action = [
|
|
"acm:ListCertificates",
|
|
"acm:ListTagsForCertificate",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "AcmList"
|
|
},
|
|
{
|
|
Condition = {
|
|
StringEquals = {
|
|
"aws:ResourceTag/Project" = "meal-order-manager"
|
|
}
|
|
}
|
|
Action = [
|
|
"acm:DescribeCertificate",
|
|
"acm:GetCertificate",
|
|
"acm:DeleteCertificate",
|
|
"acm:AddTagsToCertificate",
|
|
"acm:RemoveTagsFromCertificate",
|
|
"acm:RenewCertificate",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "AcmManageTagged"
|
|
},
|
|
{
|
|
Action = [
|
|
"ssm:GetParameter",
|
|
"ssm:GetParameters",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ssm:us-east-1:${local.account_id}:parameter/seahaven/waf/app-web-acl-arn",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "ReadAppWebAclSsm"
|
|
},
|
|
{
|
|
Action = [
|
|
"ssm:GetParameter",
|
|
"ssm:GetParameters",
|
|
"ssm:PutParameter",
|
|
"ssm:DeleteParameter",
|
|
"ssm:AddTagsToResource",
|
|
"ssm:RemoveTagsFromResource",
|
|
"ssm:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ssm:us-east-1:${local.account_id}:parameter/meal-order-manager/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "MealOrderSsm"
|
|
},
|
|
{
|
|
Action = [
|
|
"ssm:DescribeParameters",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "MealOrderSsmDescribeParameters"
|
|
},
|
|
{
|
|
Condition = {
|
|
StringEquals = {
|
|
"iam:PassedToService" = "apigateway.amazonaws.com"
|
|
}
|
|
}
|
|
Action = [
|
|
"iam:PassRole",
|
|
]
|
|
Resource = [
|
|
"arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "MealOrderPassRoleApiGateway"
|
|
},
|
|
{
|
|
Action = [
|
|
"wafv2:GetWebACL",
|
|
"wafv2:GetWebACLForResource",
|
|
"wafv2:ListWebACLs",
|
|
"wafv2:ListResourcesForWebACL",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "ReadWafWebAcl"
|
|
},
|
|
{
|
|
Action = [
|
|
"cloudwatch:PutMetricAlarm",
|
|
"cloudwatch:DeleteAlarms",
|
|
"cloudwatch:DescribeAlarms",
|
|
"cloudwatch:TagResource",
|
|
"cloudwatch:UntagResource",
|
|
"cloudwatch:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:cloudwatch:us-east-1:${local.account_id}:alarm:meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "CloudWatchAlarms"
|
|
},
|
|
{
|
|
Action = [
|
|
"sns:Publish",
|
|
"sns:GetTopicAttributes",
|
|
"sns:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:sns:us-east-1:${local.account_id}:site-alerts",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "SnsPublishSiteAlerts"
|
|
},
|
|
{
|
|
Action = [
|
|
"ses:GetIdentityVerificationAttributes",
|
|
"ses:GetSendQuota",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "SesIdentityRead"
|
|
},
|
|
]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "hcptf_apply_ec2" {
|
|
name = "meal-order-manager-ec2"
|
|
role = aws_iam_role.hcptf_apply.id
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = [
|
|
"ec2:AssociateRouteTable",
|
|
"ec2:AttachInternetGateway",
|
|
"ec2:AuthorizeSecurityGroupEgress",
|
|
"ec2:AuthorizeSecurityGroupIngress",
|
|
"ec2:CreateInternetGateway",
|
|
"ec2:CreateRoute",
|
|
"ec2:CreateRouteTable",
|
|
"ec2:CreateSecurityGroup",
|
|
"ec2:CreateSubnet",
|
|
"ec2:CreateTags",
|
|
"ec2:CreateVpc",
|
|
"ec2:DeleteInternetGateway",
|
|
"ec2:DeleteRoute",
|
|
"ec2:DeleteRouteTable",
|
|
"ec2:DeleteSecurityGroup",
|
|
"ec2:DeleteSubnet",
|
|
"ec2:DeleteTags",
|
|
"ec2:DeleteVpc",
|
|
"ec2:DescribeAccountAttributes",
|
|
"ec2:DescribeAvailabilityZones",
|
|
"ec2:DescribeInternetGateways",
|
|
"ec2:DescribeNetworkInterfaces",
|
|
"ec2:DescribeRouteTables",
|
|
"ec2:DescribeSecurityGroupRules",
|
|
"ec2:DescribeSecurityGroups",
|
|
"ec2:DescribeSubnets",
|
|
"ec2:DescribeTags",
|
|
"ec2:DescribeVpcAttribute",
|
|
"ec2:DescribeVpcs",
|
|
"ec2:DetachInternetGateway",
|
|
"ec2:DisassociateRouteTable",
|
|
"ec2:ModifySubnetAttribute",
|
|
"ec2:ModifyVpcAttribute",
|
|
"ec2:RevokeSecurityGroupEgress",
|
|
"ec2:RevokeSecurityGroupIngress",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "Ec2VpcManagement"
|
|
},
|
|
]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "hcptf_plan_refresh" {
|
|
name = "meal-order-manager-plan-refresh"
|
|
role = aws_iam_role.hcptf_plan.id
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [
|
|
{
|
|
Action = [
|
|
"iam:GetRole",
|
|
"iam:GetRolePolicy",
|
|
"iam:ListRolePolicies",
|
|
"iam:ListAttachedRolePolicies",
|
|
"iam:ListRoleTags",
|
|
]
|
|
Resource = [
|
|
"arn:aws:iam::${local.account_id}:role/tf-managed/meal-order-manager-*",
|
|
"arn:aws:iam::${local.account_id}:role/tf-managed/githubdeploy-meal-order-manager*",
|
|
"arn:aws:iam::${local.account_id}:role/hcptf-meal-order-manager",
|
|
"arn:aws:iam::${local.account_id}:role/hcptf-meal-order-manager-plan",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshIamRoles"
|
|
},
|
|
{
|
|
Action = [
|
|
"iam:GetPolicy",
|
|
"iam:GetPolicyVersion",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshManagedPolicies"
|
|
},
|
|
{
|
|
Action = [
|
|
"events:DescribeRule",
|
|
"events:ListTargetsByRule",
|
|
"events:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:events:us-east-1:${local.account_id}:rule/meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshEventBridge"
|
|
},
|
|
{
|
|
Action = [
|
|
"lambda:Get*",
|
|
"lambda:List*",
|
|
]
|
|
Resource = [
|
|
"arn:aws:lambda:us-east-1:${local.account_id}:function:meal-order-manager-*",
|
|
"arn:aws:lambda:us-east-1:${local.account_id}:layer:meal-order-manager-*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshLambda"
|
|
},
|
|
{
|
|
Action = [
|
|
"ecs:DescribeClusters",
|
|
"ecs:DescribeServices",
|
|
"ecs:DescribeTaskDefinition",
|
|
"ecs:DescribeTaskSets",
|
|
"ecs:ListClusters",
|
|
"ecs:ListServices",
|
|
"ecs:ListTaskDefinitions",
|
|
"ecs:ListTagsForResource",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshEcs"
|
|
},
|
|
{
|
|
Action = [
|
|
"elasticloadbalancing:DescribeLoadBalancers",
|
|
"elasticloadbalancing:DescribeLoadBalancerAttributes",
|
|
"elasticloadbalancing:DescribeListeners",
|
|
"elasticloadbalancing:DescribeListenerAttributes",
|
|
"elasticloadbalancing:DescribeTargetGroups",
|
|
"elasticloadbalancing:DescribeTargetGroupAttributes",
|
|
"elasticloadbalancing:DescribeTags",
|
|
"elasticloadbalancing:DescribeRules",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshElb"
|
|
},
|
|
{
|
|
Action = [
|
|
"ecr:DescribeRepositories",
|
|
"ecr:DescribeImages",
|
|
"ecr:GetLifecyclePolicy",
|
|
"ecr:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ecr:us-east-1:${local.account_id}:repository/meal-order-manager",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshEcr"
|
|
},
|
|
{
|
|
Action = [
|
|
"sqs:GetQueueAttributes",
|
|
"sqs:GetQueueUrl",
|
|
"sqs:ListQueueTags",
|
|
]
|
|
Resource = [
|
|
"arn:aws:sqs:us-east-1:${local.account_id}:meal-order-manager-jobs",
|
|
"arn:aws:sqs:us-east-1:${local.account_id}:meal-order-manager-jobs-dlq",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshJobsQueues"
|
|
},
|
|
{
|
|
Action = [
|
|
"scheduler:GetSchedule",
|
|
"scheduler:GetScheduleGroup",
|
|
"scheduler:ListSchedules",
|
|
"scheduler:ListScheduleGroups",
|
|
"scheduler:ListTagsForResource",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshScheduler"
|
|
},
|
|
{
|
|
Action = [
|
|
"ec2:DescribeAccountAttributes",
|
|
"ec2:DescribeAvailabilityZones",
|
|
"ec2:DescribeInternetGateways",
|
|
"ec2:DescribeNetworkInterfaces",
|
|
"ec2:DescribeRouteTables",
|
|
"ec2:DescribeSecurityGroupRules",
|
|
"ec2:DescribeSecurityGroups",
|
|
"ec2:DescribeSubnets",
|
|
"ec2:DescribeTags",
|
|
"ec2:DescribeVpcAttribute",
|
|
"ec2:DescribeVpcs",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshVpc"
|
|
},
|
|
{
|
|
Action = [
|
|
"s3:Get*",
|
|
"s3:ListBucket",
|
|
]
|
|
Resource = [
|
|
"arn:aws:s3:::meal-order-manager-artifacts-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-artifacts-${local.account_id}/*",
|
|
"arn:aws:s3:::meal-order-manager-form-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-form-${local.account_id}/*",
|
|
"arn:aws:s3:::meal-order-manager-reports-${local.account_id}",
|
|
"arn:aws:s3:::meal-order-manager-reports-${local.account_id}/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshBuckets"
|
|
},
|
|
{
|
|
Action = [
|
|
"dynamodb:DescribeTable",
|
|
"dynamodb:DescribeTimeToLive",
|
|
"dynamodb:DescribeContinuousBackups",
|
|
"dynamodb:ListTagsOfResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:dynamodb:us-east-1:${local.account_id}:table/meal-order-manager-orders",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshDynamoDB"
|
|
},
|
|
{
|
|
Action = [
|
|
"logs:DescribeLogGroups",
|
|
"logs:ListTagsForResource",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshLogs"
|
|
},
|
|
{
|
|
Action = [
|
|
"cloudfront:DescribeFunction",
|
|
"cloudfront:Get*",
|
|
"cloudfront:List*",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshCloudFront"
|
|
},
|
|
{
|
|
Action = [
|
|
"acm:DescribeCertificate",
|
|
"acm:ListCertificates",
|
|
"acm:ListTagsForCertificate",
|
|
"acm:GetCertificate",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshAcm"
|
|
},
|
|
{
|
|
Action = [
|
|
"ssm:GetParameter",
|
|
"ssm:GetParameters",
|
|
"ssm:ListTagsForResource",
|
|
]
|
|
Resource = [
|
|
"arn:aws:ssm:us-east-1:${local.account_id}:parameter/seahaven/waf/app-web-acl-arn",
|
|
"arn:aws:ssm:us-east-1:${local.account_id}:parameter/meal-order-manager/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshAppWebAclSsm"
|
|
},
|
|
{
|
|
Action = [
|
|
"ssm:DescribeParameters",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshSsmDescribeParameters"
|
|
},
|
|
{
|
|
Action = [
|
|
"wafv2:GetWebACL",
|
|
"wafv2:ListWebACLs",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshWafWebAcl"
|
|
},
|
|
{
|
|
Action = [
|
|
"apigateway:GET",
|
|
]
|
|
Resource = [
|
|
"arn:aws:apigateway:us-east-1::/apis/*",
|
|
"arn:aws:apigateway:us-east-1::/tags/*",
|
|
]
|
|
Effect = "Allow"
|
|
Sid = "RefreshHttpApi"
|
|
},
|
|
{
|
|
Action = [
|
|
"cloudwatch:DescribeAlarms",
|
|
"cloudwatch:ListTagsForResource",
|
|
]
|
|
Resource = "*"
|
|
Effect = "Allow"
|
|
Sid = "RefreshAlarms"
|
|
},
|
|
]
|
|
})
|
|
}
|
|
|
|
resource "aws_iam_role" "hcptf_apply" {
|
|
name = "hcptf-meal-order-manager"
|
|
assume_role_policy = data.aws_iam_policy_document.hcptf_apply_trust.json
|
|
max_session_duration = 3600
|
|
|
|
tags = {
|
|
Project = "meal-order-manager"
|
|
Owner = "adam@seahavenind.com"
|
|
ManagedBy = "terraform"
|
|
}
|
|
|
|
# Apply role cannot iam:TagRole on itself. Provider default_tags
|
|
# merge into tags_all, so ignoring tags alone still 403s mid-apply.
|
|
lifecycle {
|
|
ignore_changes = [tags, tags_all]
|
|
}
|
|
}
|
|
|
|
# Exclusive set keeps seahaven-hcptf-iam-management detached.
|
|
resource "aws_iam_role_policy_attachments_exclusive" "hcptf_apply" {
|
|
role_name = aws_iam_role.hcptf_apply.name
|
|
policy_arns = [
|
|
aws_iam_policy.hcptf_apply_services.arn,
|
|
aws_iam_policy.hcptf_apply_compute.arn,
|
|
]
|
|
}
|
|
|
|
resource "aws_iam_role" "hcptf_plan" {
|
|
name = "hcptf-meal-order-manager-plan"
|
|
assume_role_policy = data.aws_iam_policy_document.hcptf_plan_trust.json
|
|
max_session_duration = 3600
|
|
|
|
tags = {
|
|
Project = "meal-order-manager"
|
|
Owner = "adam@seahavenind.com"
|
|
ManagedBy = "terraform"
|
|
}
|
|
|
|
# Same self-tag restriction as hcptf_apply.
|
|
lifecycle {
|
|
ignore_changes = [tags, tags_all]
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachment" "hcptf_plan_viewonly" {
|
|
role = aws_iam_role.hcptf_plan.name
|
|
policy_arn = "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
|
|
}
|
|
|
|
resource "aws_iam_role_policy_attachments_exclusive" "hcptf_plan" {
|
|
role_name = aws_iam_role.hcptf_plan.name
|
|
policy_arns = [
|
|
aws_iam_role_policy_attachment.hcptf_plan_viewonly.policy_arn,
|
|
]
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "hcptf_scoped_iam" {
|
|
name = "scoped-iam-management"
|
|
role = aws_iam_role.hcptf_apply.id
|
|
policy = data.aws_iam_policy_document.hcptf_scoped_iam.json
|
|
}
|