Files
shared-memory/terraform/iam.tf
T
shadowdaoandClaude Opus 4.7 08be60e661 feat(terraform): AWS Fargate deployment module
Adds a terraform/ directory with an opinionated module that deploys
shared-memory to ECS Fargate behind an ALB. The module assumes the
operator already provides the VPC, RDS Postgres, ACM cert, ECR images,
and OIDC clients, and creates everything else: ECS cluster + services,
ALB, Service Connect namespace for app-embedder discovery, EFS-backed
model cache for the embedder, Secrets Manager entries, IAM roles,
CloudWatch log groups, and a one-shot migrator task definition.

Includes examples/basic/ with a worked invocation and a README covering
prerequisites, quick start, the post-apply migrator run, image updates,
DNS setup, and a security note. Main README gains a short Mode C
pointer to the terraform/ guide.

Validated with `terraform fmt -check -recursive` and
`terraform validate` against AWS provider 5.x.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 09:40:12 -07:00

70 lines
2.5 KiB
Terraform

# -----------------------------------------------------------------------------
# IAM. Two role kinds:
#
# * Task execution role — used by the ECS agent itself to pull images,
# fetch secrets, and write logs. Shared across all three task defs.
# * Task role — assumed by the running container. We give every service
# its own (even if empty today) so future per-service permissions (S3,
# SES, etc.) can be granted without widening blast radius.
# -----------------------------------------------------------------------------
# ---- Task execution role ----
data "aws_iam_policy_document" "ecs_tasks_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ecs-tasks.amazonaws.com"]
}
}
}
resource "aws_iam_role" "execution" {
name = "${var.name_prefix}-ecs-execution"
assume_role_policy = data.aws_iam_policy_document.ecs_tasks_assume.json
tags = local.tags
}
# AWS-managed policy: pull from ECR, write to CloudWatch.
resource "aws_iam_role_policy_attachment" "execution_default" {
role = aws_iam_role.execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
# Allow the execution role to decrypt the specific secrets this module owns.
# Scoped to the module's secret ARNs only — no wildcard against the account.
data "aws_iam_policy_document" "execution_secrets" {
statement {
sid = "ReadModuleSecrets"
actions = ["secretsmanager:GetSecretValue"]
resources = values(local.secret_arns)
}
}
resource "aws_iam_role_policy" "execution_secrets" {
name = "${var.name_prefix}-execution-secrets"
role = aws_iam_role.execution.id
policy = data.aws_iam_policy_document.execution_secrets.json
}
# ---- Task roles (one per service; empty by default but ready to be widened) ----
resource "aws_iam_role" "app_task" {
name = "${var.name_prefix}-app-task"
assume_role_policy = data.aws_iam_policy_document.ecs_tasks_assume.json
tags = local.tags
}
resource "aws_iam_role" "embedder_task" {
name = "${var.name_prefix}-embedder-task"
assume_role_policy = data.aws_iam_policy_document.ecs_tasks_assume.json
tags = local.tags
}
resource "aws_iam_role" "migrator_task" {
name = "${var.name_prefix}-migrator-task"
assume_role_policy = data.aws_iam_policy_document.ecs_tasks_assume.json
tags = local.tags
}