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>
86 lines
2.7 KiB
HCL
86 lines
2.7 KiB
HCL
# ---------------------------------------------------------------------------
|
|
# T6: host the advisor UI on S3 + CloudFront. The bucket is private; CloudFront
|
|
# reaches it via Origin Access Control. index.html is static and committed; the
|
|
# live endpoint is injected via a generated config.js so we never bake an
|
|
# ephemeral URL into the repo.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
resource "aws_s3_bucket" "ui" {
|
|
bucket_prefix = "${local.name}-ui-"
|
|
force_destroy = true
|
|
tags = local.onprem_tag
|
|
}
|
|
|
|
resource "aws_cloudfront_origin_access_control" "ui" {
|
|
name = "${local.name}-ui-oac"
|
|
origin_access_control_origin_type = "s3"
|
|
signing_behavior = "always"
|
|
signing_protocol = "sigv4"
|
|
}
|
|
|
|
resource "aws_cloudfront_distribution" "ui" {
|
|
enabled = true
|
|
default_root_object = "index.html"
|
|
comment = "${local.name} advisor UI"
|
|
|
|
origin {
|
|
domain_name = aws_s3_bucket.ui.bucket_regional_domain_name
|
|
origin_id = "ui-s3"
|
|
origin_access_control_id = aws_cloudfront_origin_access_control.ui.id
|
|
}
|
|
|
|
default_cache_behavior {
|
|
allowed_methods = ["GET", "HEAD"]
|
|
cached_methods = ["GET", "HEAD"]
|
|
target_origin_id = "ui-s3"
|
|
viewer_protocol_policy = "redirect-to-https"
|
|
forwarded_values {
|
|
query_string = false
|
|
cookies { forward = "none" }
|
|
}
|
|
}
|
|
|
|
restrictions {
|
|
geo_restriction { restriction_type = "none" }
|
|
}
|
|
|
|
viewer_certificate {
|
|
cloudfront_default_certificate = true
|
|
}
|
|
|
|
tags = local.cloud_tag
|
|
}
|
|
|
|
resource "aws_s3_bucket_policy" "ui" {
|
|
bucket = aws_s3_bucket.ui.id
|
|
policy = jsonencode({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Principal = { Service = "cloudfront.amazonaws.com" }
|
|
Action = "s3:GetObject"
|
|
Resource = "${aws_s3_bucket.ui.arn}/*"
|
|
Condition = { StringEquals = { "AWS:SourceArn" = aws_cloudfront_distribution.ui.arn } }
|
|
}]
|
|
})
|
|
}
|
|
|
|
resource "aws_s3_object" "index" {
|
|
bucket = aws_s3_bucket.ui.id
|
|
key = "index.html"
|
|
source = "${path.module}/../ui/index.html"
|
|
etag = filemd5("${path.module}/../ui/index.html")
|
|
content_type = "text/html"
|
|
}
|
|
|
|
# Injected config: the demo orchestrator endpoint the UI calls.
|
|
resource "aws_s3_object" "config" {
|
|
bucket = aws_s3_bucket.ui.id
|
|
key = "config.js"
|
|
content = "window.DEMO_ENDPOINT = \"${trimsuffix(aws_apigatewayv2_stage.default.invoke_url, "/")}/demo\";\n"
|
|
content_type = "application/javascript"
|
|
etag = md5("${trimsuffix(aws_apigatewayv2_stage.default.invoke_url, "/")}/demo")
|
|
}
|
|
|
|
output "ui_url" { value = "https://${aws_cloudfront_distribution.ui.domain_name}" }
|