Files
hncb-fusion-deid-demo/terraform/main.tf
Conan Scott 78d67a2469 Implement reversible PII de-identification round trip (T1–T7)
Build the AWS side of the HNCB demo end to end (region ap-southeast-1):

- T1 /tokenize + T2 /restore: Lambdas behind a public API Gateway (shared-secret
  auth), Presidio detection, random per-request tokens, DynamoDB vault; overlap
  resolution so a ROC ID stays TW_ROC_ID.
- T3: Presidio made private (SG-locked to the tokenize Lambda in-VPC; DynamoDB
  gateway endpoint); only /tokenize + /restore are public.
- T4: RAG Lambda registered as an MCP tool on an AgentCore Gateway (AWS_IAM/SigV4);
  agentcore_setup.sh + a SigV4 MCP invoke test.
- T5: Strands agent deployed to AgentCore Runtime; SigV4 gateway auth, apac
  inference profile, pinned deps.
- T6: advisor UI on S3+CloudFront with a Fusion-less demo orchestrator (/demo)
  chaining tokenize -> runtime -> restore.
- T7: README runbook + trace check; teardown deletes gateway/runtime/memory/ECR.

Verified live: the cloud AgentCore/Bedrock trace shows only tokens, never the
real name. Secrets stay in gitignored local.auto.tfvars.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:10:58 +10:00

125 lines
3.5 KiB
HCL

terraform {
required_version = ">= 1.5"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
archive = { source = "hashicorp/archive", version = "~> 2.0" }
}
}
provider "aws" {
region = var.region
# Every taggable resource created by this stack carries this tag, on top of any
# per-resource tags (e.g. the on-prem/cloud Zone tags).
default_tags {
tags = {
Owner = "conan hncb demo"
}
}
}
locals {
name = var.project
# Logical trust zones are represented by tags for the demo (everything is one account).
onprem_tag = { Zone = "on-prem-VPC-A" }
cloud_tag = { Zone = "cloud-VPC-B" }
}
########################################
# Token vault + seeded customer data (both live in the "on-prem" zone)
########################################
resource "aws_dynamodb_table" "vault" {
name = "${local.name}-vault"
billing_mode = "PAY_PER_REQUEST"
hash_key = "token"
attribute {
name = "token"
type = "S"
}
ttl {
attribute_name = "expires_at"
enabled = true
}
tags = local.onprem_tag
}
resource "aws_dynamodb_table" "customers" {
name = "${local.name}-customers"
billing_mode = "PAY_PER_REQUEST"
hash_key = "customer_id"
attribute {
name = "customer_id"
type = "S"
}
tags = local.onprem_tag
}
########################################
# RAG tool Lambda (step 4-6): resolves the token, reads customer data,
# returns a de-identified evidence package. Never returns raw PII.
########################################
data "archive_file" "rag" {
type = "zip"
source_dir = "${path.module}/../lambda_rag"
output_path = "${path.module}/rag_lambda.zip"
}
resource "aws_iam_role" "rag" {
name = "${local.name}-rag-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "rag" {
name = "${local.name}-rag-policy"
role = aws_iam_role.rag.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["dynamodb:GetItem", "dynamodb:Query"]
Resource = [aws_dynamodb_table.vault.arn, aws_dynamodb_table.customers.arn]
},
{
Effect = "Allow"
Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
Resource = "arn:aws:logs:*:*:*"
}
]
})
}
resource "aws_lambda_function" "rag" {
function_name = "${local.name}-rag-tool"
role = aws_iam_role.rag.arn
runtime = "python3.12"
handler = "handler.lambda_handler"
filename = data.archive_file.rag.output_path
source_code_hash = data.archive_file.rag.output_base64sha256
timeout = 15
environment {
variables = {
VAULT_TABLE = aws_dynamodb_table.vault.name
CUSTOMERS_TABLE = aws_dynamodb_table.customers.name
}
}
tags = local.onprem_tag
}
########################################
# Outputs
########################################
output "region" { value = var.region }
output "vault_table" { value = aws_dynamodb_table.vault.name }
output "customers_table" { value = aws_dynamodb_table.customers.name }
output "rag_lambda_name" { value = aws_lambda_function.rag.function_name }
output "rag_lambda_arn" { value = aws_lambda_function.rag.arn }
output "bedrock_model_id" { value = var.bedrock_model_id }