# --------------------------------------------------------------------------- # Hosting for the two long-running containers: Fusion (the gateway) and the # Presidio detector. Kept intentionally simple for a demo: default VPC, public # subnets, Fargate. For a first pass you can also run both containers locally # and skip this file entirely (see README "Lightweight path"). # # NOTE: var.fusion_image_uri and var.presidio_image_uri must be set first # (scripts/deploy.sh builds+pushes Presidio; you supply the Axway image). # --------------------------------------------------------------------------- data "aws_vpc" "default" { default = true } data "aws_subnets" "default" { filter { name = "vpc-id" values = [data.aws_vpc.default.id] } } resource "aws_ecs_cluster" "this" { name = "${local.name}-cluster" tags = local.onprem_tag } resource "aws_security_group" "svc" { name = "${local.name}-svc-sg" description = "Demo services SG" vpc_id = data.aws_vpc.default.id ingress { description = "Fusion gateway" from_port = 8080 to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # DEMO ONLY - lock down for anything real } ingress { description = "Presidio analyzer" from_port = 5001 to_port = 5001 protocol = "tcp" self = true } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = local.onprem_tag } resource "aws_iam_role" "ecs_exec" { name = "${local.name}-ecs-exec" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } Action = "sts:AssumeRole" }] }) } resource "aws_iam_role_policy_attachment" "ecs_exec" { role = aws_iam_role.ecs_exec.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" } # Task role for Fusion: it needs to invoke Bedrock/AgentCore and read/write the vault. resource "aws_iam_role" "fusion_task" { name = "${local.name}-fusion-task" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } Action = "sts:AssumeRole" }] }) } resource "aws_iam_role_policy" "fusion_task" { name = "${local.name}-fusion-task-policy" role = aws_iam_role.fusion_task.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow", Action = ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query"], Resource = [aws_dynamodb_table.vault.arn] }, { Effect = "Allow", Action = ["bedrock:InvokeModel", "bedrock-agentcore:*"], Resource = "*" } ] }) } locals { services = { fusion = { image = var.fusion_image_uri, port = 8080, task_role = aws_iam_role.fusion_task.arn, tag = local.onprem_tag } presidio = { image = var.presidio_image_uri, port = 5001, task_role = aws_iam_role.ecs_exec.arn, tag = local.onprem_tag } } } resource "aws_ecs_task_definition" "svc" { for_each = local.services family = "${local.name}-${each.key}" requires_compatibilities = ["FARGATE"] network_mode = "awsvpc" cpu = 512 memory = 1024 execution_role_arn = aws_iam_role.ecs_exec.arn task_role_arn = each.value.task_role container_definitions = jsonencode([{ name = each.key image = each.value.image essential = true portMappings = [{ containerPort = each.value.port }] }]) tags = each.value.tag } resource "aws_ecs_service" "svc" { for_each = local.services name = "${local.name}-${each.key}" cluster = aws_ecs_cluster.this.id task_definition = aws_ecs_task_definition.svc[each.key].arn desired_count = 1 launch_type = "FARGATE" network_configuration { subnets = data.aws_subnets.default.ids security_groups = [aws_security_group.svc.id] assign_public_ip = true } tags = each.value.tag }