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 }